Merge branch 'develop' into feature/elk

This commit is contained in:
Jim Blake 2014-12-11 16:24:52 -05:00
commit dad574d33a
74 changed files with 4069 additions and 1465 deletions

View file

@ -35,7 +35,6 @@ log4j.rootLogger=INFO, AllAppender
# These classes are too chatty to display INFO messages. # 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.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 log4j.logger.edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase=DEBUG
# Spring as a whole is too chatty to display INFO messages. # Spring as a whole is too chatty to display INFO messages.

View file

@ -875,3 +875,9 @@ 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. 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

View file

@ -6,23 +6,27 @@ import java.lang.reflect.Method;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.EditProcessObject; import edu.cornell.mannlib.vedit.beans.EditProcessObject;
import edu.cornell.mannlib.vedit.beans.FormObject; import edu.cornell.mannlib.vedit.beans.FormObject;
import edu.cornell.mannlib.vedit.beans.Option; 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.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
public class FormUtils { public class FormUtils {
@ -248,6 +252,35 @@ public class FormUtils {
return vclassOptionList; 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) { public static void beanSet(Object newObj, String field, String value) {
beanSet (newObj, field, value, null); beanSet (newObj, field, value, null);
} }

View file

@ -2,12 +2,10 @@
package edu.cornell.mannlib.vitro.webapp.auth.permissions; package edu.cornell.mannlib.vitro.webapp.auth.permissions;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.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.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement; 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 String roleName;
private final RoleLevel roleLevel; private final RoleLevel roleLevel;
private final ServletContext ctx;
public DisplayByRolePermission(String roleName, RoleLevel roleLevel, public DisplayByRolePermission(String roleName, RoleLevel roleLevel) {
ServletContext ctx) {
super(NAMESPACE + roleName); super(NAMESPACE + roleName);
if (roleName == null) { if (roleName == null) {
@ -42,13 +38,9 @@ public class DisplayByRolePermission extends Permission {
if (roleLevel == null) { if (roleLevel == null) {
throw new NullPointerException("roleLevel may not be null."); throw new NullPointerException("roleLevel may not be null.");
} }
if (ctx == null) {
throw new NullPointerException("context may not be null.");
}
this.roleName = roleName; this.roleName = roleName;
this.roleLevel = roleLevel; this.roleLevel = roleLevel;
this.ctx = ctx;
} }
@Override @Override
@ -113,19 +105,18 @@ public class DisplayByRolePermission extends Permission {
String subjectUri = action.getSubjectUri(); String subjectUri = action.getSubjectUri();
String objectUri = action.getObjectUri(); String objectUri = action.getObjectUri();
Property op = action.getProperty(); Property op = action.getProperty();
return canDisplayResource(subjectUri) return canDisplayResource(subjectUri) && canDisplayPredicate(op)
&& canDisplayPredicate(op)
&& canDisplayResource(objectUri); && canDisplayResource(objectUri);
} }
private boolean canDisplayResource(String resourceUri) { private boolean canDisplayResource(String resourceUri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( return PropertyRestrictionBean.getBean().canDisplayResource(
resourceUri, this.roleLevel); resourceUri, this.roleLevel);
} }
private boolean canDisplayPredicate(Property predicate) { private boolean canDisplayPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx) return PropertyRestrictionBean.getBean().canDisplayPredicate(predicate,
.canDisplayPredicate(predicate, this.roleLevel); this.roleLevel);
} }
@Override @Override

View file

@ -2,12 +2,10 @@
package edu.cornell.mannlib.vitro.webapp.auth.permissions; package edu.cornell.mannlib.vitro.webapp.auth.permissions;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.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.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; 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 String roleName;
private final RoleLevel roleLevel; private final RoleLevel roleLevel;
private final ServletContext ctx;
public EditByRolePermission(String roleName, RoleLevel roleLevel, public EditByRolePermission(String roleName, RoleLevel roleLevel) {
ServletContext ctx) {
super(NAMESPACE + roleName); super(NAMESPACE + roleName);
if (roleName == null) { if (roleName == null) {
@ -39,13 +35,9 @@ public class EditByRolePermission extends Permission {
if (roleLevel == null) { if (roleLevel == null) {
throw new NullPointerException("roleLevel may not be null."); throw new NullPointerException("roleLevel may not be null.");
} }
if (ctx == null) {
throw new NullPointerException("context may not be null.");
}
this.roleName = roleName; this.roleName = roleName;
this.roleLevel = roleLevel; this.roleLevel = roleLevel;
this.ctx = ctx;
} }
/** /**
@ -80,8 +72,7 @@ public class EditByRolePermission extends Permission {
private boolean isAuthorized(AbstractDataPropertyStatementAction action) { private boolean isAuthorized(AbstractDataPropertyStatementAction action) {
String subjectUri = action.getSubjectUri(); String subjectUri = action.getSubjectUri();
Property predicate = action.getPredicate(); Property predicate = action.getPredicate();
return canModifyResource(subjectUri) return canModifyResource(subjectUri) && canModifyPredicate(predicate);
&& canModifyPredicate(predicate);
} }
/** /**
@ -92,19 +83,18 @@ public class EditByRolePermission extends Permission {
String subjectUri = action.getSubjectUri(); String subjectUri = action.getSubjectUri();
Property predicate = action.getPredicate(); Property predicate = action.getPredicate();
String objectUri = action.getObjectUri(); String objectUri = action.getObjectUri();
return canModifyResource(subjectUri) return canModifyResource(subjectUri) && canModifyPredicate(predicate)
&& canModifyPredicate(predicate)
&& canModifyResource(objectUri); && canModifyResource(objectUri);
} }
private boolean canModifyResource(String resourceUri) { private boolean canModifyResource(String resourceUri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource( return PropertyRestrictionBean.getBean().canModifyResource(resourceUri,
resourceUri, roleLevel); roleLevel);
} }
private boolean canModifyPredicate(Property predicate) { private boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( return PropertyRestrictionBean.getBean().canModifyPredicate(predicate,
predicate, roleLevel); roleLevel);
} }
@Override @Override

View file

@ -150,9 +150,9 @@ public class PermissionRegistry {
List<Permission> permissions = new ArrayList<Permission>(); List<Permission> permissions = new ArrayList<Permission>();
permissions.addAll(SimplePermission.getAllInstances()); permissions.addAll(SimplePermission.getAllInstances());
permissions.addAll(createDisplayByRolePermissions(ctx)); permissions.addAll(createDisplayByRolePermissions());
permissions.addAll(createEditByRolePermissions(ctx)); permissions.addAll(createEditByRolePermissions());
permissions.addAll(createPublishByRolePermissions(ctx)); permissions.addAll(createPublishByRolePermissions());
PermissionRegistry.createRegistry(ctx, permissions); PermissionRegistry.createRegistry(ctx, permissions);
@ -169,17 +169,12 @@ public class PermissionRegistry {
* same rights as PUBLIC. Other permissions give them their self-editing * same rights as PUBLIC. Other permissions give them their self-editing
* privileges. * privileges.
*/ */
private Collection<Permission> createDisplayByRolePermissions( private Collection<Permission> createDisplayByRolePermissions() {
ServletContext ctx) {
List<Permission> list = new ArrayList<Permission>(); List<Permission> list = new ArrayList<Permission>();
list.add(new DisplayByRolePermission("Admin", RoleLevel.DB_ADMIN, list.add(new DisplayByRolePermission("Admin", RoleLevel.DB_ADMIN));
ctx)); list.add(new DisplayByRolePermission("Curator", RoleLevel.CURATOR));
list.add(new DisplayByRolePermission("Curator", RoleLevel.CURATOR, list.add(new DisplayByRolePermission("Editor", RoleLevel.EDITOR));
ctx)); list.add(new DisplayByRolePermission("Public", RoleLevel.PUBLIC));
list.add(new DisplayByRolePermission("Editor", RoleLevel.EDITOR,
ctx));
list.add(new DisplayByRolePermission("Public", RoleLevel.PUBLIC,
ctx));
return list; return list;
} }
@ -191,12 +186,11 @@ public class PermissionRegistry {
* *
* Other permissions give self-editors their editing privileges. * Other permissions give self-editors their editing privileges.
*/ */
private Collection<Permission> createEditByRolePermissions( private Collection<Permission> createEditByRolePermissions() {
ServletContext ctx) {
List<Permission> list = new ArrayList<Permission>(); List<Permission> list = new ArrayList<Permission>();
list.add(new EditByRolePermission("Admin", RoleLevel.DB_ADMIN, ctx)); list.add(new EditByRolePermission("Admin", RoleLevel.DB_ADMIN));
list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR, ctx)); list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR));
list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR, ctx)); list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR));
return list; return list;
} }
@ -210,17 +204,12 @@ public class PermissionRegistry {
* same rights as PUBLIC. Other permissions give them their self-editing * same rights as PUBLIC. Other permissions give them their self-editing
* privileges. * privileges.
*/ */
private Collection<Permission> createPublishByRolePermissions( private Collection<Permission> createPublishByRolePermissions() {
ServletContext ctx) {
List<Permission> list = new ArrayList<Permission>(); List<Permission> list = new ArrayList<Permission>();
list.add(new PublishByRolePermission("Admin", RoleLevel.DB_ADMIN, list.add(new PublishByRolePermission("Admin", RoleLevel.DB_ADMIN));
ctx)); list.add(new PublishByRolePermission("Curator", RoleLevel.CURATOR));
list.add(new PublishByRolePermission("Curator", RoleLevel.CURATOR, list.add(new PublishByRolePermission("Editor", RoleLevel.EDITOR));
ctx)); list.add(new PublishByRolePermission("Public", RoleLevel.PUBLIC));
list.add(new PublishByRolePermission("Editor", RoleLevel.EDITOR,
ctx));
list.add(new PublishByRolePermission("Public", RoleLevel.PUBLIC,
ctx));
return list; return list;
} }
} }

