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

@ -6,23 +6,27 @@ import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
import edu.cornell.mannlib.vedit.beans.FormObject;
import edu.cornell.mannlib.vedit.beans.Option;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
public class FormUtils {
@ -247,6 +251,35 @@ public class FormUtils {
}
return vclassOptionList;
}
public static List<Option> makeOptionListOfSubVClasses(
WebappDaoFactory wadf, String parentVClassUri,
String selectedVClassURI) {
VClassDao vClassDao = wadf.getVClassDao();
Set<String> uris = new HashSet<>(vClassDao.getAllSubClassURIs(parentVClassUri));
uris.add(parentVClassUri);
List<Option> options = new LinkedList<>();
for (String vclassUri: uris) {
VClass vclass = vClassDao.getVClassByURI(vclassUri);
Option option = new Option();
option.setValue(vclass.getURI());
option.setBody(vclass.getPickListName());
options.add(option);
if(Objects.equals(selectedVClassURI, vclass.getURI())) {
option.setSelected(true);
}
}
Collections.sort(options, new Comparator<Option>() {
@Override
public int compare(Option o1, Option o2) {
return o1.getBody().compareTo(o2.getBody());
}});
return options;
}
public static void beanSet(Object newObj, String field, String value) {
beanSet (newObj, field, value, null);

View file

@ -2,12 +2,10 @@
package edu.cornell.mannlib.vitro.webapp.auth.permissions;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement;
@ -30,10 +28,8 @@ public class DisplayByRolePermission extends Permission {
private final String roleName;
private final RoleLevel roleLevel;
private final ServletContext ctx;
public DisplayByRolePermission(String roleName, RoleLevel roleLevel,
ServletContext ctx) {
public DisplayByRolePermission(String roleName, RoleLevel roleLevel) {
super(NAMESPACE + roleName);
if (roleName == null) {
@ -42,13 +38,9 @@ public class DisplayByRolePermission extends Permission {
if (roleLevel == null) {
throw new NullPointerException("roleLevel may not be null.");
}
if (ctx == null) {
throw new NullPointerException("context may not be null.");
}
this.roleName = roleName;
this.roleLevel = roleLevel;
this.ctx = ctx;
}
@Override
@ -110,22 +102,21 @@ public class DisplayByRolePermission extends Permission {
* subject, its predicate, and its object.
*/
private boolean isAuthorized(DisplayObjectPropertyStatement action) {
String subjectUri = action.getSubjectUri();
String subjectUri = action.getSubjectUri();
String objectUri = action.getObjectUri();
Property op = action.getProperty();
return canDisplayResource(subjectUri)
&& canDisplayPredicate(op)
return canDisplayResource(subjectUri) && canDisplayPredicate(op)
&& canDisplayResource(objectUri);
}
private boolean canDisplayResource(String resourceUri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource(
return PropertyRestrictionBean.getBean().canDisplayResource(
resourceUri, this.roleLevel);
}
private boolean canDisplayPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx)
.canDisplayPredicate(predicate, this.roleLevel);
return PropertyRestrictionBean.getBean().canDisplayPredicate(predicate,
this.roleLevel);
}
@Override

View file

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

View file

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

View file

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

View file

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

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

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

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 edu.cornell.mannlib.vitro.webapp.auth.policy.BasicPolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
@ -31,13 +31,13 @@ public abstract class AbstractRelationshipPolicy implements PolicyIface {
}
protected boolean canModifyResource(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
uri, RoleLevel.SELF);
return PropertyRestrictionBean.getBean().canModifyResource(uri,
RoleLevel.SELF);
}
protected boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
predicate, RoleLevel.SELF);
return PropertyRestrictionBean.getBean().canModifyPredicate(predicate,
RoleLevel.SELF);
}
protected PolicyDecision cantModifyResource(String uri) {

View file

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

View file

@ -6,13 +6,15 @@ import java.text.Collator;
import java.util.List;
import java.util.LinkedList;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
/**
* class representing a property that relates an entity (object)
* to a data literal
* @author bjl23
*
*/
public class DataProperty extends Property implements Comparable<DataProperty>, ResourceBean {
public class DataProperty extends Property implements Comparable<DataProperty>, ResourceBean, RoleRestrictedProperty {
private String name = null;
private String publicName = null;

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 edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
/**
* a class representing an object property
*
*/
public class ObjectProperty extends Property implements Comparable<ObjectProperty>, ResourceBean, Cloneable
public class ObjectProperty extends Property implements Comparable<ObjectProperty>, ResourceBean, Cloneable, RoleRestrictedProperty
{
private static final Log log = LogFactory.getLog(ObjectProperty.class.getName());

View file

@ -46,6 +46,13 @@ public class VitroApiServlet extends HttpServlet {
Authenticator auth = Authenticator.getInstance(req);
UserAccount account = auth.getAccountForInternalAuth(email);
if (auth.accountRequiresEditing(account)) {
log.debug("Account " + email + " requires editing.");
throw new AuthException("user account must include first and "
+ "last names and a valid email address.");
}
if (!auth.isCurrentPassword(account, password)) {
log.debug("Invalid: '" + email + "'/'" + password + "'");
throw new AuthException("email/password combination is not valid");
@ -57,6 +64,11 @@ public class VitroApiServlet extends HttpServlet {
throw new AuthException("Account is not authorized");
}
if (account.isPasswordChangeRequired()) {
log.debug("Account " + email + " requires a new password.");
throw new AuthException("user account requires a new password.");
}
log.debug("Authorized for '" + email + "'");
}

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

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

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

View file

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

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 edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
@ -72,9 +73,12 @@ public interface PropertyDao {
this(OWL_THING, uri, OWL_THING);
}
public FullPropertyKey(Property prop) {
this(prop.getDomainVClassURI(), prop.getURI(), prop
.getRangeVClassURI());
public FullPropertyKey(Property p) {
this(p.getDomainVClassURI(), p.getURI(), p.getRangeVClassURI());
}
public FullPropertyKey(RoleRestrictedProperty p) {
this(p.getDomainVClassURI(), p.getURI(), p.getRangeVClassURI());
}
public FullPropertyKey(String domainUri, String propertyUri,

View file

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

View file

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

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

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.RDFS;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class JenaBaseDao extends JenaBaseDaoCon {
@ -574,6 +575,20 @@ public class JenaBaseDao extends JenaBaseDaoCon {
return list;
}
protected RoleLevel getMostRestrictiveRoleLevel(Resource res, Property prop) {
RoleLevel level = RoleLevel.getRoleByUri(null);
for (Statement stmt : res.listProperties(prop).toList()) {
if (stmt.getObject().isURIResource()) {
RoleLevel roleFromModel = RoleLevel.getRoleByUri(stmt
.getObject().as(Resource.class).getURI());
if (roleFromModel.compareTo(level) > 0) {
level = roleFromModel;
}
}
}
return level;
}
/**
* convenience method for use with functional object properties
*/

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.RDFS;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
@ -1137,7 +1138,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
qexec.close();
}
FullPropertyKey key = new FullPropertyKey(op);
FullPropertyKey key = new FullPropertyKey((RoleRestrictedProperty)op);
String customListViewConfigFileName = customListViewConfigFileMap.get(key);
if (customListViewConfigFileName == null) {
log.debug("no list view found for " + key);

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
*
* Because subclass/superclass is only a partial ordering, this breaks the
* contract for Comparator, and throws an IllegalArgumentException under Java 8.
* In particular, for classes sub, super and other, we have sub=other, sub<super,
* which should imply other<super, but that is not true.
*
* As far as I can determine, this sort is never relied on anyway, so there
* should be no impact in removing it. Note that PropertyInstanceDaoJena re-sorts
* thes results before using them, so this sort was irrelevant for any calls
* through that path.
*/
private class VClassHierarchyRanker implements Comparator<VClass> {
private VClassDao vcDao;
public VClassHierarchyRanker(VClassDao vcDao) {
this.vcDao = vcDao;
}
@Override
public int compare(VClass vc1, VClass vc2) {
if (vcDao.isSubClassOf(vc1, vc2)) {
return -1;
} else if (vcDao.isSubClassOf(vc2, vc1)) {
return 1;
} else {
return 0;
}
}
}
// private class VClassHierarchyRanker implements Comparator<VClass> {
// private VClassDao vcDao;
// public VClassHierarchyRanker(VClassDao vcDao) {
// this.vcDao = vcDao;
// }
// @Override
// public int compare(VClass vc1, VClass vc2) {
// if (vcDao.isSubClassOf(vc1, vc2)) {
// return -1;
// } else if (vcDao.isSubClassOf(vc2, vc1)) {
// return 1;
// } else {
// return 0;
// }
// }
// }
//
public List<PropertyInstance> getAllPropInstByVClass(String classURI) {
if (classURI==null || classURI.length()<1) {
@ -708,7 +718,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
return propInsts;
}
Collections.sort(vclasses, new VClassHierarchyRanker(this.getWebappDaoFactory().getVClassDao()));
// Removed: see VIVO-766.
// Collections.sort(vclasses, new VClassHierarchyRanker(this.getWebappDaoFactory().getVClassDao()));
OntModel ontModel = getOntModelSelector().getTBoxModel();

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

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 boolean shutdown = false;
protected Log log = LogFactory.getLog(ContextNodeFields.class);
private RDFService rdfService;
//Subclasses may want to utilize rdfService directly (for example, to execute queries that yielding multiple variables mapped to different fields)
protected RDFService rdfService;
@Override
public void setContextModels(ContextModelAccess models) {

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.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
/**
* Execute SPARQL queries against a model.
@ -95,6 +96,15 @@ public class SparqlQueryRunner {
protected abstract T defaultValue();
protected String ifResourcePresent(QuerySolution solution,
String variableName, String defaultValue) {
RDFNode node = solution.get(variableName);
if (node == null || !node.isURIResource()) {
return defaultValue;
}
return node.asResource().getURI();
}
protected String ifLiteralPresent(QuerySolution solution,
String variableName, String defaultValue) {
Literal literal = solution.getLiteral(variableName);
@ -126,5 +136,36 @@ public class SparqlQueryRunner {
}
}
public static String bindValues(String rawString, VariableValue... values) {
String queryString = rawString;
for (VariableValue value: values) {
queryString = value.bind(queryString);
}
return queryString;
}
public static UriValue uriValue(String name, String uri) {
return new UriValue(name, uri);
}
public interface VariableValue {
String bind(String rawString);
}
private static class UriValue implements VariableValue {
private final String name;
private final String uri;
public UriValue(String name, String uri) {
this.name = name;
this.uri = uri;
}
@Override
public String bind(String rawString) {
return rawString.replaceAll("\\?" + name + "\\b", "<" + uri + ">");
}
}
}

View file

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

View file

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

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.PropertyGroup;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
@ -42,7 +42,6 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
*/
public class GroupedPropertyList extends BaseTemplateModel {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(GroupedPropertyList.class);
private static final int MAX_GROUP_DISPLAY_RANK = 99;
@ -247,16 +246,9 @@ public class GroupedPropertyList extends BaseTemplateModel {
}
boolean addToList = true;
for(ObjectProperty op : populatedObjectPropertyList) {
RedundancyReason reason = redundant(op, piOp);
if(reason != null) {
addToList = false;
if (reason == RedundancyReason.LABEL_AND_URI_MATCH
&& moreRestrictiveRange(piOp, op, wadf)) {
op.setRangeVClassURI(piOp.getRangeVClassURI());
op.setRangeVClass(piOp.getRangeVClass());
}
break;
}
if (redundant(op, piOp)) {
addToList = false;
}
}
if(addToList) {
propertyList.add(piOp);
@ -281,67 +273,8 @@ public class GroupedPropertyList extends BaseTemplateModel {
return propertyList;
}
private enum RedundancyReason {
LABEL_AND_URI_MATCH, LABEL_URI_DOMAIN_AND_RANGE_MATCH
}
private boolean moreRestrictiveRange(ObjectProperty piOp, ObjectProperty op,
WebappDaoFactory wadf) {
if(piOp.getRangeVClassURI() == null) {
return false;
} else if (op.getRangeVClassURI() == null) {
return (piOp.getRangeVClassURI() != null);
} else {
//Check and see if the range vclass exists for the possible piOp and populated op properties,
//because for populated properties, if the range class is a union,
//blank nodes will be broken and the code should instead use the existing or piOp range class uri
VClass piOpRangeClass = wadf.getVClassDao().getVClassByURI(piOp.getRangeVClassURI());
VClass opRangeClass = wadf.getVClassDao().getVClassByURI(op.getRangeVClassURI());
//if the possible range class exists but the populated one does not, then return true to allow the possible
//class to be utilized
if(piOpRangeClass != null && opRangeClass == null) return true;
return (wadf.getVClassDao().isSubClassOf(
piOp.getRangeVClassURI(), op.getRangeVClassURI()));
}
}
private RedundancyReason redundant(ObjectProperty op, ObjectProperty op2) {
if (op2.getURI() == null) {
return null;
}
boolean uriMatches = (op.getURI() != null
&& op.getURI().equals(op2.getURI()));
boolean domainMatches = false;
boolean rangeMatches = false;
boolean labelMatches = false;
if(op.getDomainPublic() == null) {
if(op2.getDomainPublic() == null) {
labelMatches = true;
}
} else if (op.getDomainPublic().equals(op2.getDomainPublic())) {
labelMatches = true;
}
if(uriMatches && labelMatches) {
return RedundancyReason.LABEL_AND_URI_MATCH;
}
if(op.getDomainVClassURI() == null) {
if(op2.getDomainVClassURI() == null) {
domainMatches = true;
}
} else if (op.getDomainVClassURI().equals(op2.getDomainVClassURI())) {
domainMatches = true;
}
if(op.getRangeVClassURI() == null) {
if (op2.getRangeVClassURI() == null) {
rangeMatches = true;
}
} else if (op.getRangeVClassURI().equals(op2.getRangeVClassURI())) {
rangeMatches = true;
}
if (uriMatches && domainMatches && rangeMatches) {
return RedundancyReason.LABEL_URI_DOMAIN_AND_RANGE_MATCH;
}
return null;
private boolean redundant(ObjectProperty op, ObjectProperty op2) {
return new FullPropertyKey((Property)op).equals(new FullPropertyKey((Property)op2));
}
private void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri,

View file

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

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