View file

@ -2,12 +2,10 @@
package edu.cornell.mannlib.vitro.webapp.auth.permissions; package edu.cornell.mannlib.vitro.webapp.auth.permissions;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.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.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataProperty; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataPropertyStatement; 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 String roleName;
private final RoleLevel roleLevel; private final RoleLevel roleLevel;
private final ServletContext ctx;
public PublishByRolePermission(String roleName, RoleLevel roleLevel, public PublishByRolePermission(String roleName, RoleLevel roleLevel) {
ServletContext ctx) {
super(NAMESPACE + roleName); super(NAMESPACE + roleName);
if (roleName == null) { if (roleName == null) {
@ -41,13 +37,9 @@ public class PublishByRolePermission extends Permission {
if (roleLevel == null) { if (roleLevel == null) {
throw new NullPointerException("roleLevel may not be null."); throw new NullPointerException("roleLevel may not be null.");
} }
if (ctx == null) {
throw new NullPointerException("context may not be null.");
}
this.roleName = roleName; this.roleName = roleName;
this.roleLevel = roleLevel; this.roleLevel = roleLevel;
this.ctx = ctx;
} }
@Override @Override
@ -116,13 +108,13 @@ public class PublishByRolePermission extends Permission {
} }
private boolean canPublishResource(String resourceUri) { private boolean canPublishResource(String resourceUri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canPublishResource( return PropertyRestrictionBean.getBean().canPublishResource(
resourceUri, this.roleLevel); resourceUri, this.roleLevel);
} }
private boolean canPublishPredicate(Property predicate) { private boolean canPublishPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx) return PropertyRestrictionBean.getBean().canPublishPredicate(predicate,
.canPublishPredicate(predicate, this.roleLevel); this.roleLevel);
} }
@Override @Override

View file

@ -4,7 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy;
import javax.servlet.ServletContext; 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.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
@ -23,13 +23,13 @@ public abstract class BaseSelfEditingPolicy {
} }
protected boolean canModifyResource(String uri) { protected boolean canModifyResource(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource( return PropertyRestrictionBean.getBean().canModifyResource(uri,
uri, roleLevel); roleLevel);
} }
protected boolean canModifyPredicate(Property predicate) { protected boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( return PropertyRestrictionBean.getBean().canModifyPredicate(predicate,
predicate, roleLevel); roleLevel);
} }
protected PolicyDecision cantModifyResource(String uri) { protected PolicyDecision cantModifyResource(String uri) {

View file

@ -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.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual; 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.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
@ -114,14 +114,18 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface {
String subjectUri = action.getSubjectUri(); String subjectUri = action.getSubjectUri();
Property predicate = action.getProperty(); Property predicate = action.getProperty();
String objectUri = action.getObjectUri(); String objectUri = action.getObjectUri();
if (canDisplayResource(subjectUri) && canDisplayPredicate(predicate) if (canDisplayResource(subjectUri)
&& canDisplayPredicate(predicate)
&& canDisplayResource(objectUri) && canDisplayResource(objectUri)
&& isAboutAssociatedIndividual(individuals, subjectUri, objectUri)) { && isAboutAssociatedIndividual(individuals, subjectUri,
objectUri)) {
return authorized("user may view ObjectPropertyStatement " return authorized("user may view ObjectPropertyStatement "
+ subjectUri + " ==> " + predicate.getURI() + " ==> " + objectUri); + subjectUri + " ==> " + predicate.getURI() + " ==> "
+ objectUri);
} else { } else {
return defaultDecision("user may not view ObjectPropertyStatement " 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) { private boolean canDisplayResource(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( return PropertyRestrictionBean.getBean().canDisplayResource(uri,
uri, RoleLevel.SELF); RoleLevel.SELF);
} }
private boolean canDisplayPredicate(Property predicate) { private boolean canDisplayPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx) return PropertyRestrictionBean.getBean().canDisplayPredicate(predicate,
.canDisplayPredicate(predicate, RoleLevel.SELF); RoleLevel.SELF);
} }
private boolean isAboutAssociatedIndividual(Collection<String> selves, private boolean isAboutAssociatedIndividual(Collection<String> selves,

View file

@ -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;
}
}
}

View file

@ -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();
}
}

View file

@ -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 + "]";
}
}

View file

@ -2,21 +2,12 @@
package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; 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.Log;
import org.apache.commons.logging.LogFactory; 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.beans.EditProcessObject;
import edu.cornell.mannlib.vedit.listener.ChangeListener; import edu.cornell.mannlib.vedit.listener.ChangeListener;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
/** /**
* Add this ChangeListener to your EditProcessObject when modifying the * Add this ChangeListener to your EditProcessObject when modifying the
@ -27,83 +18,50 @@ public class PropertyRestrictionListener implements ChangeListener {
private static final Log log = LogFactory private static final Log log = LogFactory
.getLog(PropertyRestrictionListener.class); .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. * If the deleted property had a non-null restriction, rebuild the bean.
*/ */
@Override @Override
public void doDeleted(Object oldObj, EditProcessObject epo) { public void doDeleted(Object oldObj, EditProcessObject epo) {
Property p = (Property) oldObj; if (oldObj instanceof RoleRestrictedProperty) {
if (anyRoleChanged(p.getHiddenFromDisplayBelowRoleLevel(), RoleRestrictedProperty p = (RoleRestrictedProperty) oldObj;
p.getProhibitedFromUpdateBelowRoleLevel(), FullPropertyKey key = new FullPropertyKey(p);
p.getHiddenFromPublishBelowRoleLevel(), null, null, null)) { updateLevels(new PropertyRestrictionLevels(key, p));
log.debug("rebuilding the PropertyRestrictionPolicyHelper after deletion"); } else {
createAndSetBean(); 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 @Override
public void doInserted(Object newObj, EditProcessObject epo) { public void doInserted(Object newObj, EditProcessObject epo) {
Property p = (Property) newObj; if (newObj instanceof RoleRestrictedProperty) {
if (anyRoleChanged(null, null, null, RoleRestrictedProperty p = (RoleRestrictedProperty) newObj;
p.getHiddenFromDisplayBelowRoleLevel(), FullPropertyKey key = new FullPropertyKey(p);
p.getProhibitedFromUpdateBelowRoleLevel(), updateLevels(new PropertyRestrictionLevels(key, p));
p.getHiddenFromPublishBelowRoleLevel())) { } else {
log.debug("rebuilding the PropertyRestrictionPolicyHelper after insertion"); log.warn("Not an instance of RoleRestrictedProperty: " + newObj);
createAndSetBean();
} }
} }
/** /**
* If the updated property has changed its restrictions, rebuild the bean. * Update the changed property.
*/ */
@Override @Override
public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) { public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) {
Property oldP = (Property) oldObj; if (newObj instanceof RoleRestrictedProperty) {
Property newP = (Property) newObj; RoleRestrictedProperty newP = (RoleRestrictedProperty) newObj;
if (anyRoleChanged(oldP.getHiddenFromDisplayBelowRoleLevel(), FullPropertyKey key = new FullPropertyKey(newP);
oldP.getProhibitedFromUpdateBelowRoleLevel(), updateLevels(new PropertyRestrictionLevels(key, newP));
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;
} else { } else {
return oldRole.compareTo(newRole) == 0; log.warn("Not instances of RoleRestrictedProperty: " + oldObj
+ ", " + newObj);
} }
} }
private void createAndSetBean() { private void updateLevels(PropertyRestrictionLevels levels) {
OntModel model = ModelAccess.on(ctx).getOntModel(); PropertyRestrictionBean.getBean().updateProperty(levels);
Model displayModel = ModelAccess.on(ctx).getOntModel(DISPLAY);
PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper
.createBean(model, displayModel);
PropertyRestrictionPolicyHelper.setBean(ctx, bean);
} }
} }

View file

@ -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());
}
}
}

View file

@ -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();
}

View file

@ -8,7 +8,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.BasicPolicyDecision; 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.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; 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) { protected boolean canModifyResource(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource( return PropertyRestrictionBean.getBean().canModifyResource(uri,
uri, RoleLevel.SELF); RoleLevel.SELF);
} }
protected boolean canModifyPredicate(Property predicate) { protected boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( return PropertyRestrictionBean.getBean().canModifyPredicate(predicate,
predicate, RoleLevel.SELF); RoleLevel.SELF);
} }
protected PolicyDecision cantModifyResource(String uri) { protected PolicyDecision cantModifyResource(String uri) {

View file

@ -79,6 +79,7 @@ public class BaseResourceBean implements ResourceBean {
return shorthand; return shorthand;
} }
// Never returns null.
public static RoleLevel getRoleByUri(String uri2) { public static RoleLevel getRoleByUri(String uri2) {
if (uri2 == null) if (uri2 == null)
return RoleLevel.values()[0]; return RoleLevel.values()[0];
@ -208,13 +209,13 @@ public class BaseResourceBean implements ResourceBean {
} }
@Override @Override
public void setHiddenFromDisplayBelowRoleLevel(RoleLevel eR) { public void setHiddenFromDisplayBelowRoleLevel(RoleLevel level) {
hiddenFromDisplayBelowRoleLevel = eR; hiddenFromDisplayBelowRoleLevel = level;
} }
@Override @Override
public void setHiddenFromDisplayBelowRoleLevelUsingRoleUri(String roleUri) { public void setHiddenFromDisplayBelowRoleLevelUsingRoleUri(String roleUri) {
hiddenFromDisplayBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri); hiddenFromDisplayBelowRoleLevel = RoleLevel.getRoleByUri(roleUri);
} }
@Override @Override
@ -223,13 +224,13 @@ public class BaseResourceBean implements ResourceBean {
} }
@Override @Override
public void setProhibitedFromUpdateBelowRoleLevel(RoleLevel eR) { public void setProhibitedFromUpdateBelowRoleLevel(RoleLevel level) {
prohibitedFromUpdateBelowRoleLevel = eR; prohibitedFromUpdateBelowRoleLevel = level;
} }
@Override @Override
public void setProhibitedFromUpdateBelowRoleLevelUsingRoleUri(String roleUri) { public void setProhibitedFromUpdateBelowRoleLevelUsingRoleUri(String roleUri) {
prohibitedFromUpdateBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri); prohibitedFromUpdateBelowRoleLevel = RoleLevel.getRoleByUri(roleUri);
} }
@Override @Override
@ -238,8 +239,8 @@ public class BaseResourceBean implements ResourceBean {
} }
@Override @Override
public void setHiddenFromPublishBelowRoleLevel(RoleLevel eR) { public void setHiddenFromPublishBelowRoleLevel(RoleLevel level) {
hiddenFromPublishBelowRoleLevel = eR; hiddenFromPublishBelowRoleLevel = level;
} }
@Override @Override

View file

@ -6,13 +6,15 @@ import java.text.Collator;
import java.util.List; import java.util.List;
import java.util.LinkedList; import java.util.LinkedList;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
/** /**
* class representing a property that relates an entity (object) * class representing a property that relates an entity (object)
* to a data literal * to a data literal
* @author bjl23 * @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 name = null;
private String publicName = null; private String publicName = null;

View file

@ -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();
}
}

View file

@ -17,11 +17,13 @@ import org.joda.time.DateTime;
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
/** /**
* a class representing an object property * 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()); private static final Log log = LogFactory.getLog(ObjectProperty.class.getName());

View file

@ -46,6 +46,13 @@ public class VitroApiServlet extends HttpServlet {
Authenticator auth = Authenticator.getInstance(req); Authenticator auth = Authenticator.getInstance(req);
UserAccount account = auth.getAccountForInternalAuth(email); 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)) { if (!auth.isCurrentPassword(account, password)) {
log.debug("Invalid: '" + email + "'/'" + password + "'"); log.debug("Invalid: '" + email + "'/'" + password + "'");
throw new AuthException("email/password combination is not valid"); 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"); 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 + "'"); log.debug("Authorized for '" + email + "'");
} }

View file

@ -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.controller.edit.utils.RoleLevelOptionsSetup;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; 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.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
public class DatapropRetryController extends BaseEditController { public class DatapropRetryController extends BaseEditController {
@ -124,7 +124,7 @@ public class DatapropRetryController extends BaseEditController {
//set up any listeners //set up any listeners
List changeListenerList = new ArrayList(); List changeListenerList = new ArrayList();
changeListenerList.add(new PropertyRestrictionListener(getServletContext())); changeListenerList.add(new PropertyRestrictionListener());
epo.setChangeListenerList(changeListenerList); epo.setChangeListenerList(changeListenerList);

View file

@ -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 {
}

View file

@ -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());
}
}
}
}

View file

@ -17,8 +17,10 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.EditProcessObject; import edu.cornell.mannlib.vedit.beans.EditProcessObject;
import edu.cornell.mannlib.vedit.beans.FormObject; 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.controller.BaseEditController;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology; import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
@ -33,7 +35,8 @@ public class PropertyEditController extends BaseEditController {
private static final Log log = LogFactory.getLog(PropertyEditController.class.getName()); 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, if (!isAuthorizedToDisplayPage(request, response,
SimplePermission.EDIT_ONTOLOGY.ACTION)) { SimplePermission.EDIT_ONTOLOGY.ACTION)) {
return; return;
@ -189,11 +192,9 @@ public class PropertyEditController extends BaseEditController {
request.setAttribute("suppressquery","true"); request.setAttribute("suppressquery","true");
boolean FORCE_NEW = true;
EditProcessObject epo = super.createEpo(request, FORCE_NEW); EditProcessObject epo = super.createEpo(request, FORCE_NEW);
FormObject foo = new FormObject(); FormObject foo = new FormObject();
HashMap OptionMap = new HashMap(); HashMap<String, List<Option>> OptionMap = new HashMap<>();
foo.setOptionLists(OptionMap); foo.setOptionLists(OptionMap);
epo.setFormObject(foo); epo.setFormObject(foo);
@ -210,11 +211,18 @@ public class PropertyEditController extends BaseEditController {
sortForPickList(subProps, vreq); sortForPickList(subProps, vreq);
request.setAttribute("subproperties", subProps); request.setAttribute("subproperties", subProps);
// equivalent properties and faux properties
List<ObjectProperty> eqProps = getObjectPropertiesForURIList( List<ObjectProperty> eqProps = getObjectPropertiesForURIList(
opDao.getEquivalentPropertyURIs(p.getURI()), opDao); opDao.getEquivalentPropertyURIs(p.getURI()), opDao);
sortForPickList(eqProps, vreq); sortForPickList(eqProps, vreq);
request.setAttribute("equivalentProperties", eqProps); 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); RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("epoKey",epo.getKey()); request.setAttribute("epoKey",epo.getKey());
request.setAttribute("propertyWebapp", p); 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); doPost(request,response);
} }

View file

@ -22,6 +22,7 @@ import edu.cornell.mannlib.vedit.beans.Option;
import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vedit.forwarder.PageForwarder; import edu.cornell.mannlib.vedit.forwarder.PageForwarder;
import edu.cornell.mannlib.vedit.forwarder.impl.UrlForwarder; 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.util.FormUtils;
import edu.cornell.mannlib.vedit.validator.Validator; import edu.cornell.mannlib.vedit.validator.Validator;
import edu.cornell.mannlib.vedit.validator.impl.IntValidator; 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.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener; import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; 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.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup; import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; 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 { public class PropertyRetryController extends BaseEditController {
@ -67,10 +66,8 @@ public class PropertyRetryController extends BaseEditController {
} }
ObjectPropertyDao propDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getObjectPropertyDao(); ObjectPropertyDao propDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getObjectPropertyDao();
//getUnfilteredWebappDaoFactory().getObjectPropertyDao();
epo.setDataAccessObject(propDao); epo.setDataAccessObject(propDao);
OntologyDao ontDao = request.getUnfilteredWebappDaoFactory().getOntologyDao(); OntologyDao ontDao = request.getUnfilteredWebappDaoFactory().getOntologyDao();
VClassDao vclassDao = request.getUnfilteredWebappDaoFactory().getVClassDao();
ObjectProperty propertyForEditing = null; ObjectProperty propertyForEditing = null;
if (!epo.getUseRecycledBean()){ if (!epo.getUseRecycledBean()){
@ -82,6 +79,7 @@ public class PropertyRetryController extends BaseEditController {
epo.setAction("update"); epo.setAction("update");
} catch (NullPointerException e) { } catch (NullPointerException e) {
log.error("Need to implement 'record not found' error message."); log.error("Need to implement 'record not found' error message.");
throw(e);
} }
} else { } else {
propertyForEditing = new ObjectProperty(); propertyForEditing = new ObjectProperty();
@ -105,9 +103,9 @@ public class PropertyRetryController extends BaseEditController {
//set any validators //set any validators
List localNameValidatorList = new ArrayList(); List<Validator> localNameValidatorList = new ArrayList<>();
localNameValidatorList.add(new XMLNameValidator()); localNameValidatorList.add(new XMLNameValidator());
List localNameInverseValidatorList = new ArrayList(); List<Validator> localNameInverseValidatorList = new ArrayList<>();
localNameInverseValidatorList.add(new XMLNameValidator(true)); localNameInverseValidatorList.add(new XMLNameValidator(true));
epo.getValidatorMap().put("LocalName", localNameValidatorList); epo.getValidatorMap().put("LocalName", localNameValidatorList);
epo.getValidatorMap().put("LocalNameInverse", localNameInverseValidatorList); epo.getValidatorMap().put("LocalNameInverse", localNameInverseValidatorList);
@ -116,8 +114,8 @@ public class PropertyRetryController extends BaseEditController {
epo.getValidatorMap().put("DisplayRank", displayRankValidatorList); epo.getValidatorMap().put("DisplayRank", displayRankValidatorList);
//set up any listeners //set up any listeners
List changeListenerList = new ArrayList(); List<ChangeListener> changeListenerList = new ArrayList<>();
changeListenerList.add(new PropertyRestrictionListener(getServletContext())); changeListenerList.add(new PropertyRestrictionListener());
epo.setChangeListenerList(changeListenerList); epo.setChangeListenerList(changeListenerList);
//make a postinsert pageforwarder that will send us to a new class's fetch screen //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 //set the getMethod so we can retrieve a new bean after we've inserted it
try { try {
Class[] args = new Class[1]; Class<?>[] args = new Class[1];
args[0] = String.class; args[0] = String.class;
epo.setGetMethod(propDao.getClass().getDeclaredMethod("getObjectPropertyByURI",args)); epo.setGetMethod(propDao.getClass().getDeclaredMethod("getObjectPropertyByURI",args));
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
@ -149,7 +147,7 @@ public class PropertyRetryController extends BaseEditController {
optionMap.put("ProhibitedFromUpdateBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getUpdateOptionsList(propertyForEditing)); optionMap.put("ProhibitedFromUpdateBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getUpdateOptionsList(propertyForEditing));
optionMap.put("HiddenFromPublishBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getPublishOptionsList(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>(); HashMap<String,Option> hashMap = new HashMap<String,Option>();
groupOptList = getSortedList(hashMap,groupOptList,request); groupOptList = getSortedList(hashMap,groupOptList,request);
groupOptList.add(0,new Option("","none")); groupOptList.add(0,new Option("","none"));
@ -163,7 +161,6 @@ public class PropertyRetryController extends BaseEditController {
request.setAttribute("inverseFunctional",propertyForEditing.getInverseFunctional()); request.setAttribute("inverseFunctional",propertyForEditing.getInverseFunctional());
request.setAttribute("selectFromExisting",propertyForEditing.getSelectFromExisting()); request.setAttribute("selectFromExisting",propertyForEditing.getSelectFromExisting());
request.setAttribute("offerCreateNewOption", propertyForEditing.getOfferCreateNewOption()); request.setAttribute("offerCreateNewOption", propertyForEditing.getOfferCreateNewOption());
//request.setAttribute("stubObjectRelation", propertyForEditing.getStubObjectRelation());
request.setAttribute("objectIndividualSortPropertyURI", propertyForEditing.getObjectIndividualSortPropertyURI()); request.setAttribute("objectIndividualSortPropertyURI", propertyForEditing.getObjectIndividualSortPropertyURI());
request.setAttribute("domainEntitySortDirection", propertyForEditing.getDomainEntitySortDirection()); request.setAttribute("domainEntitySortDirection", propertyForEditing.getDomainEntitySortDirection());
request.setAttribute("collateBySubclass", propertyForEditing.getCollateBySubclass()); 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); doPost(request, response);
} }
@ -269,21 +267,9 @@ public class PropertyRetryController extends BaseEditController {
optionMap.put("RangeVClassURI", rangeOptionList); optionMap.put("RangeVClassURI", rangeOptionList);
} }
private List<VClass> makeVClassListForOptions(String VClassURI, List<VClass> allClassBeanList, VClassDao vclassDao) { private static class PropertyInsertPageForwarder implements PageForwarder {
List<VClass> currentClassList = new ArrayList<VClass>(); @Override
VClass currentVClass = vclassDao.getVClassByURI(VClassURI); public void doForward(HttpServletRequest request, HttpServletResponse response, EditProcessObject epo){
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){
String newPropertyUrl = "propertyEdit?uri="; String newPropertyUrl = "propertyEdit?uri=";
ObjectProperty p = (ObjectProperty) epo.getNewBean(); ObjectProperty p = (ObjectProperty) epo.getNewBean();
try { try {

View file

@ -185,6 +185,7 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
urls.put("classHierarchy", UrlBuilder.getUrl("/showClassHierarchy")); urls.put("classHierarchy", UrlBuilder.getUrl("/showClassHierarchy"));
urls.put("classGroups", UrlBuilder.getUrl("/listGroups")); urls.put("classGroups", UrlBuilder.getUrl("/listGroups"));
urls.put("dataPropertyHierarchy", UrlBuilder.getUrl("/showDataPropertyHierarchy")); urls.put("dataPropertyHierarchy", UrlBuilder.getUrl("/showDataPropertyHierarchy"));
urls.put("fauxPropertyList", UrlBuilder.getUrl("/listFauxProperties"));
urls.put("propertyGroups", UrlBuilder.getUrl("/listPropertyGroups")); urls.put("propertyGroups", UrlBuilder.getUrl("/listPropertyGroups"));
urls.put("objectPropertyHierarchy", UrlBuilder.getUrl("/showObjectPropertyHierarchy", new ParamMap("iffRoot", "true"))); urls.put("objectPropertyHierarchy", UrlBuilder.getUrl("/showObjectPropertyHierarchy", new ParamMap("iffRoot", "true")));
map.put("urls", urls); map.put("urls", urls);

View file

@ -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]" ;
}
}

View file

@ -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);
}

View file

@ -7,6 +7,7 @@ import java.util.Objects;
import com.hp.hpl.jena.vocabulary.OWL; 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.Property;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
@ -72,9 +73,12 @@ public interface PropertyDao {
this(OWL_THING, uri, OWL_THING); this(OWL_THING, uri, OWL_THING);
} }
public FullPropertyKey(Property prop) { public FullPropertyKey(Property p) {
this(prop.getDomainVClassURI(), prop.getURI(), prop this(p.getDomainVClassURI(), p.getURI(), p.getRangeVClassURI());
.getRangeVClassURI()); }
public FullPropertyKey(RoleRestrictedProperty p) {
this(p.getDomainVClassURI(), p.getURI(), p.getRangeVClassURI());
} }
public FullPropertyKey(String domainUri, String propertyUri, public FullPropertyKey(String domainUri, String propertyUri,

View file

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

View file

@ -92,6 +92,11 @@ public interface WebappDaoFactory {
*/ */
public VClassDao getVClassDao(); public VClassDao getVClassDao();
/**
* returns a Data Access Object for working with "faux" ObjectProperties.
*/
public FauxPropertyDao getFauxPropertyDao();
/* ==================== DAOs for ABox manipulation ===================== */ /* ==================== DAOs for ABox manipulation ===================== */

View file

@ -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.");
}
}

View file

@ -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.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayModelDao; 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.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.MenuDao; import edu.cornell.mannlib.vitro.webapp.dao.MenuDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
@ -57,6 +58,7 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
transient private DataPropertyStatementDao filteringDataPropertyStatementDao=null; transient private DataPropertyStatementDao filteringDataPropertyStatementDao=null;
transient private IndividualDao filteringIndividualDao=null; transient private IndividualDao filteringIndividualDao=null;
transient private ObjectPropertyDao filteringObjectPropertyDao=null; transient private ObjectPropertyDao filteringObjectPropertyDao=null;
transient private FauxPropertyDao filteringFauxPropertyDao=null;
transient private ObjectPropertyStatementDao filteringObjectPropertyStatementDao=null; transient private ObjectPropertyStatementDao filteringObjectPropertyStatementDao=null;
transient private VClassDao filteringVClassDao=null; transient private VClassDao filteringVClassDao=null;
@ -234,6 +236,14 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
return filteringObjectPropertyDao; return filteringObjectPropertyDao;
} }
public FauxPropertyDao getFauxPropertyDao() {
if (filteringFauxPropertyDao == null ){
filteringFauxPropertyDao = new FauxPropertyDaoFiltering(innerWebappDaoFactory.getFauxPropertyDao(),
filters);
}
return filteringFauxPropertyDao;
}
public VClassDao getVClassDao() { public VClassDao getVClassDao() {
if (filteringVClassDao == null ){ if (filteringVClassDao == null ){

View file

@ -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 + "]";
}
}
}

View file

@ -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.RDF;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class JenaBaseDao extends JenaBaseDaoCon { public class JenaBaseDao extends JenaBaseDaoCon {
@ -574,6 +575,20 @@ public class JenaBaseDao extends JenaBaseDaoCon {
return list; 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 * convenience method for use with functional object properties
*/ */

View file

@ -42,6 +42,7 @@ import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
@ -1137,7 +1138,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
} }
qexec.close(); qexec.close();
} }
FullPropertyKey key = new FullPropertyKey(op); FullPropertyKey key = new FullPropertyKey((RoleRestrictedProperty)op);
String customListViewConfigFileName = customListViewConfigFileMap.get(key); String customListViewConfigFileName = customListViewConfigFileMap.get(key);
if (customListViewConfigFileName == null) { if (customListViewConfigFileName == null) {
log.debug("no list view found for " + key); log.debug("no list view found for " + key);

View file

@ -564,26 +564,36 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
} }
/* /* Removed: see VIVO-766.
* sorts VClasses so that subclasses come before superclasses * 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 class VClassHierarchyRanker implements Comparator<VClass> {
private VClassDao vcDao; // private VClassDao vcDao;
public VClassHierarchyRanker(VClassDao vcDao) { // public VClassHierarchyRanker(VClassDao vcDao) {
this.vcDao = vcDao; // this.vcDao = vcDao;
} // }
@Override // @Override
public int compare(VClass vc1, VClass vc2) { // public int compare(VClass vc1, VClass vc2) {
if (vcDao.isSubClassOf(vc1, vc2)) { // if (vcDao.isSubClassOf(vc1, vc2)) {
return -1; // return -1;
} else if (vcDao.isSubClassOf(vc2, vc1)) { // } else if (vcDao.isSubClassOf(vc2, vc1)) {
return 1; // return 1;
} else { // } else {
return 0; // return 0;
} // }
} // }
} // }
//
public List<PropertyInstance> getAllPropInstByVClass(String classURI) { public List<PropertyInstance> getAllPropInstByVClass(String classURI) {
if (classURI==null || classURI.length()<1) { if (classURI==null || classURI.length()<1) {
@ -708,7 +718,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
return propInsts; 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(); OntModel ontModel = getOntModelSelector().getTBoxModel();

View file

@ -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.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayModelDao; 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.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.MenuDao; import edu.cornell.mannlib.vitro.webapp.dao.MenuDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
@ -360,6 +361,15 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
return objectPropertyDao; return objectPropertyDao;
} }
private FauxPropertyDao fauxPropertyDao = null;
@Override
public FauxPropertyDao getFauxPropertyDao() {
if( fauxPropertyDao == null ) {
fauxPropertyDao = new FauxPropertyDaoJena(this);
}
return fauxPropertyDao;
}
private PropertyInstanceDao propertyInstanceDao = null; private PropertyInstanceDao propertyInstanceDao = null;
@Override @Override
public PropertyInstanceDao getPropertyInstanceDao() { public PropertyInstanceDao getPropertyInstanceDao() {

View file

@ -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);
}
}
}

View file

@ -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.
}
}

View file

@ -34,8 +34,8 @@ public class ContextNodeFields implements DocumentModifier, ContextModelsUser{
protected List<String> queries = new ArrayList<String>(); protected List<String> queries = new ArrayList<String>();
protected boolean shutdown = false; protected boolean shutdown = false;
protected Log log = LogFactory.getLog(ContextNodeFields.class); protected Log log = LogFactory.getLog(ContextNodeFields.class);
//Subclasses may want to utilize rdfService directly (for example, to execute queries that yielding multiple variables mapped to different fields)
private RDFService rdfService; protected RDFService rdfService;
@Override @Override
public void setContextModels(ContextModelAccess models) { public void setContextModels(ContextModelAccess models) {

View file

@ -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.
}
}

View file

@ -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.Literal;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
/** /**
* Execute SPARQL queries against a model. * Execute SPARQL queries against a model.
@ -95,6 +96,15 @@ public class SparqlQueryRunner {
protected abstract T defaultValue(); 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, protected String ifLiteralPresent(QuerySolution solution,
String variableName, String defaultValue) { String variableName, String defaultValue) {
Literal literal = solution.getLiteral(variableName); Literal literal = solution.getLiteral(variableName);
@ -127,4 +137,35 @@ 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 + ">");
}
}
} }

View file

@ -12,7 +12,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
* LockableOntModels. * LockableOntModels.
* *
* <pre> * <pre>
* LockableOntModelSelector lockableOms = new LockingOntModelSelector(oms); * LockableOntModelSelector lockableOms = new LockableOntModelSelector(oms);
* *
* try (LockedOntModel m = lockableOms.getDisplayModel.read()) { * try (LockedOntModel m = lockableOms.getDisplayModel.read()) {
* ... * ...

View file

@ -69,8 +69,7 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
DataPropertyTemplateModel(DataProperty dp, Individual subject, VitroRequest vreq, DataPropertyTemplateModel(DataProperty dp, Individual subject, VitroRequest vreq,
boolean editing, List<DataProperty> populatedDataPropertyList) { boolean editing, List<DataProperty> populatedDataPropertyList) {
super(dp, subject, vreq); super(dp, subject, vreq, dp.getPublicName());
setName(dp.getPublicName());
// Get the config for this data property // Get the config for this data property
try { try {

View file

@ -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.Property;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance; import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; 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 { public class GroupedPropertyList extends BaseTemplateModel {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(GroupedPropertyList.class); private static final Log log = LogFactory.getLog(GroupedPropertyList.class);
private static final int MAX_GROUP_DISPLAY_RANK = 99; private static final int MAX_GROUP_DISPLAY_RANK = 99;
@ -247,16 +246,9 @@ public class GroupedPropertyList extends BaseTemplateModel {
} }
boolean addToList = true; boolean addToList = true;
for(ObjectProperty op : populatedObjectPropertyList) { for(ObjectProperty op : populatedObjectPropertyList) {
RedundancyReason reason = redundant(op, piOp); if (redundant(op, piOp)) {
if(reason != null) { addToList = false;
addToList = false; }
if (reason == RedundancyReason.LABEL_AND_URI_MATCH
&& moreRestrictiveRange(piOp, op, wadf)) {
op.setRangeVClassURI(piOp.getRangeVClassURI());
op.setRangeVClass(piOp.getRangeVClass());
}
break;
}
} }
if(addToList) { if(addToList) {
propertyList.add(piOp); propertyList.add(piOp);
@ -281,67 +273,8 @@ public class GroupedPropertyList extends BaseTemplateModel {
return propertyList; return propertyList;
} }
private enum RedundancyReason { private boolean redundant(ObjectProperty op, ObjectProperty op2) {
LABEL_AND_URI_MATCH, LABEL_URI_DOMAIN_AND_RANGE_MATCH return new FullPropertyKey((Property)op).equals(new FullPropertyKey((Property)op2));
}
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 void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri, private void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri,

View file

@ -86,8 +86,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
boolean editing) boolean editing)
throws InvalidConfigurationException { throws InvalidConfigurationException {
super(op, subject, vreq); super(op, subject, vreq, op.getDomainPublic());
setName(op.getDomainPublic());
sortDirection = op.getDomainEntitySortDirection(); sortDirection = op.getDomainEntitySortDirection();
domainUri = op.getDomainVClassURI(); domainUri = op.getDomainVClassURI();
@ -232,7 +231,6 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
public static ObjectPropertyTemplateModel getObjectPropertyTemplateModel(ObjectProperty op, public static ObjectPropertyTemplateModel getObjectPropertyTemplateModel(ObjectProperty op,
Individual subject, VitroRequest vreq, boolean editing, Individual subject, VitroRequest vreq, boolean editing,
List<ObjectProperty> populatedObjectPropertyList) { List<ObjectProperty> populatedObjectPropertyList) {
if (op.getCollateBySubclass()) { if (op.getCollateBySubclass()) {
try { try {
return new CollatedObjectPropertyTemplateModel(op, subject, vreq, editing, populatedObjectPropertyList); return new CollatedObjectPropertyTemplateModel(op, subject, vreq, editing, populatedObjectPropertyList);

View file

@ -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.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; 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.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.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
@ -40,21 +40,23 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
protected String addUrl; protected String addUrl;
private String name; private String name;
private FauxProperty fauxProperty;
PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq, String name) {
PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq) {
this.vreq = vreq; this.vreq = vreq;
subjectUri = subject.getURI(); subjectUri = subject.getURI();
this.property = property; this.property = property;
propertyUri = property.getURI(); propertyUri = property.getURI();
localName = property.getLocalName(); localName = property.getLocalName();
setVerboseDisplayValues(property); this.name = name;
addUrl = ""; addUrl = "";
// Do in subclass constructor. The label has not been set on the property, and the fauxProperty = isFauxProperty(property);
// means of getting the label differs between object and data properties. if (fauxProperty != null) {
// this.name = property.getLabel(); this.name = fauxProperty.getDisplayName();
}
setVerboseDisplayValues(property);
} }
protected void setVerboseDisplayValues(Property property) { protected void setVerboseDisplayValues(Property property) {
@ -101,35 +103,31 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
String editUrl = UrlBuilder.getUrl(getPropertyEditRoute(), "uri", property.getURI()); String editUrl = UrlBuilder.getUrl(getPropertyEditRoute(), "uri", property.getURI());
verboseDisplay.put("propertyEditUrl", editUrl); verboseDisplay.put("propertyEditUrl", editUrl);
if(isFauxProperty(property)) { if (fauxProperty != null) {
verboseDisplay.put("fauxProperty", "true"); verboseDisplay.put("fauxProperty", assembleFauxPropertyValues(fauxProperty));
} }
} }
private boolean isFauxProperty(Property prop) { private FauxProperty isFauxProperty(Property prop) {
if(!(prop instanceof ObjectProperty)) { FauxPropertyDao fpDao = vreq.getUnfilteredWebappDaoFactory().getFauxPropertyDao();
return false; return fpDao.getFauxPropertyByUris(prop.getDomainVClassURI(), prop.getURI(), prop.getRangeVClassURI());
} }
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 abstract Route getPropertyEditRoute();
protected void setName(String name) {
this.name = name;
}
public String toString() { public String toString() {
return String.format("%s on %s", return String.format("%s on %s",
propertyUri != null ? propertyUri : "null Prop URI", propertyUri != null ? propertyUri : "null Prop URI",

View file

@ -12,7 +12,7 @@ import static org.junit.Assert.assertNull;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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 stubs.javax.servlet.ServletContextStub;
import com.hp.hpl.jena.ontology.OntModel; 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.ArrayIdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; 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.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.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction;
@ -71,9 +70,8 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
public void setUp() throws Exception { public void setUp() throws Exception {
ctx = new ServletContextStub(); ctx = new ServletContextStub();
PropertyRestrictionPolicyHelper prph = PropertyRestrictionPolicyHelperStub PropertyRestrictionBeanStub
.getInstance(new String[] { UNSAFE_NS }); .getInstance(new String[] { UNSAFE_NS });
PropertyRestrictionPolicyHelper.setBean(ctx, prph);
policy = new SelfEditingPolicy(ctx); policy = new SelfEditingPolicy(ctx);
@ -87,14 +85,13 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
@Test @Test
public void testProhibitedProperties() { public void testProhibitedProperties() {
PropertyRestrictionPolicyHelper prph = PropertyRestrictionPolicyHelperStub PropertyRestrictionBeanStub
.getInstance(new String[] { UNSAFE_NS }, new String[] { .getInstance(new String[] { UNSAFE_NS }, new String[] {
"http://mannlib.cornell.edu/bad#prp234", "http://mannlib.cornell.edu/bad#prp234",
"http://mannlib.cornell.edu/bad#prp999", "http://mannlib.cornell.edu/bad#prp999",
"http://mannlib.cornell.edu/bad#prp333", "http://mannlib.cornell.edu/bad#prp333",
"http://mannlib.cornell.edu/bad#prp777", "http://mannlib.cornell.edu/bad#prp777",
"http://mannlib.cornell.edu/bad#prp0020" }); "http://mannlib.cornell.edu/bad#prp0020" });
PropertyRestrictionPolicyHelper.setBean(ctx, prph);
whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI, whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI,
new Property("http://mannlib.cornell.edu/bad#prp234"), SAFE_RESOURCE); new Property("http://mannlib.cornell.edu/bad#prp234"), SAFE_RESOURCE);

View file

@ -10,7 +10,7 @@ import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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 stubs.javax.servlet.ServletContextStub;
import com.hp.hpl.jena.ontology.OntModel; 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.Identifier;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; 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.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.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
@ -78,9 +77,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
ServletContextStub ctx = new ServletContextStub(); ServletContextStub ctx = new ServletContextStub();
PropertyRestrictionPolicyHelper.setBean(ctx, PropertyRestrictionBeanStub.getInstance(new String[] { ADMIN_NS });
PropertyRestrictionPolicyHelperStub
.getInstance(new String[] { ADMIN_NS }));
policy = new SelfEditingPolicy(ctx); policy = new SelfEditingPolicy(ctx);
Assert.assertNotNull(policy); Assert.assertNotNull(policy);

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -2,11 +2,19 @@
package edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery; 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.ByteArrayOutputStream;
import java.io.StringReader; 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.Before;
import org.junit.Test; import org.junit.Test;
@ -25,6 +33,20 @@ import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException;
* formats. * formats.
*/ */
public class SparqlQueryApiExecutorTest extends AbstractTestClass { 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 = "" // private static final String MODEL_CONTENTS_N3 = "" //
+ "<http://here.edu/subject> \n" + "<http://here.edu/subject> \n"
+ " <http://here.edu/predicate> <http://here.edu/object> ." + " <http://here.edu/predicate> <http://here.edu/object> ."
@ -201,24 +223,24 @@ public class SparqlQueryApiExecutorTest extends AbstractTestClass {
@Test(expected = NullPointerException.class) @Test(expected = NullPointerException.class)
public void nullRdfService() throws Exception { 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) @Test(expected = NullPointerException.class)
public void nullQuery() throws Exception { public void nullQuery() throws Exception {
SparqlQueryApiExecutor.instance(rdfService, null, "text/plain"); SparqlQueryApiExecutor.instance(rdfService, null, ACCEPT_TEXT);
fail("nullQuery not implemented"); fail("nullQuery not implemented");
} }
@Test(expected = QueryParseException.class) @Test(expected = QueryParseException.class)
public void emptyQuery() throws Exception { public void emptyQuery() throws Exception {
SparqlQueryApiExecutor.instance(rdfService, "", "text/plain"); SparqlQueryApiExecutor.instance(rdfService, "", ACCEPT_TEXT);
fail("emptyQuery not implemented"); fail("emptyQuery not implemented");
} }
@Test(expected = QueryParseException.class) @Test(expected = QueryParseException.class)
public void cantParseQuery() throws Exception { public void cantParseQuery() throws Exception {
SparqlQueryApiExecutor.instance(rdfService, "BOGUS", "text/plain"); SparqlQueryApiExecutor.instance(rdfService, "BOGUS", ACCEPT_TEXT);
fail("cantParseQuery not implemented"); fail("cantParseQuery not implemented");
} }
@ -237,179 +259,177 @@ public class SparqlQueryApiExecutorTest extends AbstractTestClass {
@Test @Test
public void selectToText() throws Exception { 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); SELECT_RESULT_TEXT);
} }
@Test @Test
public void selectToCsv() throws Exception { 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); SELECT_RESULT_CSV);
} }
@Test @Test
public void selectToTsv() throws Exception { public void selectToTsv() throws Exception {
executeQuery("select to tsv", SELECT_ALL_QUERY, executeQuery("select to tsv", SELECT_ALL_QUERY, ACCEPT_TSV,
"text/tab-separated-values", SELECT_RESULT_TSV); SELECT_RESULT_TSV);
} }
@Test @Test
public void selectToXml() throws Exception { public void selectToXml() throws Exception {
executeQuery("select to xml", SELECT_ALL_QUERY, executeQuery("select to xml", SELECT_ALL_QUERY, ACCEPT_SPARQL_XML,
"application/sparql-results+xml", SELECT_RESULT_XML); SELECT_RESULT_XML);
} }
@Test @Test
public void selectToJson() throws Exception { public void selectToJson() throws Exception {
executeQuery("select to json", SELECT_ALL_QUERY, executeQuery("select to json", SELECT_ALL_QUERY, ACCEPT_SPARQL_JSON,
"application/sparql-results+json", SELECT_RESULT_JSON); SELECT_RESULT_JSON);
} }
@Test @Test
public void selectWithInvalidContentType() throws Exception { public void selectWithInvalidContentType() throws Exception {
executeWithInvalidAcceptHeader("select with application/rdf+xml", 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, executeWithInvalidAcceptHeader("select with text/n3", SELECT_ALL_QUERY,
"text/n3"); ACCEPT_N3);
executeWithInvalidAcceptHeader("select with text/turtle", executeWithInvalidAcceptHeader("select with text/turtle",
SELECT_ALL_QUERY, "text/turtle"); SELECT_ALL_QUERY, ACCEPT_TURTLE);
executeWithInvalidAcceptHeader("select with application/json", executeWithInvalidAcceptHeader("select with application/json",
SELECT_ALL_QUERY, "application/json"); SELECT_ALL_QUERY, ACCEPT_JSON);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@Test @Test
public void askToText() throws Exception { public void askToText() throws Exception {
executeQuery("ask to text", ASK_ALL_QUERY, "text/plain", executeQuery("ask to text", ASK_ALL_QUERY, ACCEPT_TEXT, ASK_RESULT_TEXT);
ASK_RESULT_TEXT);
} }
@Test @Test
public void askToCsv() throws Exception { 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 @Test
public void askToTsv() throws Exception { public void askToTsv() throws Exception {
executeQuery("ask to tsv", ASK_ALL_QUERY, "text/tab-separated-values", executeQuery("ask to tsv", ASK_ALL_QUERY, ACCEPT_TSV, ASK_RESULT_TSV);
ASK_RESULT_TSV);
} }
@Test @Test
public void askToXml() throws Exception { public void askToXml() throws Exception {
executeQuery("ask to xml", ASK_ALL_QUERY, executeQuery("ask to xml", ASK_ALL_QUERY, ACCEPT_SPARQL_XML,
"application/sparql-results+xml", ASK_RESULT_XML); ASK_RESULT_XML);
} }
@Test @Test
public void askToJson() throws Exception { public void askToJson() throws Exception {
executeQuery("ask to json", ASK_ALL_QUERY, executeQuery("ask to json", ASK_ALL_QUERY, ACCEPT_SPARQL_JSON,
"application/sparql-results+json", ASK_RESULT_JSON); ASK_RESULT_JSON);
} }
@Test @Test
public void askWithInvalidAcceptHeader() throws Exception { public void askWithInvalidAcceptHeader() throws Exception {
executeWithInvalidAcceptHeader("ask with application/rdf+xml", 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, executeWithInvalidAcceptHeader("ask with text/n3", ASK_ALL_QUERY,
"text/n3"); ACCEPT_N3);
executeWithInvalidAcceptHeader("ask with text/turtle", ASK_ALL_QUERY, executeWithInvalidAcceptHeader("ask with text/turtle", ASK_ALL_QUERY,
"text/turtle"); ACCEPT_TURTLE);
executeWithInvalidAcceptHeader("ask with application/json", executeWithInvalidAcceptHeader("ask with application/json",
ASK_ALL_QUERY, "application/json"); ASK_ALL_QUERY, ACCEPT_JSON);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@Test @Test
public void constructToText() throws Exception { 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); CONSTRUCT_RESULT_TEXT);
} }
@Test @Test
public void constructToRdfXml() throws Exception { public void constructToRdfXml() throws Exception {
executeQuery("construct to rdf/xml", CONSTRUCT_ALL_QUERY, executeQuery("construct to rdf/xml", CONSTRUCT_ALL_QUERY,
"application/rdf+xml", CONSTRUCT_RESULT_RDFXML); ACCEPT_RDFXML, CONSTRUCT_RESULT_RDFXML);
} }
@Test @Test
public void constructToN3() throws Exception { 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); CONSTRUCT_RESULT_N3);
} }
@Test @Test
public void constructToTurtle() throws Exception { 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); CONSTRUCT_RESULT_TURTLE);
} }
@Test @Test
public void constructToJsonld() throws Exception { public void constructToJsonld() throws Exception {
executeQuery("construct to JSON-LD", CONSTRUCT_ALL_QUERY, executeQuery("construct to JSON-LD", CONSTRUCT_ALL_QUERY, ACCEPT_JSON,
"application/json", CONSTRUCT_RESULT_JSONLD); CONSTRUCT_RESULT_JSONLD);
} }
@Test @Test
public void constructWithInvalidAcceptHeader() throws Exception { public void constructWithInvalidAcceptHeader() throws Exception {
executeWithInvalidAcceptHeader("construct with text/csv", executeWithInvalidAcceptHeader("construct with text/csv",
CONSTRUCT_ALL_QUERY, "text/csv"); CONSTRUCT_ALL_QUERY, ACCEPT_CSV);
executeWithInvalidAcceptHeader("construct with text/tsv", executeWithInvalidAcceptHeader("construct with text/tsv",
CONSTRUCT_ALL_QUERY, "text/tsv"); CONSTRUCT_ALL_QUERY, "text/tsv");
executeWithInvalidAcceptHeader( executeWithInvalidAcceptHeader(
"construct with application/sparql-results+xml", "construct with application/sparql-results+xml",
CONSTRUCT_ALL_QUERY, "application/sparql-results+xml"); CONSTRUCT_ALL_QUERY, ACCEPT_SPARQL_XML);
executeWithInvalidAcceptHeader( executeWithInvalidAcceptHeader(
"construct with application/sparql-results+json", "construct with application/sparql-results+json",
CONSTRUCT_ALL_QUERY, "application/sparql-results+json"); CONSTRUCT_ALL_QUERY, ACCEPT_SPARQL_JSON);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@Test @Test
public void describeToText() throws Exception { 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); DESCRIBE_RESULT_TEXT);
} }
@Test @Test
public void describeToRdfXml() throws Exception { public void describeToRdfXml() throws Exception {
executeQuery("describe to rdf/xml", DESCRIBE_ALL_QUERY, executeQuery("describe to rdf/xml", DESCRIBE_ALL_QUERY, ACCEPT_RDFXML,
"application/rdf+xml", DESCRIBE_RESULT_RDFXML); DESCRIBE_RESULT_RDFXML);
} }
@Test @Test
public void describeToN3() throws Exception { 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); DESCRIBE_RESULT_N3);
} }
@Test @Test
public void describeToTurtle() throws Exception { 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); DESCRIBE_RESULT_TURTLE);
} }
@Test @Test
public void describeToJsonld() throws Exception { public void describeToJsonld() throws Exception {
executeQuery("describe to JSON-LD", DESCRIBE_ALL_QUERY, executeQuery("describe to JSON-LD", DESCRIBE_ALL_QUERY, ACCEPT_JSON,
"application/json", DESCRIBE_RESULT_JSONLD); DESCRIBE_RESULT_JSONLD);
} }
@Test @Test
public void describeWithInvalidAcceptHeader() throws Exception { public void describeWithInvalidAcceptHeader() throws Exception {
executeWithInvalidAcceptHeader("describe with text/csv", executeWithInvalidAcceptHeader("describe with text/csv",
DESCRIBE_ALL_QUERY, "text/csv"); DESCRIBE_ALL_QUERY, ACCEPT_CSV);
executeWithInvalidAcceptHeader("describe with text/tsv", executeWithInvalidAcceptHeader("describe with text/tsv",
DESCRIBE_ALL_QUERY, "text/tsv"); DESCRIBE_ALL_QUERY, "text/tsv");
executeWithInvalidAcceptHeader( executeWithInvalidAcceptHeader(
"describe with application/sparql-results+xml", "describe with application/sparql-results+xml",
DESCRIBE_ALL_QUERY, "application/sparql-results+xml"); DESCRIBE_ALL_QUERY, ACCEPT_SPARQL_XML);
executeWithInvalidAcceptHeader( executeWithInvalidAcceptHeader(
"describe with application/sparql-results+json", "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); rdfService, queryString, acceptHeader);
executor.executeAndFormat(out); 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, private void executeWithInvalidAcceptHeader(String message,

View file

@ -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")));
}
}

View file

@ -970,7 +970,7 @@ public class ConfigurationBeanLoaderTest extends AbstractTestClass {
// Nothing. // Nothing.
} }
public class AGoodApple implements OneBadAppleSpoilsTheBunch { public static class AGoodApple implements OneBadAppleSpoilsTheBunch {
// Nothing // Nothing
} }

View file

@ -10,10 +10,10 @@ import java.io.StringReader;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.hamcrest.CoreMatchers;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
@ -71,7 +71,7 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
@Test @Test
public void invalidXml() throws InvalidConfigurationException { public void invalidXml() throws InvalidConfigurationException {
suppressSyserr(); // catch the error report from the XML parser suppressSyserr(); // catch the error report from the XML parser
expectException(JUnitMatchers expectException(CoreMatchers
.containsString("Config file is not valid XML:")); .containsString("Config file is not valid XML:"));
readConfigFile("<unbalancedTag>"); readConfigFile("<unbalancedTag>");
} }

View file

@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; 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.ModelAccess.ReasoningOption.ASSERTIONS_AND_INFERENCES;
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION; import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -27,6 +28,7 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; 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.ObjectPropertyDaoStub;
import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub;
@ -60,6 +62,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
private WebappDaoFactoryStub wadf; private WebappDaoFactoryStub wadf;
private ObjectPropertyDaoStub opDao; private ObjectPropertyDaoStub opDao;
private FauxPropertyDaoStub fpDao;
private ServletContextStub ctx; private ServletContextStub ctx;
private HttpSessionStub session; private HttpSessionStub session;
@ -117,8 +120,10 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
logMessages = new StringWriter(); logMessages = new StringWriter();
opDao = new ObjectPropertyDaoStub(); opDao = new ObjectPropertyDaoStub();
fpDao = new FauxPropertyDaoStub();
wadf = new WebappDaoFactoryStub(); wadf = new WebappDaoFactoryStub();
wadf.setObjectPropertyDao(opDao); wadf.setObjectPropertyDao(opDao);
wadf.setFauxPropertyDao(fpDao);
ctx = new ServletContextStub(); ctx = new ServletContextStub();
// create paths for all of the files in the temporary config directory. // 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 = new ModelAccessFactoryStub();
mafs.get(vreq).setWebappDaoFactory(wadf, ASSERTIONS_AND_INFERENCES); mafs.get(vreq).setWebappDaoFactory(wadf, ASSERTIONS_AND_INFERENCES);
mafs.get(vreq).setWebappDaoFactory(wadf, POLICY_NEUTRAL);
subject = new IndividualImpl(); subject = new IndividualImpl();

View file

@ -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.");
}
}

View file

@ -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);
}
}

View file

@ -2,6 +2,7 @@
package stubs.edu.cornell.mannlib.vitro.webapp.dao; package stubs.edu.cornell.mannlib.vitro.webapp.dao;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -57,6 +58,11 @@ public class DataPropertyDaoStub implements DataPropertyDao {
// Stub methods // Stub methods
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@Override
public List<DataProperty> getAllDataProperties() {
return new ArrayList<>(dpMap.values());
}
@Override @Override
public DataProperty getDataPropertyByURI(String dataPropertyURI) { public DataProperty getDataPropertyByURI(String dataPropertyURI) {
return dpMap.get(dataPropertyURI); return dpMap.get(dataPropertyURI);
@ -189,12 +195,6 @@ public class DataPropertyDaoStub implements DataPropertyDao {
"PropertyDao.getClassesWithRestrictionOnProperty() not implemented."); "PropertyDao.getClassesWithRestrictionOnProperty() not implemented.");
} }
@Override
public List getAllDataProperties() {
throw new RuntimeException(
"DataPropertyDao.getAllDataProperties() not implemented.");
}
@Override @Override
public List getAllExternalIdDataProperties() { public List getAllExternalIdDataProperties() {
throw new RuntimeException( throw new RuntimeException(

View file

@ -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.");
}
}

View file

@ -2,6 +2,7 @@
package stubs.edu.cornell.mannlib.vitro.webapp.dao; package stubs.edu.cornell.mannlib.vitro.webapp.dao;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -41,7 +42,8 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
opMap.put(uri, property); opMap.put(uri, property);
} }
public void setCustomListViewConfigFileName(ObjectProperty property, String filename) { public void setCustomListViewConfigFileName(ObjectProperty property,
String filename) {
if (property == null) { if (property == null) {
throw new NullPointerException("property may not be null."); throw new NullPointerException("property may not be null.");
} }
@ -58,6 +60,11 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
// Stub methods // Stub methods
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@Override
public List<ObjectProperty> getAllObjectProperties() {
return new ArrayList<>(opMap.values());
}
@Override @Override
public ObjectProperty getObjectPropertyByURI(String objectPropertyURI) { public ObjectProperty getObjectPropertyByURI(String objectPropertyURI) {
if (objectPropertyURI == null) { if (objectPropertyURI == null) {
@ -66,17 +73,17 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
return opMap.get(objectPropertyURI); return opMap.get(objectPropertyURI);
} }
@Override @Override
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
String domainURI, String rangeURI) { String domainURI, String rangeURI) {
return getObjectPropertyByURI(objectPropertyURI); return getObjectPropertyByURI(objectPropertyURI);
} }
@Override @Override
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
String domainURI, String rangeURI, ObjectProperty base) { String domainURI, String rangeURI, ObjectProperty base) {
return getObjectPropertyByURI(objectPropertyURI); return getObjectPropertyByURI(objectPropertyURI);
} }
@Override @Override
public String getCustomListViewConfigFileName(ObjectProperty objectProperty) { public String getCustomListViewConfigFileName(ObjectProperty objectProperty) {
@ -194,12 +201,6 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
"ObjectPropertyDaoStub.getClassesWithRestrictionOnProperty() not implemented."); "ObjectPropertyDaoStub.getClassesWithRestrictionOnProperty() not implemented.");
} }
@Override
public List<ObjectProperty> getAllObjectProperties() {
throw new RuntimeException(
"ObjectPropertyDaoStub.getAllObjectProperties() not implemented.");
}
@Override @Override
public List<ObjectProperty> getObjectPropertiesForObjectPropertyStatements( public List<ObjectProperty> getObjectPropertiesForObjectPropertyStatements(
List objectPropertyStatements) { List objectPropertyStatements) {

View file

@ -3,7 +3,6 @@
package stubs.edu.cornell.mannlib.vitro.webapp.dao; package stubs.edu.cornell.mannlib.vitro.webapp.dao;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao; 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.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayModelDao; 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.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.MenuDao; import edu.cornell.mannlib.vitro.webapp.dao.MenuDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
@ -42,6 +42,7 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
private MenuDao menuDao; private MenuDao menuDao;
private ObjectPropertyDao objectPropertyDao; private ObjectPropertyDao objectPropertyDao;
private ObjectPropertyStatementDao objectPropertyStatementDao; private ObjectPropertyStatementDao objectPropertyStatementDao;
private FauxPropertyDao fauxPropertyDao;
private OntologyDao ontologyDao; private OntologyDao ontologyDao;
private UserAccountsDao userAccountsDao; private UserAccountsDao userAccountsDao;
private VClassDao vClassDao; private VClassDao vClassDao;
@ -74,6 +75,10 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
this.objectPropertyStatementDao = objectPropertyStatementDao; this.objectPropertyStatementDao = objectPropertyStatementDao;
} }
public void setFauxPropertyDao(FauxPropertyDao fauxPropertyDao) {
this.fauxPropertyDao = fauxPropertyDao;
}
public void setOntologyDao(OntologyDao ontologyDao) { public void setOntologyDao(OntologyDao ontologyDao) {
this.ontologyDao = ontologyDao; this.ontologyDao = ontologyDao;
} }
@ -120,9 +125,15 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
return this.objectPropertyDao; return this.objectPropertyDao;
} }
@Override
public FauxPropertyDao getFauxPropertyDao() {
return this.fauxPropertyDao;
}
@Override @Override
public ObjectPropertyStatementDao getObjectPropertyStatementDao() { public ObjectPropertyStatementDao getObjectPropertyStatementDao() {
return this.objectPropertyStatementDao; } return this.objectPropertyStatementDao;
}
@Override @Override
public OntologyDao getOntologyDao() { public OntologyDao getOntologyDao() {

View file

@ -13,9 +13,6 @@ edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests 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.utils.developer.DeveloperSettings$Setup
edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl$ComponentsSetup 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.SimpleReasonerSetup
#edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase #edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
edu.cornell.mannlib.vitro.webapp.migration.Release18Migrator
# Must run after JenaDataSourceSetup # Must run after JenaDataSourceSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.ThemeInfoSetup 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.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 edu.cornell.mannlib.vitro.webapp.auth.policy.setup.CommonPolicyFamilySetup

View file

@ -762,6 +762,15 @@
<url-pattern>/showDataPropertyHierarchy</url-pattern> <url-pattern>/showDataPropertyHierarchy</url-pattern>
</servlet-mapping> </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>
<servlet-name>ListPropertyWebappsController</servlet-name> <servlet-name>ListPropertyWebappsController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ListPropertyWebappsController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ListPropertyWebappsController</servlet-class>

View file

@ -888,3 +888,9 @@ 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. 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

View 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();
});
}
}

View 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 &quot;more ...&quot; 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>

View file

@ -18,7 +18,7 @@
<tr><td colspan="5"><hr class="formDivider"/></td></tr> <tr><td colspan="5"><hr class="formDivider"/></td></tr>
<tr class="editformcell"> <tr class="editformcell">
<td style="vertical-align:top;" valign="top" colspan="1"> <td style="vertical-align:top;" valign="top" colspan="1">
<b>Ontology</b><br/><br/> <b>Ontology</b><br/>
<c:choose> <c:choose>
<c:when test="${_action eq 'update'}"> <c:when test="${_action eq 'update'}">
<select name="Namespace" disabled="disabled"><form:option name="Namespace"/></select><br/> <select name="Namespace" disabled="disabled"><form:option name="Namespace"/></select><br/>
@ -30,8 +30,7 @@
</c:choose> </c:choose>
</td> </td>
<td style="vertical-align:top;" valign="top" colspan="2"> <td style="vertical-align:top;" valign="top" colspan="2">
<b>Internal name*</b><br/> <b>Internal name*</b> (RDF local name)<br/>
(RDF local name)<br/>
<c:choose> <c:choose>
<c:when test="${_action eq 'update'}"> <c:when test="${_action eq 'update'}">
<input type="text" class="fullWidthInput" disabled="disabled" name="LocalName" value="<form:value name='LocalName'/>" /><br/> <input type="text" class="fullWidthInput" disabled="disabled" name="LocalName" value="<form:value name='LocalName'/>" /><br/>
@ -49,7 +48,7 @@
</c:if> </c:if>
</td> </td>
<td style="vertical-align:top;" valign="top" colspan="2"> <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" /> <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:set var="DomainPublicError"><form:error name="DomainPublic"/></c:set>
<c:if test="${!empty DomainPublicError}"> <c:if test="${!empty DomainPublicError}">

View file

@ -91,6 +91,53 @@
</td> </td>
</tr> </tr>
<tr><td colspan="3"><hr/></td></tr>
<!-- _____________________________________________ faux properties __________________________________________ -->
<tr valign="bottom" align="center">
<td colspan="2" valign="bottom" align="left">
<c:if test="${!empty fauxproperties}">
<c:forEach var="fauxproperty" items="${fauxproperties}">
<ul style="list-style-type:none;">
<li>
<c:choose>
<c:when test="${empty fauxproperty.domainLabel}">
<c:url var="fauxpropertyURL" value="editForm">
<c:param name="controller" value="FauxProperty"/>
<c:param name="baseUri" value="${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> <tr><td colspan="3"><hr/></td></tr>
<!-- _____________________________________________ superproperties __________________________________________ --> <!-- _____________________________________________ superproperties __________________________________________ -->
<tr valign="bottom" align="center"> <tr valign="bottom" align="center">

View file

@ -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>')}

View file

@ -33,6 +33,7 @@
<ul role="navigation"> <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.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.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> <li role="listitem"><a href="${ontologyEditor.urls.propertyGroups}" title="${i18n().property_groups}">${i18n().property_groups}</a></li>
</ul> </ul>

View file

@ -231,14 +231,16 @@ name will be used as the label. -->
<#local verboseDisplay = property.verboseDisplay!> <#local verboseDisplay = property.verboseDisplay!>
<#if verboseDisplay?has_content> <#if verboseDisplay?has_content>
<section class="verbosePropertyListing"> <section class="verbosePropertyListing">
<#if verboseDisplay.fauxProperty??> <#if verboseDisplay.fauxProperty?has_content>
a faux property of <a class="propertyLink" href="${verboseDisplay.fauxProperty.propertyEditUrl}" title="${i18n().name}">
${verboseDisplay.fauxProperty.displayName}</a>
is a faux property of
</#if> </#if>
<a class="propertyLink" href="${verboseDisplay.propertyEditUrl}" title="${i18n().name}">${verboseDisplay.localName}</a> <a class="propertyLink" href="${verboseDisplay.propertyEditUrl}" title="${i18n().name}">${verboseDisplay.localName}</a>
(<span>${property.type?lower_case}</span> property); (<span>${property.type?lower_case}</span> property);
order in group: <span>${verboseDisplay.displayRank};</span> order in group: <span>${verboseDisplay.displayRank}</span>;
display level: <span>${verboseDisplay.displayLevel};</span> display level: <span>${verboseDisplay.displayLevel}</span>;
update level: <span>${verboseDisplay.updateLevel};</span> update level: <span>${verboseDisplay.updateLevel}</span>;
publish level: <span>${verboseDisplay.publishLevel}</span> publish level: <span>${verboseDisplay.publishLevel}</span>
</section> </section>
</#if> </#if>