VIVO-692 Restrict LOD by Publish level, not by Display level

Create a new annotation for properties and classes, HiddenFromPublishBelowRoleLevelAnnot.
Provide the means to initialize these annotations, edit them, and display them in the verbose property display.
Create a Permission and some requested actions so the policies can decide which statements must be filtered out, based on the user's role.
Add unit tests and improve acceptance tests
This commit is contained in:
j2blake 2014-03-10 17:42:05 -04:00
parent 95538e4c8a
commit fdeee35bb4
55 changed files with 1977 additions and 251 deletions

View file

@ -35,7 +35,6 @@ log4j.rootLogger=INFO, AllAppender
# These classes are too chatty to display INFO messages.
log4j.logger.edu.cornell.mannlib.vitro.webapp.startup.StartupStatus=WARN
log4j.logger.edu.cornell.mannlib.vitro.webapp.controller.freemarker.BrowseController=WARN
log4j.logger.edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener=WARN
log4j.logger.edu.cornell.mannlib.vitro.webapp.dao.jena.RDBGraphGenerator=WARN
log4j.logger.edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase=DEBUG

View file

@ -5,6 +5,7 @@
@prefix simplePermission: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#> .
@prefix displayByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.DisplayByRolePermission#> .
@prefix editByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.EditByRolePermission#> .
@prefix publishByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.PublishByRolePermission#> .
auth:ADMIN
a auth:PermissionSet ;
@ -65,6 +66,7 @@ auth:ADMIN
# role-based permissions for ADMIN
auth:hasPermission displayByRole:Admin ;
auth:hasPermission editByRole:Admin ;
auth:hasPermission publishByRole:Admin ;
.
auth:CURATOR
@ -104,6 +106,7 @@ auth:CURATOR
# role-based permissions for CURATOR
auth:hasPermission displayByRole:Curator ;
auth:hasPermission editByRole:Curator ;
auth:hasPermission publishByRole:Curator ;
.
auth:EDITOR
@ -134,6 +137,7 @@ auth:EDITOR
# role-based permissions for EDITOR
auth:hasPermission displayByRole:Editor ;
auth:hasPermission editByRole:Editor ;
auth:hasPermission publishByRole:Editor ;
.
auth:SELF_EDITOR
@ -158,6 +162,7 @@ auth:SELF_EDITOR
# For role-based display and editing, SelfEditor is like Public.
# SelfEditor uses its special permissions to edit/display its own values.
auth:hasPermission displayByRole:Public ;
auth:hasPermission publishByRole:Public ;
.
auth:PUBLIC
@ -171,4 +176,5 @@ auth:PUBLIC
# role-based permissions for PUBLIC
auth:hasPermission displayByRole:Public ;
auth:hasPermission publishByRole:Public ;
.

View file

@ -109,6 +109,9 @@ xmlns:vitro="&vitro;"
<rdf:Description rdf:about="http://vitro.mannlib.cornell.edu/ns/vitro/0.7#hiddenFromDisplayBelowRoleLevelAnnot">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#AnnotationProperty"/>
</rdf:Description>
<rdf:Description rdf:about="http://vitro.mannlib.cornell.edu/ns/vitro/0.7#hiddenFromPublishBelowRoleLevelAnnot">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#AnnotationProperty"/>
</rdf:Description>
<rdf:Description rdf:about="http://vitro.mannlib.cornell.edu/ns/vitro/0.7#forceStubDeletionAnnot">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#AnnotationProperty"/>
</rdf:Description>

View file

@ -15,7 +15,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObje
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;

View file

@ -134,6 +134,7 @@ public class PermissionRegistry {
permissions.addAll(SimplePermission.getAllInstances());
permissions.addAll(createDisplayByRolePermissions(ctx));
permissions.addAll(createEditByRolePermissions(ctx));
permissions.addAll(createPublishByRolePermissions(ctx));
PermissionRegistry.createRegistry(ctx, permissions);
@ -185,5 +186,24 @@ public class PermissionRegistry {
public void contextDestroyed(ServletContextEvent sce) {
sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);
}
/**
* There is no PublishByRolePermission for self-editors. They get the
* same rights as PUBLIC. Other permissions give them their self-editing
* privileges.
*/
private Collection<Permission> createPublishByRolePermissions(
ServletContext ctx) {
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));
return list;
}
}
}

View file

@ -0,0 +1,133 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
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.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishObjectProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/**
* Is the user authorized to publish properties that are marked as restricted to
* a certain "Role Level"?
*/
public class PublishByRolePermission extends Permission {
private static final Log log = LogFactory
.getLog(PublishByRolePermission.class);
public static final String NAMESPACE = "java:"
+ PublishByRolePermission.class.getName() + "#";
private final String roleName;
private final RoleLevel roleLevel;
private final ServletContext ctx;
public PublishByRolePermission(String roleName, RoleLevel roleLevel,
ServletContext ctx) {
super(NAMESPACE + roleName);
if (roleName == null) {
throw new NullPointerException("role may not be null.");
}
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
public boolean isAuthorized(RequestedAction whatToAuth) {
boolean result;
if (whatToAuth instanceof PublishDataProperty) {
result = isAuthorized((PublishDataProperty) whatToAuth);
} else if (whatToAuth instanceof PublishObjectProperty) {
result = isAuthorized((PublishObjectProperty) whatToAuth);
} else if (whatToAuth instanceof PublishDataPropertyStatement) {
result = isAuthorized((PublishDataPropertyStatement) whatToAuth);
} else if (whatToAuth instanceof PublishObjectPropertyStatement) {
result = isAuthorized((PublishObjectPropertyStatement) whatToAuth);
} else {
result = false;
}
if (result) {
log.debug(this + " authorizes " + whatToAuth);
} else {
log.debug(this + " does not authorize " + whatToAuth);
}
return result;
}
/**
* The user may publish this data property if they are allowed to publish
* its predicate.
*/
private boolean isAuthorized(PublishDataProperty action) {
String predicateUri = action.getDataProperty().getURI();
return canPublishPredicate(new Property(predicateUri));
}
/**
* The user may publish this object property if they are allowed to publish
* its predicate.
*/
private boolean isAuthorized(PublishObjectProperty action) {
return canPublishPredicate(action.getObjectProperty());
}
/**
* The user may publish this data property if they are allowed to publish
* its subject and its predicate.
*/
private boolean isAuthorized(PublishDataPropertyStatement action) {
String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri();
return canPublishResource(subjectUri)
&& canPublishPredicate(new Property(predicateUri));
}
/**
* The user may publish this data property if they are allowed to publish
* its subject, its predicate, and its object.
*/
private boolean isAuthorized(PublishObjectPropertyStatement action) {
String subjectUri = action.getSubjectUri();
Property predicate = action.getPredicate();
String objectUri = action.getObjectUri();
return canPublishResource(subjectUri) && canPublishPredicate(predicate)
&& canPublishResource(objectUri);
}
private boolean canPublishResource(String resourceUri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canPublishResource(
resourceUri, this.roleLevel);
}
private boolean canPublishPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx)
.canPublishPredicate(predicate, this.roleLevel);
}
@Override
public String toString() {
return "PublishByRolePermission['" + roleName + "']";
}
}

View file

@ -48,7 +48,6 @@ public class ServletPolicyList {
PolicyList policies = getPolicyList(sc);
if (!policies.contains(policy)) {
policies.add(policy);
log.info("Added policy: " + policy.getClass().getSimpleName());
log.debug("Added policy: " + policy.toString());
} else {
log.warn("Ignored attempt to add redundant policy.");
@ -67,7 +66,6 @@ public class ServletPolicyList {
PolicyList policies = getPolicyList(sc);
if (!policies.contains(policy)) {
policies.add(0, policy);
log.info("Added policy at front: " + policy.getClass().getSimpleName());
log.debug("Added policy at front: " + policy.toString());
} else {
log.warn("Ignored attempt to add redundant policy.");

View file

@ -37,8 +37,9 @@ public class PropertyRestrictionListener implements ChangeListener {
@Override
public void doDeleted(Object oldObj, EditProcessObject epo) {
Property p = (Property) oldObj;
if (eitherRoleChanged(p.getHiddenFromDisplayBelowRoleLevel(),
p.getProhibitedFromUpdateBelowRoleLevel(), null, null)) {
if (anyRoleChanged(p.getHiddenFromDisplayBelowRoleLevel(),
p.getProhibitedFromUpdateBelowRoleLevel(),
p.getHiddenFromPublishBelowRoleLevel(), null, null, null)) {
log.debug("rebuilding the PropertyRestrictionPolicyHelper after deletion");
createAndSetBean();
}
@ -50,9 +51,10 @@ public class PropertyRestrictionListener implements ChangeListener {
@Override
public void doInserted(Object newObj, EditProcessObject epo) {
Property p = (Property) newObj;
if (eitherRoleChanged(null, null,
if (anyRoleChanged(null, null, null,
p.getHiddenFromDisplayBelowRoleLevel(),
p.getProhibitedFromUpdateBelowRoleLevel())) {
p.getProhibitedFromUpdateBelowRoleLevel(),
p.getHiddenFromPublishBelowRoleLevel())) {
log.debug("rebuilding the PropertyRestrictionPolicyHelper after insertion");
createAndSetBean();
}
@ -65,20 +67,24 @@ public class PropertyRestrictionListener implements ChangeListener {
public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) {
Property oldP = (Property) oldObj;
Property newP = (Property) newObj;
if (eitherRoleChanged(oldP.getHiddenFromDisplayBelowRoleLevel(),
if (anyRoleChanged(oldP.getHiddenFromDisplayBelowRoleLevel(),
oldP.getProhibitedFromUpdateBelowRoleLevel(),
oldP.getHiddenFromPublishBelowRoleLevel(),
newP.getHiddenFromDisplayBelowRoleLevel(),
newP.getProhibitedFromUpdateBelowRoleLevel())) {
newP.getProhibitedFromUpdateBelowRoleLevel(),
newP.getHiddenFromPublishBelowRoleLevel())) {
log.debug("rebuilding the PropertyRestrictionPolicyHelper after update");
createAndSetBean();
}
}
private boolean eitherRoleChanged(RoleLevel oldDisplayRole,
RoleLevel oldUpdateRole, RoleLevel newDisplayRole,
RoleLevel newUpdateRole) {
private boolean anyRoleChanged(RoleLevel oldDisplayRole,
RoleLevel oldUpdateRole, RoleLevel oldPublishRole,
RoleLevel newDisplayRole, RoleLevel newUpdateRole,
RoleLevel newPublishRole) {
return (!isTheSame(oldDisplayRole, newDisplayRole))
|| (!isTheSame(oldUpdateRole, newUpdateRole));
|| (!isTheSame(oldUpdateRole, newUpdateRole))
|| (!isTheSame(oldPublishRole, newPublishRole));
}
private boolean isTheSame(RoleLevel oldRole, RoleLevel newRole) {

View file

@ -19,12 +19,6 @@ 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.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
@ -46,10 +40,10 @@ import edu.cornell.mannlib.vitro.webapp.utils.ApplicationConfigurationOntologyUt
/**
* Assists the role-based policies in determining whether a property or resource
* may be displayed or modified.
* 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 and modifying restricted properties.
* for displaying, modifying, or publishing restricted properties.
*
* Create this bean after the Jena model is in place in the context.
*
@ -119,6 +113,8 @@ public class PropertyRestrictionPolicyHelper {
new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
Map<Pair<String, Pair<String,String>>, RoleLevel> modifyThresholdMap =
new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
Map<Pair<String, Pair<String,String>>, RoleLevel> publishThresholdMap =
new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
OntModel union = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM,
ModelFactory.createUnion(displayModel, model));
@ -126,15 +122,14 @@ public class PropertyRestrictionPolicyHelper {
populateThresholdMap(union, displayThresholdMap,
VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT);
populateThresholdMap(
union,
modifyThresholdMap,
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, displayModel);
displayThresholdMap, modifyThresholdMap, publishThresholdMap);
return bean;
}
@ -209,6 +204,9 @@ public class PropertyRestrictionPolicyHelper {
} 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) {
log.debug("Putting D:" + faux.getDomainVClassURI() + " P:" + faux.getURI() + " R:" + faux.getRangeVClassURI() + " ==> L:" + role);
@ -251,6 +249,12 @@ public class PropertyRestrictionPolicyHelper {
*/
private final Map<Pair<String, Pair<String,String>>, 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<Pair<String, Pair<String,String>>, RoleLevel> publishThresholdMap;
/**
* Store unmodifiable versions of the inputs.
@ -263,19 +267,23 @@ public class PropertyRestrictionPolicyHelper {
Collection<String> modifyExceptionsAllowedUris,
Map<Pair<String, Pair<String,String>>, RoleLevel> displayThresholdMap,
Map<Pair<String, Pair<String,String>>, RoleLevel> modifyThresholdMap,
Model displayModel) {
Map<Pair<String, Pair<String,String>>, RoleLevel> publishThresholdMap) {
this.modifyProhibitedNamespaces = unmodifiable(modifyProhibitedNamespaces);
this.modifyExceptionsAllowedUris = unmodifiable(modifyExceptionsAllowedUris);
this.displayThresholdMap = displayThresholdMap;
this.modifyThresholdMap = modifyThresholdMap;
// this.displayThresholdMap = unmodifiable(displayThresholdMap);
// this.modifyThresholdMap = unmodifiable(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);
}
}
@ -341,6 +349,22 @@ public class PropertyRestrictionPolicyHelper {
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.
@ -408,6 +432,33 @@ public class PropertyRestrictionPolicyHelper {
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;

View file

@ -60,6 +60,10 @@ public abstract class AbstractDataPropertyStatementAction extends
return new String[] {subjectUri};
}
public String dataValue() {
return dataValue;
}
@Override
public String toString() {
return getClass().getSimpleName() + ": <" + subjectUri + "> <"

View file

@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
@ -17,23 +18,31 @@ public abstract class AbstractObjectPropertyStatementAction extends
private final Property predicate;
private final String objectUri;
public AbstractObjectPropertyStatementAction(OntModel ontModel, String subjectUri,
Property predicate, String objectUri) {
public AbstractObjectPropertyStatementAction(OntModel ontModel,
String subjectUri, Property predicate, String objectUri) {
super(ontModel);
this.subjectUri = subjectUri;
this.predicate = predicate;
this.objectUri = objectUri;
}
public AbstractObjectPropertyStatementAction(OntModel ontModel, ObjectPropertyStatement ops) {
public AbstractObjectPropertyStatementAction(OntModel ontModel,
ObjectPropertyStatement ops) {
super(ontModel);
this.subjectUri = (ops.getSubject() == null) ? ops.getSubjectURI()
: ops.getSubject().getURI();
this.predicate = (ops.getProperty());
this.predicate = (ops.getProperty() == null) ? createProperty(ops
.getPropertyURI()) : ops.getProperty();
this.objectUri = (ops.getObject() == null) ? ops.getObjectURI() : ops
.getObject().getURI();
}
private ObjectProperty createProperty(String propertyURI) {
ObjectProperty op = new ObjectProperty();
op.setURI(propertyURI);
return op;
}
public String getSubjectUri() {
return subjectUri;
}
@ -42,8 +51,9 @@ public abstract class AbstractObjectPropertyStatementAction extends
return objectUri;
}
@Override
public Property getPredicate() {
return predicate;
return predicate;
}
@Override
@ -53,7 +63,7 @@ public abstract class AbstractObjectPropertyStatementAction extends
@Override
public String[] getResourceUris() {
return new String[] {subjectUri, objectUri};
return new String[] { subjectUri, objectUri };
}
@Override

View file

@ -0,0 +1,24 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
/** Should we allow the user to publish this DataProperty in Linked Open Data? */
public class PublishDataProperty extends RequestedAction {
private final DataProperty dataProperty;
public PublishDataProperty(DataProperty dataProperty) {
this.dataProperty = dataProperty;
}
public DataProperty getDataProperty() {
return dataProperty;
}
@Override
public String toString() {
return "PublishDataProperty[" + dataProperty + "]";
}
}

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.auth.requestedAction.publish;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
/**
* Should we publish this DataPropertyStatement in a Linked Open Data request
* from the current user?
*/
public class PublishDataPropertyStatement extends
AbstractDataPropertyStatementAction {
public PublishDataPropertyStatement(OntModel ontModel, String subjectUri,
String predicateUri, String dataValue) {
super(ontModel, subjectUri, predicateUri, dataValue);
}
public PublishDataPropertyStatement(OntModel ontModel,
DataPropertyStatement dps) {
super(ontModel, dps);
}
}

View file

@ -0,0 +1,24 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
/** Should we allow the user to publish this ObjectProperty in Linked Open Data? */
public class PublishObjectProperty extends RequestedAction {
private final ObjectProperty objectProperty;
public PublishObjectProperty(ObjectProperty objectProperty) {
this.objectProperty = objectProperty;
}
public ObjectProperty getObjectProperty() {
return objectProperty;
}
@Override
public String toString() {
return "PublishObjectProperty[" + objectProperty.getLocalName() + "]";
}
}

View file

@ -0,0 +1,28 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/**
* Should we publish this ObjectPropertyStatement in a Linked Open Data request
* from the current user?
*/
public class PublishObjectPropertyStatement extends
AbstractObjectPropertyStatementAction {
public PublishObjectPropertyStatement(OntModel ontModel, String subjectUri,
Property keywordPred, String objectUri) {
super(ontModel, subjectUri, keywordPred, objectUri);
}
public PublishObjectPropertyStatement(OntModel ontModel,
ObjectPropertyStatement ops) {
super(ontModel, ops);
}
}

View file

@ -25,53 +25,70 @@ public class BaseResourceBean implements ResourceBean {
protected String localNameWithPrefix = null;
protected String pickListName = null;
// these will be phased in and used in the filters Brian C. has been setting up,
// with hiddenFromDisplay to control the level at which any class, individual, object property, or data property is displayed
// and prohibitedFromEditing to control when a control for editing is made available
protected RoleLevel hiddenFromDisplayBelowRoleLevel = null;
//protected RoleLevel prohibitedFromCreateBelowRoleLevel = null;
protected RoleLevel prohibitedFromUpdateBelowRoleLevel = null;
//protected RoleLevel prohibitedFromDeleteBelowRoleLevel = null;
protected RoleLevel hiddenFromPublishBelowRoleLevel = null;
public enum RoleLevel { PUBLIC("http://vitro.mannlib.cornell.edu/ns/vitro/role#public","public","public"),
SELF("http://vitro.mannlib.cornell.edu/ns/vitro/role#selfEditor","self-authenticated","self"),
EDITOR("http://vitro.mannlib.cornell.edu/ns/vitro/role#editor","editor, curator, site administrator","editor"),
CURATOR("http://vitro.mannlib.cornell.edu/ns/vitro/role#curator","curator, site administrator","curator"),
DB_ADMIN("http://vitro.mannlib.cornell.edu/ns/vitro/role#dbAdmin","site administrator","siteAdmin"),
NOBODY("http://vitro.mannlib.cornell.edu/ns/vitro/role#nobody","root user","root");
public enum RoleLevel {
PUBLIC("http://vitro.mannlib.cornell.edu/ns/vitro/role#public",
"all users, including public", "all users who can log in",
"public"),
private final String uri;
private final String label;
private final String shorthand;
SELF("http://vitro.mannlib.cornell.edu/ns/vitro/role#selfEditor",
"self-editor and above", "self-editor and above", "self"),
RoleLevel(String uriStr,String labelStr, String shortStr) {
this.uri = uriStr;
this.label = labelStr;
this.shorthand = shortStr;
}
EDITOR("http://vitro.mannlib.cornell.edu/ns/vitro/role#editor",
"editor and above", "editor and above", "editor"),
public String getURI() {
return uri;
}
CURATOR("http://vitro.mannlib.cornell.edu/ns/vitro/role#curator",
"curator and above", "curator and above", "curator"),
public String getLabel() {
return label;
}
DB_ADMIN("http://vitro.mannlib.cornell.edu/ns/vitro/role#dbAdmin",
"site admin and root user", "site admin and root user",
"siteAdmin"),
public String getShorthand() {
return shorthand;
}
NOBODY("http://vitro.mannlib.cornell.edu/ns/vitro/role#nobody",
"root user", "root user", "root");
public static RoleLevel getRoleByUri(String uri2) {
if( uri2 == null )
return RoleLevel.values()[0];
private final String uri;
private final String displayLabel;
private final String updateLabel;
private final String shorthand;
for( RoleLevel role : RoleLevel.values() ){
if( role.uri.equals( uri2 ) )
return role;
}
return RoleLevel.values()[0];
}
private RoleLevel(String uri, String displayLabel, String updateLabel,
String shorthand) {
this.uri = uri;
this.displayLabel = displayLabel;
this.updateLabel = updateLabel;
this.shorthand = shorthand;
}
public String getURI() {
return uri;
}
public String getDisplayLabel() {
return displayLabel;
}
public String getUpdateLabel() {
return updateLabel;
}
public String getShorthand() {
return shorthand;
}
public static RoleLevel getRoleByUri(String uri2) {
if (uri2 == null)
return RoleLevel.values()[0];
for (RoleLevel role : RoleLevel.values()) {
if (role.uri.equals(uri2))
return role;
}
return RoleLevel.values()[0];
}
public static RoleLevel getRoleFromLoginStatus(HttpServletRequest req) {
UserAccount u = LoginStatusBean.getCurrentUser(req);
@ -81,7 +98,7 @@ public class BaseResourceBean implements ResourceBean {
Set<String> roles = u.getPermissionSetUris();
if (roles.contains(PermissionSets.URI_DBA)) {
return DB_ADMIN;
return DB_ADMIN;
} else if (roles.contains(PermissionSets.URI_CURATOR)) {
return CURATOR;
} else if (roles.contains(PermissionSets.URI_EDITOR)) {
@ -93,16 +110,19 @@ public class BaseResourceBean implements ResourceBean {
return SELF;
}
}
}
}
public boolean isAnonymous() {
@Override
public boolean isAnonymous() {
return (this.URI==null || VitroVocabulary.PSEUDO_BNODE_NS.equals(this.getNamespace()));
}
public String getURI() {
@Override
public String getURI() {
return URI;
}
public void setURI(String URI) {
@Override
public void setURI(String URI) {
if( this.localName != null || this.namespace != null)
buildLocalAndNS(URI);
else
@ -122,29 +142,34 @@ public class BaseResourceBean implements ResourceBean {
}
}
public String getNamespace() {
@Override
public String getNamespace() {
if( namespace == null && this.URI != null)
buildLocalAndNS(this.URI);
return namespace;
}
public void setNamespace(String namespace) {
@Override
public void setNamespace(String namespace) {
this.namespace = namespace;
if (namespace != null && localName != null ) {
this.URI = namespace + localName;
}
}
public String getLabel() {
@Override
public String getLabel() {
return getLocalName();
}
public String getLocalName() {
@Override
public String getLocalName() {
if( localName == null && this.URI != null)
buildLocalAndNS(this.URI);
return localName;
}
public void setLocalName(String localName) {
@Override
public void setLocalName(String localName) {
this.localName = localName;
if (namespace != null && localName != null) {
this.URI = namespace + localName;
@ -160,7 +185,8 @@ public class BaseResourceBean implements ResourceBean {
this.localNameWithPrefix = prefixedLocalName;
}
public String getPickListName() {
@Override
public String getPickListName() {
return pickListName==null ? getLocalName()==null ?
(URI==null ? "(no name)" : URI ): getLocalName() : pickListName;
}
@ -168,57 +194,51 @@ public class BaseResourceBean implements ResourceBean {
this.pickListName = pickListName;
}
public RoleLevel getHiddenFromDisplayBelowRoleLevel() {
@Override
public RoleLevel getHiddenFromDisplayBelowRoleLevel() {
return hiddenFromDisplayBelowRoleLevel;
}
public void setHiddenFromDisplayBelowRoleLevel(RoleLevel eR) {
@Override
public void setHiddenFromDisplayBelowRoleLevel(RoleLevel eR) {
hiddenFromDisplayBelowRoleLevel = eR;
}
public void setHiddenFromDisplayBelowRoleLevelUsingRoleUri(String roleUri) {
@Override
public void setHiddenFromDisplayBelowRoleLevelUsingRoleUri(String roleUri) {
hiddenFromDisplayBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri);
}
/*
public RoleLevel getProhibitedFromCreateBelowRoleLevel() {
return prohibitedFromCreateBelowRoleLevel;
}
public void setProhibitedFromCreateBelowRoleLevel(RoleLevel eR) {
prohibitedFromCreateBelowRoleLevel = eR;
}
public void setProhibitedFromCreateBelowRoleLevelUsingRoleUri(String roleUri) {
prohibitedFromCreateBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri);
}
*/
public RoleLevel getProhibitedFromUpdateBelowRoleLevel() {
@Override
public RoleLevel getProhibitedFromUpdateBelowRoleLevel() {
return prohibitedFromUpdateBelowRoleLevel;
}
public void setProhibitedFromUpdateBelowRoleLevel(RoleLevel eR) {
@Override
public void setProhibitedFromUpdateBelowRoleLevel(RoleLevel eR) {
prohibitedFromUpdateBelowRoleLevel = eR;
}
public void setProhibitedFromUpdateBelowRoleLevelUsingRoleUri(String roleUri) {
@Override
public void setProhibitedFromUpdateBelowRoleLevelUsingRoleUri(String roleUri) {
prohibitedFromUpdateBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri);
}
/*
public RoleLevel getProhibitedFromDeleteBelowRoleLevel() {
return prohibitedFromDeleteBelowRoleLevel;
@Override
public RoleLevel getHiddenFromPublishBelowRoleLevel() {
return hiddenFromPublishBelowRoleLevel;
}
@Override
public void setHiddenFromPublishBelowRoleLevel(RoleLevel eR) {
hiddenFromPublishBelowRoleLevel = eR;
}
public void setProhibitedFromDeleteBelowRoleLevel(RoleLevel eR) {
prohibitedFromDeleteBelowRoleLevel = eR;
@Override
public void setHiddenFromPublishBelowRoleLevelUsingRoleUri(String roleUri) {
hiddenFromPublishBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri);
}
public void setProhibitedFromDeleteBelowRoleLevelUsingRoleUri(String roleUri) {
prohibitedFromDeleteBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri);
}
*/
@Override
public boolean equals(Object obj) {
if(obj == null )

View file

@ -633,6 +633,7 @@ public class ObjectProperty extends Property implements Comparable<ObjectPropert
clone.setFunctional(this.getFunctional());
clone.setGroupURI(this.getGroupURI());
clone.setHiddenFromDisplayBelowRoleLevel(this.getHiddenFromDisplayBelowRoleLevel());
clone.setHiddenFromPublishBelowRoleLevel(this.getHiddenFromPublishBelowRoleLevel());
clone.setInverseFunctional(this.getInverseFunctional());
clone.setLabel(this.getLabel());
clone.setLocalName(this.getLocalName());

View file

@ -39,6 +39,12 @@ public interface ResourceBean {
public void setProhibitedFromUpdateBelowRoleLevelUsingRoleUri(String roleUri) ;
public RoleLevel getHiddenFromPublishBelowRoleLevel() ;
public void setHiddenFromPublishBelowRoleLevel(RoleLevel eR) ;
public void setHiddenFromPublishBelowRoleLevelUsingRoleUri(String roleUri) ;
public String getPickListName();
}

View file

@ -41,7 +41,7 @@ public class DatapropEditController extends BaseEditController {
VitroRequest vreq = new VitroRequest(request);
final int NUM_COLS=17;
final int NUM_COLS=18;
String datapropURI = request.getParameter("uri");
@ -73,6 +73,7 @@ public class DatapropEditController extends BaseEditController {
results.add("display limit"); // column 15
results.add("custom entry form"); // column 16
results.add("URI"); // column 17
results.add("publish level"); // column 18
RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP);
@ -135,12 +136,16 @@ public class DatapropEditController extends BaseEditController {
String descriptionStr = (dp.getDescription() == null) ? "" : dp.getDescription(); // column 11
results.add(descriptionStr);
results.add(dp.getHiddenFromDisplayBelowRoleLevel() == null ? "(unspecified)" : dp.getHiddenFromDisplayBelowRoleLevel().getLabel()); // column 12
results.add(dp.getProhibitedFromUpdateBelowRoleLevel() == null ? "(unspecified)" : dp.getProhibitedFromUpdateBelowRoleLevel().getLabel()); // column 13
results.add(dp.getHiddenFromDisplayBelowRoleLevel() == null ? "(unspecified)"
: dp.getHiddenFromDisplayBelowRoleLevel().getDisplayLabel()); // column 12
results.add(dp.getProhibitedFromUpdateBelowRoleLevel() == null ? "(unspecified)"
: dp.getProhibitedFromUpdateBelowRoleLevel().getUpdateLabel()); // column 13
results.add(String.valueOf(dp.getDisplayTier())); // column 14
results.add(String.valueOf(dp.getDisplayLimit())); // column 15
results.add(dp.getCustomEntryForm() == null ? "(unspecified)" : dp.getCustomEntryForm()); // column 16
results.add(dp.getURI() == null ? "" : dp.getURI()); // column 17
results.add(dp.getHiddenFromPublishBelowRoleLevel() == null ? "(unspecified)"
: dp.getHiddenFromPublishBelowRoleLevel().getDisplayLabel()); // column 18
request.setAttribute("results",results);
request.setAttribute("columncount",NUM_COLS);
request.setAttribute("suppressquery","true");

View file

@ -166,6 +166,7 @@ public class DatapropRetryController extends BaseEditController {
optionMap.put("HiddenFromDisplayBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getDisplayOptionsList(objectForEditing));
optionMap.put("ProhibitedFromUpdateBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getUpdateOptionsList(objectForEditing));
optionMap.put("HiddenFromPublishBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getPublishOptionsList(objectForEditing));
foo.setOptionLists(optionMap);

View file

@ -81,6 +81,8 @@ public class EntityEditController extends BaseEditController {
colCount++;
results.add("URI");
colCount++;
results.add("publish level");
colCount++;
String rName = null;
if (ent.getName() != null && ent.getName().length() > 0) {
@ -116,12 +118,16 @@ public class EntityEditController extends BaseEditController {
}
results.add(classStr);
results.add(ent.getHiddenFromDisplayBelowRoleLevel() == null ? "unspecified" : ent.getHiddenFromDisplayBelowRoleLevel().getLabel());
results.add(ent.getProhibitedFromUpdateBelowRoleLevel() == null ? "unspecified" : ent.getProhibitedFromUpdateBelowRoleLevel().getLabel());
results.add(ent.getHiddenFromDisplayBelowRoleLevel() == null ? "unspecified"
: ent.getHiddenFromDisplayBelowRoleLevel().getDisplayLabel());
results.add(ent.getProhibitedFromUpdateBelowRoleLevel() == null ? "unspecified"
: ent.getProhibitedFromUpdateBelowRoleLevel().getUpdateLabel());
String rModTime = (ent.getModTime()==null) ? "" : publicDateFormat.format(ent.getModTime());
results.add(rModTime);
results.add( (ent.getURI() == null) ? "[anonymous individual]" : ent.getURI() );
results.add(ent.getHiddenFromPublishBelowRoleLevel() == null ? "unspecified"
: ent.getHiddenFromPublishBelowRoleLevel().getDisplayLabel());
request.setAttribute("results",results);
request.setAttribute("columncount", colCount);
request.setAttribute("suppressquery","true");

View file

@ -170,6 +170,7 @@ public class EntityRetryController extends BaseEditController {
hash.put("HiddenFromDisplayBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getDisplayOptionsList(individualForEditing));
hash.put("ProhibitedFromUpdateBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getUpdateOptionsList(individualForEditing));
hash.put("HiddenFromPublishBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getPublishOptionsList(individualForEditing));
FormObject foo = new FormObject();
foo.setOptionLists(hash);

View file

@ -6,7 +6,6 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.servlet.RequestDispatcher;
@ -21,17 +20,14 @@ import edu.cornell.mannlib.vedit.beans.FormObject;
import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
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.dao.ModelAccess;
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.dao.DataPropertyDao;
public class PropertyEditController extends BaseEditController {
@ -43,7 +39,7 @@ public class PropertyEditController extends BaseEditController {
return;
}
final int NUM_COLS=24;
final int NUM_COLS=25;
VitroRequest vreq = new VitroRequest(request);
@ -81,6 +77,7 @@ public class PropertyEditController extends BaseEditController {
results.add("offer create new"); // column 22
results.add("sort direction"); // column 23
results.add("URI"); // column 24
results.add("publish level"); // column 25
results.add(p.getPickListName()); // column 1
@ -169,8 +166,10 @@ public class PropertyEditController extends BaseEditController {
String descriptionStr = (p.getDescription() == null) ? "" : p.getDescription();
results.add(descriptionStr); // column 15
results.add(p.getHiddenFromDisplayBelowRoleLevel() == null ? "(unspecified)" : p.getHiddenFromDisplayBelowRoleLevel().getLabel()); // column 16
results.add(p.getProhibitedFromUpdateBelowRoleLevel() == null ? "(unspecified)" : p.getProhibitedFromUpdateBelowRoleLevel().getLabel()); // column 17
results.add(p.getHiddenFromDisplayBelowRoleLevel() == null ? "(unspecified)"
: p.getHiddenFromDisplayBelowRoleLevel().getDisplayLabel()); // column 16
results.add(p.getProhibitedFromUpdateBelowRoleLevel() == null ? "(unspecified)"
: p.getProhibitedFromUpdateBelowRoleLevel().getUpdateLabel()); // column 17
results.add("property: "+p.getDomainDisplayTier() + ", inverse: "+p.getRangeDisplayTier()); // column 18
@ -183,6 +182,8 @@ public class PropertyEditController extends BaseEditController {
results.add(p.getDomainEntitySortDirection() == null ? "ascending" : p.getDomainEntitySortDirection()); // column 23
results.add(p.getURI()); // column 24
results.add(p.getHiddenFromPublishBelowRoleLevel() == null ? "(unspecified)"
: p.getHiddenFromPublishBelowRoleLevel().getDisplayLabel()); // column 25
request.setAttribute("results",results);
request.setAttribute("columncount",NUM_COLS);
request.setAttribute("suppressquery","true");

View file

@ -151,6 +151,7 @@ public class PropertyRetryController extends BaseEditController {
optionMap.put("HiddenFromDisplayBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getDisplayOptionsList(propertyForEditing));
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));
HashMap<String,Option> hashMap = new HashMap<String,Option>();

View file

@ -33,7 +33,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
public class VclassEditController extends BaseEditController {
private static final Log log = LogFactory.getLog(VclassEditController.class.getName());
private static final int NUM_COLS = 13;
private static final int NUM_COLS = 14;
public void doPost (HttpServletRequest req, HttpServletResponse response) {
if (!isAuthorizedToDisplayPage(req, response, SimplePermission.EDIT_ONTOLOGY.ACTIONS)) {
@ -70,6 +70,7 @@ public class VclassEditController extends BaseEditController {
results.add("display rank"); // 11
results.add("custom entry form"); // 12
results.add("URI"); // 13
results.add("publish level"); // 14
String ontologyName = null;
if (vcl.getNamespace() != null) {
@ -107,8 +108,13 @@ public class VclassEditController extends BaseEditController {
commSb = new StringBuffer("no comments yet");
}
String hiddenFromDisplay = (vcl.getHiddenFromDisplayBelowRoleLevel() == null ? "(unspecified)" : vcl.getHiddenFromDisplayBelowRoleLevel().getLabel());
String ProhibitedFromUpdate = (vcl.getProhibitedFromUpdateBelowRoleLevel() == null ? "(unspecified)" : vcl.getProhibitedFromUpdateBelowRoleLevel().getLabel());
String hiddenFromDisplay = (vcl.getHiddenFromDisplayBelowRoleLevel() == null ? "(unspecified)"
: vcl.getHiddenFromDisplayBelowRoleLevel().getDisplayLabel());
String ProhibitedFromUpdate = (vcl
.getProhibitedFromUpdateBelowRoleLevel() == null ? "(unspecified)"
: vcl.getProhibitedFromUpdateBelowRoleLevel().getUpdateLabel());
String hiddenFromPublish = (vcl.getHiddenFromPublishBelowRoleLevel() == null ? "(unspecified)"
: vcl.getHiddenFromPublishBelowRoleLevel().getDisplayLabel());
String customEntryForm = (vcl.getCustomEntryForm() == null ? "(unspecified)" : vcl.getCustomEntryForm());
@ -130,6 +136,7 @@ public class VclassEditController extends BaseEditController {
results.add(String.valueOf(vcl.getDisplayRank())); // 11
results.add(customEntryForm); // 12
results.add(uri); // 13
results.add(hiddenFromPublish); // 14
request.setAttribute("results", results);
request.setAttribute("columncount", NUM_COLS);
request.setAttribute("suppressquery", "true");

View file

@ -147,6 +147,7 @@ public class VclassRetryController extends BaseEditController {
optionMap.put("HiddenFromDisplayBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getDisplayOptionsList(vclassForEditing));
optionMap.put("ProhibitedFromUpdateBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getUpdateOptionsList(vclassForEditing));
optionMap.put("HiddenFromPublishBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getPublishOptionsList(vclassForEditing));
FormObject foo = new FormObject();
foo.setErrorMap(epo.getErrMsgMap());

View file

@ -23,7 +23,7 @@ public class RoleLevelOptionsSetup {
boolean someLevelSet=false;
Option publicOption = null;
for (BaseResourceBean.RoleLevel level : roles) {
Option option = new Option (level.getURI(),level.getLabel(),false);
Option option = new Option (level.getURI(),level.getDisplayLabel(),false);
if (level==BaseResourceBean.RoleLevel.PUBLIC) {
publicOption = option;
}
@ -50,7 +50,7 @@ public class RoleLevelOptionsSetup {
boolean someLevelSet=false;
Option publicOption = null;
for (BaseResourceBean.RoleLevel level : roles) {
Option option = new Option (level.getURI(),level.getLabel(),false);
Option option = new Option (level.getURI(),level.getUpdateLabel(),false);
if (level==BaseResourceBean.RoleLevel.PUBLIC) {
publicOption = option;
}
@ -68,4 +68,33 @@ public class RoleLevelOptionsSetup {
}
return prohibitedFromUpdateList;
}
public static List<Option> getPublishOptionsList(ResourceBean b) {
List<Option> hiddenFromPublishList = new LinkedList<Option>();
try {
BaseResourceBean.RoleLevel currentLevel = b.getHiddenFromPublishBelowRoleLevel();
BaseResourceBean.RoleLevel roles[] = BaseResourceBean.RoleLevel.values();
boolean someLevelSet=false;
Option publicOption = null;
for (BaseResourceBean.RoleLevel level : roles) {
Option option = new Option (level.getURI(),level.getDisplayLabel(),false);
if (level==BaseResourceBean.RoleLevel.PUBLIC) {
publicOption = option;
}
if (level==currentLevel) {
option.setSelected(true);
someLevelSet=true;
}
hiddenFromPublishList.add(option);
}
if (!someLevelSet) {
publicOption.setSelected(true);
}
} catch (Exception ex) {
log.error("cannot create HiddenFromPublishBelowRoleLevel options");
}
return hiddenFromPublishList;
}
}

View file

@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.controller.individual;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
@ -28,9 +29,9 @@ import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
@ -61,7 +62,7 @@ import edu.cornell.mannlib.vitro.webapp.web.ContentType;
* Otherwise, show all triples, regardless of language.
*
* Filter the result based on the policy, removing any triples that should not
* be displayed to the public (or to the user, if logged in). Also remove any
* be published to the public (or to the user, if logged in). Also remove any
* objects which can only be reached by excluded triples.
*
* ----------------
@ -104,7 +105,6 @@ public class IndividualRdfAssembler {
this.individualUri = individualUri;
this.rdfFormat = rdfFormat;
String[] includes = vreq.getParameterValues("include");
this.richExportIncludes = (includes == null) ? new String[0] : includes;
@ -150,6 +150,11 @@ public class IndividualRdfAssembler {
m.add(runConstructQuery(String.format(
"CONSTRUCT { ?s ?predicate <%1$s> . } "
+ "WHERE { ?s ?predicate <%1$s> } ", individualUri)));
if (log.isDebugEnabled()) {
StringWriter sw = new StringWriter();
m.write(sw);
log.debug("Statements about '" + individualUri + "': " + sw);
}
return m;
}
@ -166,6 +171,15 @@ public class IndividualRdfAssembler {
+ "WHERE { <%1$s> ?predicate ?object ."
+ " ?object <%2$s> ?label . } ", individualUri,
RDFS.label)));
m.add(runConstructQuery(String
.format("CONSTRUCT { ?subject <%2$s> ?type . } "
+ "WHERE { ?subject ?predicate <%1$s> ."
+ " ?subject <%2$s> ?type . } ", individualUri, RDF.type)));
m.add(runConstructQuery(String.format(
"CONSTRUCT { ?subject <%2$s> ?label . } "
+ "WHERE { ?subject ?predicate <%1$s> ."
+ " ?subject <%2$s> ?label . } ", individualUri,
RDFS.label)));
return m;
}
@ -192,18 +206,18 @@ public class IndividualRdfAssembler {
String value = stmt.getObject().asLiteral().getString();
DataPropertyStatement dps = new DataPropertyStatementImpl(
subjectUri, predicateUri, value);
RequestedAction ddps = new DisplayDataPropertyStatement(dps);
if (!PolicyHelper.isAuthorizedForActions(vreq, ddps)) {
log.debug("not authorized: " + ddps);
RequestedAction pdps = new PublishDataPropertyStatement(o, dps);
if (!PolicyHelper.isAuthorizedForActions(vreq, pdps)) {
log.debug("not authorized: " + pdps);
stmts.remove();
}
} else if (stmt.getObject().isURIResource()) {
String objectUri = stmt.getObject().asResource().getURI();
ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(
subjectUri, predicateUri, objectUri);
RequestedAction dops = new DisplayObjectPropertyStatement(ops);
if (!PolicyHelper.isAuthorizedForActions(vreq, dops)) {
log.debug("not authorized: " + dops);
RequestedAction pops = new PublishObjectPropertyStatement(o, ops);
if (!PolicyHelper.isAuthorizedForActions(vreq, pops)) {
log.debug("not authorized: " + pops);
stmts.remove();
}
} else {

View file

@ -54,10 +54,8 @@ public class VitroVocabulary {
public static final String DATAPROPERTY_ISEXTERNALID = vitroURI+"isExternalId";
public static final String HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT = vitroURI+"hiddenFromDisplayBelowRoleLevelAnnot";
//public static final String PROHIBITED_FROM_CREATE_BELOW_ROLE_LEVEL_ANNOT = vitroURI+"prohibitedFromCreateBelowRoleLevelAnnot";
public static final String PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT = vitroURI+"prohibitedFromUpdateBelowRoleLevelAnnot";
//public static final String PROHIBITED_FROM_DELETE_BELOW_ROLE_LEVEL_ANNOT = vitroURI+"prohibitedFromDeleteBelowRoleLevelAnnot";
public static final String HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT = vitroURI+"hiddenFromPublishBelowRoleLevelAnnot";
public static final String MOST_SPECIFIC_TYPE = vitroURI + "mostSpecificType";

View file

@ -101,6 +101,11 @@ public class DataPropertyFiltering extends DataProperty {
return innerDataProperty.getProhibitedFromUpdateBelowRoleLevel();
}
@Override
public RoleLevel getHiddenFromPublishBelowRoleLevel() {
return innerDataProperty.getHiddenFromPublishBelowRoleLevel();
}
@Override
public String getLocalName() {
return innerDataProperty.getLocalName();
@ -196,6 +201,16 @@ public class DataPropertyFiltering extends DataProperty {
innerDataProperty.setProhibitedFromUpdateBelowRoleLevel(BaseResourceBean.RoleLevel.getRoleByUri(roleUri));
}
@Override
public void setHiddenFromPublishBelowRoleLevel(RoleLevel eR) {
innerDataProperty.setHiddenFromPublishBelowRoleLevel(eR);
}
@Override
public void setHiddenFromPublishBelowRoleLevelUsingRoleUri(String roleUri) {
innerDataProperty.setHiddenFromPublishBelowRoleLevel(BaseResourceBean.RoleLevel.getRoleByUri(roleUri));
}
@Override
public void setLocalName(String localName) {
innerDataProperty.setLocalName(localName);

View file

@ -449,6 +449,21 @@ public class IndividualFiltering implements Individual {
_innerIndividual.setProhibitedFromUpdateBelowRoleLevel(BaseResourceBean.RoleLevel.getRoleByUri(roleUri));
}
@Override
public RoleLevel getHiddenFromPublishBelowRoleLevel() {
return _innerIndividual.getHiddenFromPublishBelowRoleLevel();
}
@Override
public void setHiddenFromPublishBelowRoleLevel(RoleLevel eR) {
_innerIndividual.setHiddenFromPublishBelowRoleLevel(eR);
}
@Override
public void setHiddenFromPublishBelowRoleLevelUsingRoleUri(String roleUri) {
_innerIndividual.setHiddenFromPublishBelowRoleLevel(BaseResourceBean.RoleLevel.getRoleByUri(roleUri));
}
@Override
public boolean isAnonymous() {
return _innerIndividual.isAnonymous();

View file

@ -140,6 +140,11 @@ public class ObjectPropertyFiltering extends ObjectProperty {
return innerObjectProperty.getProhibitedFromUpdateBelowRoleLevel();
}
@Override
public RoleLevel getHiddenFromPublishBelowRoleLevel() {
return innerObjectProperty.getHiddenFromPublishBelowRoleLevel();
}
@Override
public boolean getInverseFunctional() {
return innerObjectProperty.getInverseFunctional();
@ -368,6 +373,16 @@ public class ObjectPropertyFiltering extends ObjectProperty {
innerObjectProperty.setProhibitedFromUpdateBelowRoleLevel(BaseResourceBean.RoleLevel.getRoleByUri(roleUri));
}
@Override
public void setHiddenFromPublishBelowRoleLevel(RoleLevel eR) {
innerObjectProperty.setHiddenFromPublishBelowRoleLevel(eR);
}
@Override
public void setHiddenFromPublishBelowRoleLevelUsingRoleUri(String roleUri) {
innerObjectProperty.setHiddenFromPublishBelowRoleLevel(BaseResourceBean.RoleLevel.getRoleByUri(roleUri));
}
@Override
public void setInverseFunctional(boolean inverseFunctional) {
innerObjectProperty.setInverseFunctional(inverseFunctional);

View file

@ -235,6 +235,26 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
}
}
dp.setProhibitedFromUpdateBelowRoleLevel(prohibitedRoleLevel);//this might get set to null
//There might be multiple HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT properties, only use the highest
it = op.listProperties(HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT);
BaseResourceBean.RoleLevel publishRoleLevel = null;
while( it.hasNext() ){
Statement stmt = it.nextStatement();
RDFNode obj;
if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){
Resource res = obj.as(Resource.class);
if( res != null && res.getURI() != null ){
BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI());
if( roleFromModel != null &&
(publishRoleLevel == null || roleFromModel.compareTo(publishRoleLevel) > 0 )){
publishRoleLevel = roleFromModel;
}
}
}
}
dp.setHiddenFromPublishBelowRoleLevel(publishRoleLevel);//this might get set to null
dp.setCustomEntryForm(getPropertyStringValue(op,PROPERTY_CUSTOMENTRYFORMANNOT));
dp.setExternalId( getOntModelSelector().getTBoxModel().contains(op, DATAPROPERTY_ISEXTERNALID, "TRUE") );
@ -504,6 +524,10 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
if (PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT != null && dtp.getProhibitedFromUpdateBelowRoleLevel() != null) { // only need to add if present
jDataprop.addProperty(PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(dtp.getProhibitedFromUpdateBelowRoleLevel().getURI()));
}
jDataprop.removeAll(HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT);
if (HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT != null && dtp.getHiddenFromPublishBelowRoleLevel() != null) { // only need to add if present
jDataprop.addProperty(HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(dtp.getHiddenFromPublishBelowRoleLevel().getURI()));
}
/*
if (dtp.isSelfEditProhibited()) { // only add the property if it's true
addPropertyBooleanValue(jDataprop, PROPERTY_SELFEDITPROHIBITEDANNOT, dtp.isSelfEditProhibited(), ontModel);
@ -570,6 +594,10 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
updatePropertyResourceURIValue(jDataprop,PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT,dtp.getProhibitedFromUpdateBelowRoleLevel().getURI(),ontModel);
}
if (dtp.getHiddenFromPublishBelowRoleLevel() != null) {
updatePropertyResourceURIValue(jDataprop,HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT,dtp.getHiddenFromPublishBelowRoleLevel().getURI(),ontModel);
}
if (dtp.getGroupURI() != null) {
updatePropertyResourceURIValue(jDataprop,PROPERTY_INPROPERTYGROUPANNOT,dtp.getGroupURI(),ontModel);
}

View file

@ -43,6 +43,7 @@ public class JenaBaseDaoCon {
protected AnnotationProperty HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT = _constModel.createAnnotationProperty(VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT);
protected AnnotationProperty PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT);
protected AnnotationProperty HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT = _constModel.createAnnotationProperty(VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT);
protected AnnotationProperty SEARCH_BOOST_ANNOT = _constModel.createAnnotationProperty(VitroVocabulary.SEARCH_BOOST_ANNOT);

View file

@ -190,7 +190,7 @@ public class JenaModelUtils {
// Perform possibly-redundant extraction to try ensure we don't miss
// individual axioms floating around. We still might miss things;
// this approach isn't perfect.
if (mode = AGGRESSIVE) {
if (mode == AGGRESSIVE) {
tboxModel.add(construct(dataset, namespace, graphURI, RDFS.subClassOf));
tboxModel.add(construct(dataset, namespace, graphURI, RDFS.subPropertyOf));
tboxModel.add(construct(dataset, namespace, graphURI, OWL.equivalentClass));
@ -219,6 +219,8 @@ public class JenaModelUtils {
VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT)));
tboxModel.add(construct(dataset, namespace, graphURI, ResourceFactory.createResource(
VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT)));
tboxModel.add(construct(dataset, namespace, graphURI, ResourceFactory.createResource(
VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT)));
tboxModel.add(construct(dataset, namespace, graphURI, ResourceFactory.createResource(
VitroVocabulary.DESCRIPTION_ANNOT)));
tboxModel.add(construct(dataset, namespace, graphURI, ResourceFactory.createResource(

View file

@ -202,6 +202,25 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
p.setProhibitedFromUpdateBelowRoleLevel(prohibitedRoleLevel); //this might get set to null
//There might be multiple HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT properties, only use the highest
it = op.listProperties(HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT);
BaseResourceBean.RoleLevel publishRoleLevel = null;
while( it.hasNext() ){
Statement stmt = it.nextStatement();
RDFNode obj;
if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){
Resource res = obj.as(Resource.class);
if( res != null && res.getURI() != null ){
BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI());
if( roleFromModel != null &&
(publishRoleLevel == null || roleFromModel.compareTo(publishRoleLevel) > 0 )){
publishRoleLevel = roleFromModel;
}
}
}
}
p.setHiddenFromPublishBelowRoleLevel(publishRoleLevel); //this might get set to null
p.setCustomEntryForm(getPropertyStringValue(op,PROPERTY_CUSTOMENTRYFORMANNOT));
Boolean selectFromObj = getPropertyBooleanValue(op,PROPERTY_SELECTFROMEXISTINGANNOT);
p.setSelectFromExisting(selectFromObj==null ? true : selectFromObj);
@ -315,7 +334,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
"SELECT ?range ?rangeRoot ?label ?group ?customForm ?displayRank ?displayLevel " +
" ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed \n" +
" ?updateLevel ?publishLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed \n" +
" ?collateBySubclass ?displayLimit ?individualSortProperty \n" +
" ?entitySortDirection ?selectFromExisting ?offerCreateNew \n" +
" ?publicDescription ?stubDeletion \n" +
@ -341,6 +360,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
" OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" +
" OPTIONAL { ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" +
" OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" +
" OPTIONAL { ?configuration vitro:hiddenFromPublishBelowRoleLevelAnnot ?publishLevel } \n" +
" OPTIONAL { ?configuration <" + PROPERTY_COLLATEBYSUBCLASSANNOT.getURI() + "> ?collateBySubclass } \n" +
" OPTIONAL { ?configuration <" + DISPLAY_LIMIT.getURI() + "> ?displayLimit } \n" +
" OPTIONAL { ?configuration <" + PROPERTY_OBJECTINDIVIDUALSORTPROPERTY.getURI() + "> ?individualSortProperty } \n " +
@ -392,6 +412,12 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
BaseResourceBean.RoleLevel.getRoleByUri(
updateLevelRes.getURI()));
}
Resource publishLevelRes = qsoln.getResource("publishLevel");
if (publishLevelRes != null) {
op.setHiddenFromPublishBelowRoleLevel(
BaseResourceBean.RoleLevel.getRoleByUri(
publishLevelRes.getURI()));
}
Literal labelLit = qsoln.getLiteral("label");
if (labelLit != null) {
op.setDomainPublic(labelLit.getLexicalForm());
@ -739,6 +765,10 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
updatePropertyResourceURIValue(p, PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, prop.getProhibitedFromUpdateBelowRoleLevel().getURI());
}
if (prop.getHiddenFromPublishBelowRoleLevel() != null) {
updatePropertyResourceURIValue(p, HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT, prop.getHiddenFromPublishBelowRoleLevel().getURI());
}
updatePropertyStringValue(p,PROPERTY_CUSTOMENTRYFORMANNOT,prop.getCustomEntryForm(),ontModel);
updatePropertyBooleanValue(p,PROPERTY_SELECTFROMEXISTINGANNOT,prop.getSelectFromExisting(),ontModel,JenaBaseDao.KEEP_ONLY_IF_FALSE);
updatePropertyBooleanValue(p,PROPERTY_OFFERCREATENEWOPTIONANNOT,prop.getOfferCreateNewOption(),ontModel,JenaBaseDao.KEEP_ONLY_IF_TRUE);

View file

@ -984,6 +984,15 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao {
}
}
ontCls.removeAll(HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT);
if (HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT != null && cls.getHiddenFromPublishBelowRoleLevel() != null) { // only need to add if present
try {
ontCls.addProperty(HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(cls.getHiddenFromPublishBelowRoleLevel().getURI()));
} catch (Exception e) {
log.error("error adding HiddenFromPublishBelowRoleLevel annotation to class "+cls.getURI());
}
}
/* OPTIONAL annotation properties */
addPropertyStringValue(ontCls,PROPERTY_CUSTOMENTRYFORMANNOT,cls.getCustomEntryForm(),ontModel);
addPropertyStringValue(ontCls,PROPERTY_CUSTOMDISPLAYVIEWANNOT,cls.getCustomDisplayView(),ontModel);
@ -1025,6 +1034,10 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao {
updatePropertyResourceURIValue(ontCls,PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT,cls.getProhibitedFromUpdateBelowRoleLevel().getURI(),ontModel);
}
if (cls.getHiddenFromPublishBelowRoleLevel() != null) {
updatePropertyResourceURIValue(ontCls,HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT,cls.getHiddenFromPublishBelowRoleLevel().getURI(),ontModel);
}
updatePropertyStringValue(ontCls,PROPERTY_CUSTOMENTRYFORMANNOT,cls.getCustomEntryForm(),ontModel);
updatePropertyStringValue(ontCls,PROPERTY_CUSTOMDISPLAYVIEWANNOT,cls.getCustomDisplayView(),ontModel);
updatePropertyStringValue(ontCls,PROPERTY_CUSTOMSHORTVIEWANNOT,cls.getCustomShortView(),ontModel);

View file

@ -343,7 +343,7 @@ public class VClassJena extends VClass {
} else {
cls.getOntModel().enterCriticalSection(Lock.READ);
try {
//There might be multiple PROHIBITED_FROM_UPDATE_DISPLAY_ANNOT properties, only use the highest
//There might be multiple PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT properties, only use the highest
StmtIterator it = cls.listProperties(webappDaoFactory.getJenaBaseDao().PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT);
BaseResourceBean.RoleLevel prohibitedRoleLevel = null;
while( it.hasNext() ){
@ -369,6 +369,41 @@ public class VClassJena extends VClass {
}
}
@Override
public RoleLevel getHiddenFromPublishBelowRoleLevel() {
if (this.hiddenFromPublishBelowRoleLevel != null) {
return this.hiddenFromPublishBelowRoleLevel;
} else {
cls.getOntModel().enterCriticalSection(Lock.READ);
try {
//There might be multiple HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT properties, only use the highest
StmtIterator it = cls.listProperties(webappDaoFactory.getJenaBaseDao().HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT);
BaseResourceBean.RoleLevel publishRoleLevel = null;
while( it.hasNext() ){
Statement stmt = it.nextStatement();
RDFNode obj;
if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){
Resource res = obj.as(Resource.class);
if( res != null && res.getURI() != null ){
BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI());
if( roleFromModel != null &&
(publishRoleLevel == null || roleFromModel.compareTo(publishRoleLevel) > 0 )){
publishRoleLevel = roleFromModel;
}
}
}
}
setHiddenFromPublishBelowRoleLevel(publishRoleLevel); //this might get set to null
return this.hiddenFromPublishBelowRoleLevel;
} finally {
cls.getOntModel().leaveCriticalSection();
}
}
}
@Override
public boolean isUnion() {
return this.cls.isUnionClass();

View file

@ -85,13 +85,17 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
verboseDisplay = new HashMap<String, Object>();
RoleLevel roleLevel = property.getHiddenFromDisplayBelowRoleLevel();
String roleLevelLabel = roleLevel != null ? roleLevel.getLabel() : "";
String roleLevelLabel = roleLevel != null ? roleLevel.getDisplayLabel() : "";
verboseDisplay.put("displayLevel", roleLevelLabel);
roleLevel = property.getProhibitedFromUpdateBelowRoleLevel();
roleLevelLabel = roleLevel != null ? roleLevel.getLabel() : "";
roleLevelLabel = roleLevel != null ? roleLevel.getUpdateLabel() : "";
verboseDisplay.put("updateLevel", roleLevelLabel);
roleLevel = property.getHiddenFromPublishBelowRoleLevel();
roleLevelLabel = roleLevel != null ? roleLevel.getDisplayLabel() : "";
verboseDisplay.put("publishLevel", roleLevelLabel);
verboseDisplay.put("localName", property.getLocalNameWithPrefix());
verboseDisplay.put("displayRank", getPropertyDisplayTier(property));

View file

@ -47,6 +47,13 @@ import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
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 edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectorTest;
/**
* A collection of useful routines to help when testing.
* <ul>
@ -404,8 +411,22 @@ public abstract class AbstractTestClass {
assertEquals(message, expected, actual);
}
@SuppressWarnings("unchecked")
protected <T> Set<T> buildSet(T... array) {
return new HashSet<T>(Arrays.asList(array));
}
protected OntModel readModelFromFile(String relativePath, String rdfType) throws IOException {
InputStream stream = this.getClass()
.getResourceAsStream(relativePath);
Model model = ModelFactory.createDefaultModel();
model.read(stream, null, rdfType);
stream.close();
OntModel ontModel = ModelFactory.createOntologyModel(
OntModelSpec.OWL_DL_MEM, model);
ontModel.prepare();
return ontModel;
}
}

View file

@ -35,7 +35,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
/**
* Check that the bean gets built properly, and check that the bean works properly.
* Check that the bean gets built properly, and check that the bean works
* properly.
*/
public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
private static final Log log = LogFactory
@ -43,12 +44,12 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
private static final String PROPERTY_DISPLAY_THRESHOLD = VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT;
private static final String PROPERTY_MODIFY_THRESHOLD = VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT;
private static final String PROPERTY_PUBLISH_THRESHOLD = VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT;
private static final String[] PROHIBITED_NAMESPACES = new String[] {
VitroVocabulary.vitroURI, "" };
private static final String[] PERMITTED_EXCEPTIONS = new String[] {
VitroVocabulary.MONIKER };
private static final String[] PERMITTED_EXCEPTIONS = new String[] { VitroVocabulary.MONIKER };
private OntModel ontModel;
private ModelWrapper wrapper;
@ -56,33 +57,35 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
@Before
public void setLoggingLevel() {
// setLoggerLevel(PropertyRestrictionPolicyHelper.class, Level.DEBUG);
// setLoggerLevel(PropertyRestrictionPolicyHelper.class, Level.DEBUG);
}
private void mapPut(String predicateURI, RoleLevel roleLevel,
Map<Pair<String, Pair<String,String>>, RoleLevel> map) {
map.put(new Pair<String, Pair<String,String>>(
OWL.Thing.getURI(), new Pair<String, String>(
predicateURI, OWL.Thing.getURI())), roleLevel);
Map<Pair<String, Pair<String, String>>, RoleLevel> map) {
map.put(new Pair<String, Pair<String, String>>(OWL.Thing.getURI(),
new Pair<String, String>(predicateURI, OWL.Thing.getURI())),
roleLevel);
}
@Before
public void createTheBean() {
Map<Pair<String, Pair<String,String>>, RoleLevel> displayLevels =
new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
Map<Pair<String, Pair<String, String>>, RoleLevel> displayLevels = new HashMap<>();
mapPut("http://predicates#display_curator", CURATOR, displayLevels);
mapPut("http://predicates#display_hidden", NOBODY, displayLevels);
Map<Pair<String, Pair<String,String>>, RoleLevel> modifyLevels =
new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
Map<Pair<String, Pair<String, String>>, RoleLevel> modifyLevels = new HashMap<>();
mapPut("http://predicates#modify_self", SELF, modifyLevels);
mapPut("http://predicates#modify_curator", CURATOR, modifyLevels);
mapPut("http://predicates#modify_hidden", NOBODY, modifyLevels);
Map<Pair<String, Pair<String, String>>, RoleLevel> publishLevels = new HashMap<>();
mapPut("http://predicates#publish_curator", CURATOR, publishLevels);
mapPut("http://predicates#publish_hidden", NOBODY, publishLevels);
bean = new PropertyRestrictionPolicyHelper(
Arrays.asList(PROHIBITED_NAMESPACES),
Arrays.asList(PERMITTED_EXCEPTIONS), displayLevels,
modifyLevels, ModelFactory.createDefaultModel());
modifyLevels, publishLevels);
}
@Before
@ -100,6 +103,11 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
PROPERTY_MODIFY_THRESHOLD, EDITOR.getURI());
wrapper.add("http://thresholds#modify_curator",
PROPERTY_MODIFY_THRESHOLD, CURATOR.getURI());
wrapper.add("http://thresholds#publish_public",
PROPERTY_PUBLISH_THRESHOLD, PUBLIC.getURI());
wrapper.add("http://thresholds#publish_hidden",
PROPERTY_PUBLISH_THRESHOLD, NOBODY.getURI());
}
// ----------------------------------------------------------------------
@ -125,6 +133,12 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
null));
}
@Test
public void publishResource() {
assertEquals("publish a random resource", true,
bean.canPublishResource("http://someRandom#string", null));
}
@Test
public void modifyResourcePermittedException() {
assertEquals("modify a exception resource", true,
@ -133,76 +147,119 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
@Test
public void displayPredicateNoRestriction() {
assertEquals("displayPredicate: open", true,
bean.canDisplayPredicate(createVitroProperty(
"http://predicates#open"), PUBLIC));
assertEquals("displayPredicate: open", true, bean.canDisplayPredicate(
createVitroProperty("http://predicates#open"), PUBLIC));
}
@Test
public void displayPredicateRestrictionLower() {
assertEquals("displayPredicate: lower restriction", true,
bean.canDisplayPredicate(createVitroProperty(
"http://predicates#display_self"), CURATOR));
bean.canDisplayPredicate(
createVitroProperty("http://predicates#display_self"),
CURATOR));
}
@Test
public void displayPredicateRestrictionEqual() {
assertEquals("displayPredicate: equal restriction", true,
bean.canDisplayPredicate(createVitroProperty(
"http://predicates#display_curator"), CURATOR));
assertEquals(
"displayPredicate: equal restriction",
true,
bean.canDisplayPredicate(
createVitroProperty("http://predicates#display_curator"),
CURATOR));
}
@Test
public void displayPredicateRestrictionHigher() {
assertEquals("displayPredicate: higher restriction", false,
bean.canDisplayPredicate(createVitroProperty(
"http://predicates#display_hidden"), CURATOR));
assertEquals(
"displayPredicate: higher restriction",
false,
bean.canDisplayPredicate(
createVitroProperty("http://predicates#display_hidden"),
CURATOR));
}
@Test
public void modifyPredicateNoRestriction() {
assertEquals("modifyPredicate: open", true,
bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#open"), PUBLIC));
assertEquals("modifyPredicate: open", true, bean.canModifyPredicate(
new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#open"), PUBLIC));
}
@Test
public void modifyPredicateRestrictionLower() {
assertEquals("modifyPredicate: lower restriction", true,
bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#modify_self"),
CURATOR));
bean.canModifyPredicate(
new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#modify_self"), CURATOR));
}
@Test
public void modifyPredicateRestrictionEqual() {
assertEquals("modifyPredicate: equal restriction", true,
bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#modify_curator"),
CURATOR));
bean.canModifyPredicate(
new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#modify_curator"), CURATOR));
}
@Test
public void modifyPredicateRestrictionHigher() {
assertEquals("modifyPredicate: higher restriction", false,
bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#modify_hidden"),
CURATOR));
bean.canModifyPredicate(
new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#modify_hidden"), CURATOR));
}
@Test
public void modifyPredicateProhibitedNamespace() {
assertEquals("modifyPredicate: prohibited namespace", false,
bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
PROHIBITED_NAMESPACES[0] + "randoom"),
DB_ADMIN));
assertEquals(
"modifyPredicate: prohibited namespace",
false,
bean.canModifyPredicate(
new edu.cornell.mannlib.vitro.webapp.beans.Property(
PROHIBITED_NAMESPACES[0] + "randoom"), DB_ADMIN));
}
@Test
public void modifyPredicatePermittedException() {
assertEquals("modifyPredicate: permitted exception", true,
bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
PERMITTED_EXCEPTIONS[0]), DB_ADMIN));
bean.canModifyPredicate(
new edu.cornell.mannlib.vitro.webapp.beans.Property(
PERMITTED_EXCEPTIONS[0]), DB_ADMIN));
}
@Test
public void publishPredicateNoRestriction() {
assertEquals("publishPredicate: open", true, bean.canPublishPredicate(
createVitroProperty("http://predicates#open"), PUBLIC));
}
@Test
public void publishPredicateRestrictionLower() {
assertEquals("publishPredicate: lower restriction", true,
bean.canPublishPredicate(
createVitroProperty("http://predicates#publish_self"),
CURATOR));
}
@Test
public void publishPredicateRestrictionEqual() {
assertEquals(
"publishPredicate: equal restriction",
true,
bean.canPublishPredicate(
createVitroProperty("http://predicates#publish_curator"),
CURATOR));
}
@Test
public void publishPredicateRestrictionHigher() {
assertEquals(
"publishPredicate: higher restriction",
false,
bean.canPublishPredicate(
createVitroProperty("http://predicates#publish_hidden"),
CURATOR));
}
// ----------------------------------------------------------------------
@ -211,8 +268,7 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
@Test
public void buildDisplayThresholds() {
Map<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel> expectedMap =
new HashMap<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel>();
Map<Pair<String, Pair<String, String>>, BaseResourceBean.RoleLevel> expectedMap = new HashMap<>();
mapPut("http://thresholds#display_public", PUBLIC, expectedMap);
mapPut("http://thresholds#display_hidden", NOBODY, expectedMap);
@ -222,8 +278,7 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
@Test
public void buildModifyThresholds() {
Map<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel> expectedMap =
new HashMap<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel>();
Map<Pair<String, Pair<String, String>>, BaseResourceBean.RoleLevel> expectedMap = new HashMap<>();
mapPut("http://thresholds#modify_editor", EDITOR, expectedMap);
mapPut("http://thresholds#modify_curator", CURATOR, expectedMap);
@ -231,6 +286,16 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
assertEquals("modify thresholds", expectedMap, actualMap);
}
@Test
public void buildPublishThresholds() {
Map<Pair<String, Pair<String, String>>, BaseResourceBean.RoleLevel> expectedMap = new HashMap<>();
mapPut("http://thresholds#publish_public", PUBLIC, expectedMap);
mapPut("http://thresholds#publish_hidden", NOBODY, expectedMap);
Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_PUBLISH_THRESHOLD);
assertEquals("publish thresholds", expectedMap, actualMap);
}
/** Invoke the private static method "populateThresholdMap" */
private Map<String, RoleLevel> populateThresholdMap(String propertyUri) {
Map<String, RoleLevel> map = new HashMap<String, BaseResourceBean.RoleLevel>();
@ -264,7 +329,7 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
}
private edu.cornell.mannlib.vitro.webapp.beans.Property createVitroProperty(
String propertyURI) {
return new edu.cornell.mannlib.vitro.webapp.beans.Property(propertyURI);
String propertyURI) {
return new edu.cornell.mannlib.vitro.webapp.beans.Property(propertyURI);
}
}

View file

@ -0,0 +1,154 @@
@prefix ocresd: <http://purl.org/net/OCRe/study_design.owl#> .
@prefix geo: <http://aims.fao.org/aos/geopolitical.owl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix scires: <http://vivoweb.org/ontology/scientific-research#> .
@prefix cito: <http://purl.org/spar/cito/> .
@prefix fabio: <http://purl.org/spar/fabio/> .
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
@prefix obo: <http://purl.obolibrary.org/obo/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ocrer: <http://purl.org/net/OCRe/research.owl#> .
@prefix vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> .
@prefix event: <http://purl.org/NET/c4dm/event.owl#> .
@prefix bibo: <http://purl.org/ontology/bibo/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix c4o: <http://purl.org/spar/c4o/> .
@prefix vitro-public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix vivo: <http://vivoweb.org/ontology/core#> .
<http://vivo.mydomain.edu/individual/n3639>
a vivo:FacultyMember ,
foaf:Person ,
owl:Thing ,
foaf:Agent ,
obo:BFO_0000002 ,
obo:BFO_0000001 ,
obo:BFO_0000004 ;
rdfs:label "Baker, Able "^^xsd:string ;
obo:ARG_2000028 <http://vivo.mydomain.edu/individual/n3972> ;
obo:RO_0000053 <http://vivo.mydomain.edu/individual/n475> ,
<http://vivo.mydomain.edu/individual/n7850> ;
vitro:mostSpecificType
vivo:FacultyMember ;
vivo:freetextKeyword
"Potrezebie, Chattanooga" ;
vivo:hasCollaborator
<http://vivo.mydomain.edu/individual/n7429> ;
vivo:relatedBy <http://vivo.mydomain.edu/individual/n3401> ,
<http://vivo.mydomain.edu/individual/n5855> ,
<http://vivo.mydomain.edu/individual/n2421> ;
vivo:researchOverview
"Whatever strikes my fancy." ;
vivo:scopusId "abaker" .
<http://vivo.mydomain.edu/individual/n3972>
a vcard:Kind ,
obo:BFO_0000031 ,
owl:Thing ,
obo:ARG_2000379 ,
obo:IAO_0000030 ,
obo:BFO_0000002 ,
obo:BFO_0000001 ,
vcard:Individual ;
obo:ARG_2000029 <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n475>
a owl:Thing ,
obo:BFO_0000023 ,
vivo:InvestigatorRole ,
obo:BFO_0000002 ,
obo:BFO_0000017 ,
vivo:PrincipalInvestigatorRole ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:ResearcherRole ;
obo:RO_0000052 <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n7850>
a owl:Thing ,
obo:BFO_0000023 ,
obo:BFO_0000017 ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:LeaderRole ;
rdfs:label "Lead Guitarist"^^xsd:string ;
obo:RO_0000052 <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n7429>
a foaf:Person ,
vivo:FacultyMember ,
foaf:Agent ,
owl:Thing ,
obo:BFO_0000002 ,
obo:BFO_0000001 ,
obo:BFO_0000004 ;
rdfs:label "Yum, Yum " .
<http://vivo.mydomain.edu/individual/n3401>
a owl:Thing ,
vivo:Relationship ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:Authorship ;
vivo:relates <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n5855>
a vivo:FacultyPosition ,
owl:Thing ,
vivo:Relationship ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:Position ;
rdfs:label "Functionary"^^xsd:string ;
vivo:relates <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n2421>
a owl:Thing ,
vivo:Relationship ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:Grant ;
rdfs:label "Cosmogenic Lassitude in Plegmatic Axolotls" ;
vivo:relates <http://vivo.mydomain.edu/individual/n3639> .
obo:BFO_0000001
a owl:Class ;
rdfs:label "Entity" .
obo:BFO_0000002
a owl:Class ;
rdfs:label "Continuant" .
obo:BFO_0000004
a owl:Class ;
rdfs:label "Independent Continuant"@en-US .
vivo:FacultyMember
a owl:Class ;
rdfs:label "Faculty Member"@en-US .
foaf:Person
a owl:Class ;
rdfs:label "Person"@en-US .
foaf:Agent
a owl:Class ;
rdfs:label "Agent"@en-US .
owl:Thing
a owl:Class .
<http://vivo.mydomain.edu/individual/n3639/n3639.n3>
a foaf:Document ;
rdfs:label "RDF description of Baker, Able - http://vivo.mydomain.edu/individual/n3639" ;
<http://purl.org/dc/elements/1.1/date> "2014-03-10T11:08:39"^^xsd:dateTime ;
<http://purl.org/dc/elements/1.1/publisher> <http://vivo.mydomain.edu> ;
<http://purl.org/dc/elements/1.1/rights> <http://vivo.mydomain.edu/termsOfUse> .

View file

@ -0,0 +1,503 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.individual;
import static com.hp.hpl.jena.ontology.OntModelSpec.OWL_MEM;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.LABEL;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.RDF_TYPE;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.collections.IteratorUtils;
import org.apache.log4j.Level;
import org.junit.Before;
import org.junit.Test;
import stubs.javax.servlet.ServletContextStub;
import stubs.javax.servlet.http.HttpServletRequestStub;
import stubs.javax.servlet.http.HttpSessionStub;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.policy.BasicPolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
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;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel;
import edu.cornell.mannlib.vitro.webapp.web.ContentType;
/**
* Start with a set of data and filter it appropriately.
*/
public class IndividualRdfAssemblerTest extends AbstractTestClass {
private static final String INDIVIDUAL_URI = "http://vivo.mydomain.edu/individual/n3639";
private static final String DOCUMENT_URI = "http://vivo.mydomain.edu/individual/n3639/n3639.n3";
/** When comparing, consider all date-stamps to be equal. */
private static final String DATE_DATA_PROPERTY = "http://purl.org/dc/elements/1.1/date";
private static final String DP1 = "http://dataPropertyUri1";
private static final String OP1 = "http://objectPropertyUri1";
private static final String C1 = "http://class1";
private static final String C2 = "http://class2";
private static final String I1 = "http://individual1";
private static final String RAW_RDF_FILENAME = "IndividualRdfAssemblerTest.rawRdf.n3";
private static final String FILTERED_RDF_FILENAME = "IndividualRdfAssemblerTest.filteredRdf.n3";
private static final String UNFILTERED_RDF_FILENAME = "IndividualRdfAssemblerTest.unfilteredRdf.n3";
private static final String[] REAL_WORLD_PROPERTIES = {
"http://vivoweb.org/ontology/core#overview",
"http://vivoweb.org/ontology/core#hasResearchArea",
"http://vivoweb.org/ontology/core#researchAreaOf" };
private OntModel rawRdf;
private OntModel expectedLod;
private OntModel actualLod;
private ServletContextStub ctx;
private HttpSessionStub session;
private HttpServletRequestStub req;
private VitroRequest vreq;
private RDFServiceModel rdfService;
private IndividualRdfAssembler ira;
@Before
public void setLoggingLevels() {
setLoggerLevel(ModelAccess.class, Level.ERROR);
// setLoggerLevel(IndividualRdfAssembler.class, Level.DEBUG);
// setLoggerLevel(RDFServiceStub.class, Level.DEBUG);
}
@Before
public void setup() throws IOException {
ctx = new ServletContextStub();
session = new HttpSessionStub();
session.setServletContext(ctx);
req = new HttpServletRequestStub();
req.setSession(session);
req.setRequestUrl(new URL(DOCUMENT_URI));
}
@Test
public void getOutgoingStatements() {
Statement s1 = dataStmt(INDIVIDUAL_URI, DP1, "value");
Statement s2 = objectStmt(INDIVIDUAL_URI, OP1, I1);
rawRdf = model(s1, s2);
expectedLod = includeDocInfo(model(s1, s2));
policyUnrestricted();
filterAndCompare("getOutgoingStatements");
}
@Test
public void filterOutgoingStatements() {
Statement s1 = dataStmt(INDIVIDUAL_URI, DP1, "value");
Statement s2 = objectStmt(INDIVIDUAL_URI, OP1, I1);
rawRdf = model(s1, s2);
expectedLod = includeDocInfo(model());
policyRestrictByPredicate(DP1, OP1);
filterAndCompare("filterOutgoingStatements");
}
@Test
public void getIncomingStatements() {
Statement s1 = objectStmt(I1, OP1, INDIVIDUAL_URI);
rawRdf = model(s1);
expectedLod = includeDocInfo(model(s1));
policyUnrestricted();
filterAndCompare("getIncomingStatements");
}
@Test
public void filterIncomingStatements() {
Statement s1 = objectStmt(I1, OP1, INDIVIDUAL_URI);
rawRdf = model(s1);
expectedLod = includeDocInfo(model());
policyRestrictByPredicate(OP1);
filterAndCompare("filterIncomingStatements");
}
@Test
public void getLabelAndTypeOfOutgoingObjects() {
Statement s1 = objectStmt(INDIVIDUAL_URI, OP1, I1);
Statement s2 = dataStmt(I1, LABEL, "silly label");
Statement s3 = objectStmt(I1, RDF_TYPE, C1);
rawRdf = model(s1, s2, s3);
expectedLod = includeDocInfo(model(s1, s2, s3));
policyUnrestricted();
filterAndCompare("getLabelAndTypeOfOutgoingObjects");
}
@Test
public void filterOrphanStatementsOfOutgoingObjects() {
Statement s1 = objectStmt(INDIVIDUAL_URI, OP1, I1);
Statement s2 = dataStmt(I1, LABEL, "silly label");
Statement s3 = objectStmt(I1, RDF_TYPE, C1);
rawRdf = model(s1, s2, s3);
expectedLod = includeDocInfo(model());
policyRestrictByPredicate(OP1);
filterAndCompare("filterOrphanStatementsOfOutgoingObjects");
}
@Test
public void getLabelAndTypeOfIncomingObjects() {
Statement s1 = objectStmt(I1, OP1, INDIVIDUAL_URI);
Statement s2 = dataStmt(I1, LABEL, "silly label");
Statement s3 = objectStmt(I1, RDF_TYPE, C1);
rawRdf = model(s1, s2, s3);
expectedLod = includeDocInfo(model(s1, s2, s3));
policyUnrestricted();
filterAndCompare("getLabelAndTypeOfIncomingObjects");
}
@Test
public void filterOrphanStatementsOfIncomingObjects() {
Statement s1 = objectStmt(I1, OP1, INDIVIDUAL_URI);
Statement s2 = dataStmt(I1, LABEL, "silly label");
Statement s3 = objectStmt(I1, RDF_TYPE, C1);
rawRdf = model(s1, s2, s3);
expectedLod = includeDocInfo(model());
policyRestrictByPredicate(OP1);
filterAndCompare("filterOrphanStatementsOfIncomingObjects");
}
@Test
public void getTypeStatements() {
Statement s1 = objectStmt(INDIVIDUAL_URI, RDF_TYPE, C1);
rawRdf = model(s1);
expectedLod = includeDocInfo(model(s1));
policyUnrestricted();
filterAndCompare("getTypeStatements");
}
@Test
public void filterTypeStatements() {
Statement s1 = objectStmt(INDIVIDUAL_URI, RDF_TYPE, C1);
rawRdf = model(s1);
expectedLod = includeDocInfo(model());
policyRestrictByClass(C1);
filterAndCompare("filterTypeStatements");
}
@Test
public void getTypeAndLabelOfType() {
Statement s1 = objectStmt(INDIVIDUAL_URI, RDF_TYPE, C1);
Statement s2 = dataStmt(C1, LABEL, "silly label");
Statement s3 = objectStmt(C1, RDF_TYPE, C2);
rawRdf = model(s1, s2, s3);
expectedLod = includeDocInfo(model(s1, s2, s3));
policyUnrestricted();
filterAndCompare("getTypeAndLabelOfType");
}
@Test
public void filterOrphanTypeAndLabelOfType() {
Statement s1 = objectStmt(INDIVIDUAL_URI, RDF_TYPE, C1);
Statement s2 = dataStmt(I1, LABEL, "silly label");
Statement s3 = objectStmt(I1, RDF_TYPE, C2);
rawRdf = model(s1, s2, s3);
expectedLod = includeDocInfo(model());
policyRestrictByClass(C1);
filterAndCompare("filterOrphanTypeAndLabelOfType");
}
@Test
public void dontGetOtherStatementsFromOutgoingObjects() {
Statement s1 = objectStmt(INDIVIDUAL_URI, OP1, I1);
Statement s2 = dataStmt(I1, DP1, "silly data property");
rawRdf = model(s1, s2);
expectedLod = includeDocInfo(model(s1));
policyUnrestricted();
filterAndCompare("dontGetOtherStatementsFromOutgoingObjects");
}
@Test
public void dontGetOtherStatementsFromIncomingObjects() {
Statement s1 = objectStmt(I1, OP1, INDIVIDUAL_URI);
Statement s2 = dataStmt(I1, DP1, "silly data property");
rawRdf = model(s1, s2);
expectedLod = includeDocInfo(model(s1));
policyUnrestricted();
filterAndCompare("dontGetOtherStatementsFromIncomingObjects");
}
@Test
public void dontGetUnrelatedStatements() {
Statement s1 = dataStmt(I1, DP1, "silly data property");
rawRdf = model(s1);
expectedLod = includeDocInfo(model());
policyUnrestricted();
filterAndCompare("dontGetUnrelatedStatements");
}
@Test
public void realWorldTestRoot() throws IOException {
rawRdf = readModelFromFile(RAW_RDF_FILENAME, "N3");
expectedLod = readModelFromFile(UNFILTERED_RDF_FILENAME, "N3");
policyUnrestricted();
filterAndCompare("real world test - root");
}
@Test
public void realWorldTestPublic() throws IOException {
rawRdf = readModelFromFile(RAW_RDF_FILENAME, "N3");
expectedLod = readModelFromFile(FILTERED_RDF_FILENAME, "N3");
policyRestrictByPredicate(REAL_WORLD_PROPERTIES);
filterAndCompare("real world test - public");
}
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
private Statement dataStmt(String subjectUri, String predicateUri,
String value) {
Resource subject = ResourceFactory.createResource(subjectUri);
Property predicate = ResourceFactory.createProperty(predicateUri);
Literal object = ResourceFactory.createPlainLiteral(value);
return ResourceFactory.createStatement(subject, predicate, object);
}
private Statement objectStmt(String subjectUri, String predicateUri,
String objectUri) {
Resource subject = ResourceFactory.createResource(subjectUri);
Property predicate = ResourceFactory.createProperty(predicateUri);
Resource object = ResourceFactory.createResource(objectUri);
return ResourceFactory.createStatement(subject, predicate, object);
}
private OntModel model(Statement... stmts) {
OntModel m = ModelFactory.createOntologyModel(OWL_MEM);
m.add(Arrays.asList(stmts));
return m;
}
private OntModel includeDocInfo(OntModel m) {
List<Statement> list = new ArrayList<>();
list.add(dataStmt(DOCUMENT_URI, LABEL, "RDF description of "
+ INDIVIDUAL_URI));
list.add(dataStmt(DOCUMENT_URI, DATE_DATA_PROPERTY, "bogusTimeStamp"));
list.add(objectStmt(DOCUMENT_URI, RDF_TYPE,
"http://xmlns.com/foaf/0.1/Document"));
list.add(objectStmt(DOCUMENT_URI,
"http://purl.org/dc/elements/1.1/publisher",
"http://vivo.mydomain.edu"));
list.add(objectStmt(DOCUMENT_URI,
"http://purl.org/dc/elements/1.1/rights",
"http://vivo.mydomain.edu/termsOfUse"));
m.add(list);
return m;
}
private void policyUnrestricted() {
ServletPolicyList.addPolicy(ctx, new UnrestrictedPolicy());
}
private void policyRestrictByPredicate(String... predicateUris) {
ServletPolicyList.addPolicy(ctx, new RestrictionsPolicy(predicateUris,
new String[0]));
}
private void policyRestrictByClass(String... classUris) {
ServletPolicyList.addPolicy(ctx, new RestrictionsPolicy(new String[0],
classUris));
}
private void filterAndCompare(String message) {
setupIndividualRdfAssembler();
actualLod = runGetRdf();
List<Statement> missing = modelDifference(expectedLod, actualLod);
List<Statement> extra = modelDifference(actualLod, expectedLod);
removeMatchingDateStatements(missing, extra);
if (missing.isEmpty() && extra.isEmpty()) {
return;
}
failComparison(message, missing, extra);
}
private void setupIndividualRdfAssembler() {
rdfService = new RDFServiceModel(rawRdf);
req.setAttribute("rdfService", rdfService);
req.setAttribute("unfilteredRDFService", rdfService);
vreq = new VitroRequest(req);
ira = new IndividualRdfAssembler(vreq, INDIVIDUAL_URI, ContentType.N3);
}
private OntModel runGetRdf() {
try {
Method m = IndividualRdfAssembler.class.getDeclaredMethod("getRdf");
m.setAccessible(true);
return (OntModel) m.invoke(ira);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void failComparison(String message, List<Statement> missing,
List<Statement> extra) {
StringWriter sw = new StringWriter();
PrintWriter w = new PrintWriter(sw);
w.println(message);
writeStatementList("Missing statements:", missing, w);
writeStatementList("Extra statements:", extra, w);
System.err.print(sw.toString());
fail(sw.toString());
}
private void writeStatementList(String label, List<Statement> list,
PrintWriter w) {
if (list.isEmpty()) {
return;
}
w.println(label);
for (Statement s : list) {
w.println(" " + s);
}
}
private List<Statement> modelDifference(OntModel first, OntModel second) {
OntModel temp = ModelFactory.createOntologyModel(OWL_MEM);
temp.add(first);
temp.remove(statementList(second));
return statementList(temp);
}
@SuppressWarnings("unchecked")
private List<Statement> statementList(OntModel m) {
return IteratorUtils.toList(m.listStatements());
}
/**
* If two date statements have the same subject, then lets assume that their
* dates are the same. In fact, the actual date statement will have the
* current date/time.
*/
private void removeMatchingDateStatements(List<Statement> list1,
List<Statement> list2) {
for (Iterator<Statement> it1 = list1.iterator(); it1.hasNext();) {
Statement stmt1 = it1.next();
String subject1 = stmt1.getSubject().getURI();
String predicate1 = stmt1.getPredicate().getURI();
if (DATE_DATA_PROPERTY.equals(predicate1)) {
for (Iterator<Statement> it2 = list2.iterator(); it2.hasNext();) {
Statement stmt2 = it2.next();
String subject2 = stmt2.getSubject().getURI();
String predicate2 = stmt2.getPredicate().getURI();
if (predicate1.equals(predicate2)
&& subject1.equals(subject2)) {
it1.remove();
it2.remove();
}
}
}
}
}
// ----------------------------------------------------------------------
// Helper class
// ----------------------------------------------------------------------
private abstract static class AbstractTestPolicy implements PolicyIface {
@Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
RequestedAction whatToAuth) {
if (whatToAuth instanceof PublishDataPropertyStatement) {
return filterDataProperty((PublishDataPropertyStatement) whatToAuth);
} else if (whatToAuth instanceof PublishObjectPropertyStatement) {
return filterObjectProperty((PublishObjectPropertyStatement) whatToAuth);
} else {
return inconclusive("Bogus");
}
}
private PolicyDecision filterDataProperty(
PublishDataPropertyStatement pdps) {
return filter(pdps.getPredicateUri(), null);
}
private PolicyDecision filterObjectProperty(
PublishObjectPropertyStatement pops) {
String propertyUri = pops.getPredicateUri();
if (VitroVocabulary.RDF_TYPE.equals(propertyUri)) {
return filter(propertyUri, pops.getObjectUri());
} else {
return filter(propertyUri, null);
}
}
protected abstract PolicyDecision filter(String propertyUri,
String classUri);
protected BasicPolicyDecision authorized(String message) {
return new BasicPolicyDecision(Authorization.AUTHORIZED, message);
}
protected BasicPolicyDecision inconclusive(String message) {
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message);
}
}
private static class UnrestrictedPolicy extends AbstractTestPolicy {
@Override
protected PolicyDecision filter(String propertyUri, String classUri) {
return authorized("Totally unrestricted");
}
}
private static class RestrictionsPolicy extends AbstractTestPolicy {
private final List<String> filteredPropertyUris;
private final List<String> filteredClassUris;
public RestrictionsPolicy(String[] filteredPropertyUris,
String[] filteredClassUris) {
this.filteredPropertyUris = Arrays.asList(filteredPropertyUris);
this.filteredClassUris = Arrays.asList(filteredClassUris);
}
@Override
protected PolicyDecision filter(String propertyUri, String classUri) {
if ((propertyUri != null)
&& filteredPropertyUris.contains(propertyUri)) {
return inconclusive("Filtered property: " + propertyUri);
}
if ((classUri != null) && filteredClassUris.contains(classUri)) {
return inconclusive("Filtered class: " + classUri);
}
return authorized("Passed the filters: " + propertyUri + ","
+ classUri);
}
}
}

View file

@ -0,0 +1,163 @@
@prefix ocresd: <http://purl.org/net/OCRe/study_design.owl#> .
@prefix geo: <http://aims.fao.org/aos/geopolitical.owl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix scires: <http://vivoweb.org/ontology/scientific-research#> .
@prefix cito: <http://purl.org/spar/cito/> .
@prefix fabio: <http://purl.org/spar/fabio/> .
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
@prefix obo: <http://purl.obolibrary.org/obo/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ocrer: <http://purl.org/net/OCRe/research.owl#> .
@prefix vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> .
@prefix event: <http://purl.org/NET/c4dm/event.owl#> .
@prefix bibo: <http://purl.org/ontology/bibo/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix c4o: <http://purl.org/spar/c4o/> .
@prefix vitro-public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix vivo: <http://vivoweb.org/ontology/core#> .
<http://vivo.mydomain.edu/individual/n3639>
a vivo:FacultyMember ,
foaf:Person ,
owl:Thing ,
foaf:Agent ,
obo:BFO_0000002 ,
obo:BFO_0000001 ,
obo:BFO_0000004 ;
rdfs:label "Baker, Able "^^xsd:string ;
obo:ARG_2000028 <http://vivo.mydomain.edu/individual/n3972> ;
obo:RO_0000053 <http://vivo.mydomain.edu/individual/n475> ,
<http://vivo.mydomain.edu/individual/n7850> ;
vitro:mostSpecificType
vivo:FacultyMember ;
vivo:freetextKeyword
"Potrezebie, Chattanooga" ;
vivo:hasCollaborator
<http://vivo.mydomain.edu/individual/n7429> ;
vivo:hasResearchArea
<http://www.eionet.europa.eu/gemet/concept/971> ,
<http://vivo.mydomain.edu/individual/n2158> ;
vivo:overview "Just an ordinary chap of simple means and simple desires." ;
vivo:relatedBy <http://vivo.mydomain.edu/individual/n3401> ,
<http://vivo.mydomain.edu/individual/n5855> ,
<http://vivo.mydomain.edu/individual/n2421> ;
vivo:researchOverview
"Whatever strikes my fancy." ;
vivo:scopusId "abaker" .
<http://vivo.mydomain.edu/individual/n3972>
a vcard:Kind ,
obo:BFO_0000031 ,
owl:Thing ,
obo:ARG_2000379 ,
obo:IAO_0000030 ,
obo:BFO_0000002 ,
obo:BFO_0000001 ,
vcard:Individual ;
obo:ARG_2000029 <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n475>
a owl:Thing ,
obo:BFO_0000023 ,
vivo:InvestigatorRole ,
obo:BFO_0000002 ,
obo:BFO_0000017 ,
vivo:PrincipalInvestigatorRole ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:ResearcherRole ;
obo:RO_0000052 <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n7850>
a owl:Thing ,
obo:BFO_0000023 ,
obo:BFO_0000017 ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:LeaderRole ;
rdfs:label "Lead Guitarist"^^xsd:string ;
obo:RO_0000052 <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n7429>
a foaf:Person ,
vivo:FacultyMember ,
foaf:Agent ,
owl:Thing ,
obo:BFO_0000002 ,
obo:BFO_0000001 ,
obo:BFO_0000004 ;
rdfs:label "Yum, Yum " .
<http://www.eionet.europa.eu/gemet/concept/971>
a owl:Thing ,
<http://vivo.mydomain.edu/individual/n7793> ,
skos:Concept ;
rdfs:label "botany"^^xsd:string ;
vivo:researchAreaOf <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n2158>
a owl:Thing ,
skos:Concept ;
rdfs:label "What a concept!"^^xsd:string ;
vivo:researchAreaOf <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n3401>
a owl:Thing ,
vivo:Relationship ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:Authorship ;
vivo:relates <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n5855>
a vivo:FacultyPosition ,
owl:Thing ,
vivo:Relationship ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:Position ;
rdfs:label "Functionary"^^xsd:string ;
vivo:relates <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n2421>
a owl:Thing ,
vivo:Relationship ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:Grant ;
rdfs:label "Cosmogenic Lassitude in Plegmatic Axolotls" ;
vivo:relates <http://vivo.mydomain.edu/individual/n3639> .
obo:BFO_0000001
a owl:Class ;
rdfs:label "Entity" .
obo:BFO_0000002
a owl:Class ;
rdfs:label "Continuant" .
obo:BFO_0000004
a owl:Class ;
rdfs:label "Independent Continuant"@en-US .
vivo:FacultyMember
a owl:Class ;
rdfs:label "Faculty Member"@en-US .
foaf:Person
a owl:Class ;
rdfs:label "Person"@en-US .
foaf:Agent
a owl:Class ;
rdfs:label "Agent"@en-US .
owl:Thing
a owl:Class .

View file

@ -0,0 +1,171 @@
@prefix ocresd: <http://purl.org/net/OCRe/study_design.owl#> .
@prefix geo: <http://aims.fao.org/aos/geopolitical.owl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix scires: <http://vivoweb.org/ontology/scientific-research#> .
@prefix cito: <http://purl.org/spar/cito/> .
@prefix fabio: <http://purl.org/spar/fabio/> .
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
@prefix obo: <http://purl.obolibrary.org/obo/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ocrer: <http://purl.org/net/OCRe/research.owl#> .
@prefix vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> .
@prefix event: <http://purl.org/NET/c4dm/event.owl#> .
@prefix bibo: <http://purl.org/ontology/bibo/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix c4o: <http://purl.org/spar/c4o/> .
@prefix vitro-public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix vivo: <http://vivoweb.org/ontology/core#> .
<http://vivo.mydomain.edu/individual/n3639>
a vivo:FacultyMember ,
foaf:Person ,
owl:Thing ,
foaf:Agent ,
obo:BFO_0000002 ,
obo:BFO_0000001 ,
obo:BFO_0000004 ;
rdfs:label "Baker, Able "^^xsd:string ;
obo:ARG_2000028 <http://vivo.mydomain.edu/individual/n3972> ;
obo:RO_0000053 <http://vivo.mydomain.edu/individual/n475> ,
<http://vivo.mydomain.edu/individual/n7850> ;
vitro:mostSpecificType
vivo:FacultyMember ;
vivo:freetextKeyword
"Potrezebie, Chattanooga" ;
vivo:hasCollaborator
<http://vivo.mydomain.edu/individual/n7429> ;
vivo:hasResearchArea
<http://www.eionet.europa.eu/gemet/concept/971> ,
<http://vivo.mydomain.edu/individual/n2158> ;
vivo:overview "Just an ordinary chap of simple means and simple desires." ;
vivo:relatedBy <http://vivo.mydomain.edu/individual/n3401> ,
<http://vivo.mydomain.edu/individual/n5855> ,
<http://vivo.mydomain.edu/individual/n2421> ;
vivo:researchOverview
"Whatever strikes my fancy." ;
vivo:scopusId "abaker" .
<http://vivo.mydomain.edu/individual/n3972>
a vcard:Kind ,
obo:BFO_0000031 ,
owl:Thing ,
obo:ARG_2000379 ,
obo:IAO_0000030 ,
obo:BFO_0000002 ,
obo:BFO_0000001 ,
vcard:Individual ;
obo:ARG_2000029 <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n475>
a owl:Thing ,
obo:BFO_0000023 ,
vivo:InvestigatorRole ,
obo:BFO_0000002 ,
obo:BFO_0000017 ,
vivo:PrincipalInvestigatorRole ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:ResearcherRole ;
obo:RO_0000052 <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n7850>
a owl:Thing ,
obo:BFO_0000023 ,
obo:BFO_0000017 ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:LeaderRole ;
rdfs:label "Lead Guitarist"^^xsd:string ;
obo:RO_0000052 <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n7429>
a foaf:Person ,
vivo:FacultyMember ,
foaf:Agent ,
owl:Thing ,
obo:BFO_0000002 ,
obo:BFO_0000001 ,
obo:BFO_0000004 ;
rdfs:label "Yum, Yum " .
<http://www.eionet.europa.eu/gemet/concept/971>
a owl:Thing ,
<http://vivo.mydomain.edu/individual/n7793> ,
skos:Concept ;
rdfs:label "botany"^^xsd:string ;
vivo:researchAreaOf <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n2158>
a owl:Thing ,
skos:Concept ;
rdfs:label "What a concept!"^^xsd:string ;
vivo:researchAreaOf <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n3401>
a owl:Thing ,
vivo:Relationship ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:Authorship ;
vivo:relates <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n5855>
a vivo:FacultyPosition ,
owl:Thing ,
vivo:Relationship ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:Position ;
rdfs:label "Functionary"^^xsd:string ;
vivo:relates <http://vivo.mydomain.edu/individual/n3639> .
<http://vivo.mydomain.edu/individual/n2421>
a owl:Thing ,
vivo:Relationship ,
obo:BFO_0000002 ,
obo:BFO_0000020 ,
obo:BFO_0000001 ,
vivo:Grant ;
rdfs:label "Cosmogenic Lassitude in Plegmatic Axolotls" ;
vivo:relates <http://vivo.mydomain.edu/individual/n3639> .
obo:BFO_0000001
a owl:Class ;
rdfs:label "Entity" .
obo:BFO_0000002
a owl:Class ;
rdfs:label "Continuant" .
obo:BFO_0000004
a owl:Class ;
rdfs:label "Independent Continuant"@en-US .
vivo:FacultyMember
a owl:Class ;
rdfs:label "Faculty Member"@en-US .
foaf:Person
a owl:Class ;
rdfs:label "Person"@en-US .
foaf:Agent
a owl:Class ;
rdfs:label "Agent"@en-US .
owl:Thing
a owl:Class .
<http://vivo.mydomain.edu/individual/n3639/n3639.n3>
a foaf:Document ;
rdfs:label "RDF description of Baker, Able - http://vivo.mydomain.edu/individual/n3639" ;
<http://purl.org/dc/elements/1.1/date> "2014-03-10T11:08:39"^^xsd:dateTime ;
<http://purl.org/dc/elements/1.1/publisher> <http://vivo.mydomain.edu> ;
<http://purl.org/dc/elements/1.1/rights> <http://vivo.mydomain.edu/termsOfUse> .

View file

@ -75,6 +75,7 @@ public class DataPropertyDaoJenaTest extends AbstractTestClass {
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.DISPLAY_LIMIT), subModel.createTypedLiteral(5));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#curator"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#selfEditor"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#editor"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_INPROPERTYGROUPANNOT), subModel.createResource("http://thisIsTheInPropertyGroupURI"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_CUSTOMENTRYFORMANNOT), subModel.createResource("http://thisIsTheCustomFormEntryURI"));

View file

@ -149,6 +149,7 @@ public class ObjectPropertyDaoJenaTest extends AbstractTestClass {
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_OBJECTINDIVIDUALSORTPROPERTY), subModel.createResource("http://thisIsTheObjectIndividualSortProperty"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#curator"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#selfEditor"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#editor"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_INPROPERTYGROUPANNOT), subModel.createResource("http://thisIsTheInPropertyGroupURI"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_CUSTOMENTRYFORMANNOT), subModel.createResource("http://thisIsTheCustomFormEntryURI"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_SELECTFROMEXISTINGANNOT), subModel.createTypedLiteral(true));

View file

@ -70,6 +70,7 @@ public class VClassDaoTest {
class1.setPropertyValue(subModel.createProperty(VitroVocabulary.SEARCH_BOOST_ANNOT), subModel.createTypedLiteral(2.4f));
class1.setPropertyValue(subModel.createProperty(VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#curator"));
class1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#selfEditor"));
class1.setPropertyValue(subModel.createProperty(VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#editor"));
class1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_CUSTOMENTRYFORMANNOT), subModel.createTypedLiteral("this is the custom entry form annotation"));
class1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_CUSTOMDISPLAYVIEWANNOT), subModel.createTypedLiteral("this is the custom display view annotation"));
class1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_CUSTOMSHORTVIEWANNOT), subModel.createTypedLiteral("this is the custom short view annotation"));

View file

@ -92,6 +92,7 @@ public class VClassJenaTest {
class1.setPropertyValue(ontModel.createProperty(VitroVocabulary.SEARCH_BOOST_ANNOT), ontModel.createTypedLiteral(2.4f));
class1.setPropertyValue(ontModel.createProperty(VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT), ontModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#curator"));
class1.setPropertyValue(ontModel.createProperty(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT), ontModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#selfEditor"));
class1.setPropertyValue(ontModel.createProperty(VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT), ontModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#editor"));
class1.setPropertyValue(ontModel.createProperty(VitroVocabulary.PROPERTY_CUSTOMENTRYFORMANNOT), ontModel.createTypedLiteral("this is the custom entry form annotation"));
class1.setPropertyValue(ontModel.createProperty(VitroVocabulary.PROPERTY_CUSTOMDISPLAYVIEWANNOT), ontModel.createTypedLiteral("this is the custom display view annotation"));
class1.setPropertyValue(ontModel.createProperty(VitroVocabulary.PROPERTY_CUSTOMSHORTVIEWANNOT), ontModel.createTypedLiteral("this is the custom short view annotation"));
@ -126,6 +127,7 @@ public class VClassJenaTest {
Assert.assertEquals(vClassJena.getSearchBoost(), vClass.getSearchBoost());
Assert.assertEquals(vClassJena.getHiddenFromDisplayBelowRoleLevel(), vClass.getHiddenFromDisplayBelowRoleLevel());
Assert.assertEquals(vClassJena.getProhibitedFromUpdateBelowRoleLevel(), vClass.getProhibitedFromUpdateBelowRoleLevel());
Assert.assertEquals(vClassJena.getHiddenFromPublishBelowRoleLevel(), vClass.getHiddenFromPublishBelowRoleLevel());
}
@ -156,6 +158,7 @@ public class VClassJenaTest {
protected AnnotationProperty LOCAL_PROPERTY_CUSTOMSEARCHVIEWANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_CUSTOMSEARCHVIEWANNOT);
protected AnnotationProperty LOCAL_HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT = _constModel.createAnnotationProperty(VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT);
protected AnnotationProperty LOCAL_PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT);
protected AnnotationProperty LOCAL_HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT = _constModel.createAnnotationProperty(VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT);
protected AnnotationProperty LOCAL_IN_CLASSGROUP = _constModel.createAnnotationProperty(VitroVocabulary.IN_CLASSGROUP);
@ -234,6 +237,25 @@ public class VClassJenaTest {
}
vcw.setProhibitedFromUpdateBelowRoleLevel(prohibitedRoleLevel);//this might get set to null
//There might be multiple LOCAL_HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT properties, only use the highest
it = cls.listProperties(LOCAL_HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT);
BaseResourceBean.RoleLevel publishRoleLevel = null;
while( it.hasNext() ){
Statement stmt = it.nextStatement();
RDFNode obj;
if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){
Resource res = (Resource)obj.as(Resource.class);
if( res != null && res.getURI() != null ){
BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI());
if( roleFromModel != null &&
(publishRoleLevel == null || roleFromModel.compareTo(publishRoleLevel) > 0 )){
publishRoleLevel = roleFromModel;
}
}
}
}
vcw.setHiddenFromPublishBelowRoleLevel(publishRoleLevel);//this might get set to null
} finally {
cls.getModel().leaveCriticalSection();
}

View file

@ -8,8 +8,6 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.sdb.util.Pair;
import com.hp.hpl.jena.vocabulary.OWL;
@ -27,7 +25,6 @@ public class PropertyRestrictionPolicyHelperStub extends
return getInstance(null, null);
}
/** Prohibit some namespaces. */
public static PropertyRestrictionPolicyHelperStub getInstance(
String[] restrictedNamespaces) {
@ -45,29 +42,27 @@ public class PropertyRestrictionPolicyHelperStub extends
namespaceSet.addAll(Arrays.asList(restrictedNamespaces));
}
Map<Pair<String, Pair<String,String>>, RoleLevel> thresholdMap = new HashMap<
Pair<String, Pair<String,String>>, RoleLevel>();
Map<Pair<String, Pair<String, String>>, RoleLevel> thresholdMap = new HashMap<>();
if (restrictedProperties != null) {
for (String prop : restrictedProperties) {
thresholdMap.put(
new Pair<String, Pair<String, String>>(
OWL.Thing.getURI(), new Pair<String, String>(
prop, OWL.Thing.getURI())),
RoleLevel.NOBODY);
thresholdMap.put(new Pair<String, Pair<String, String>>(
OWL.Thing.getURI(), new Pair<String, String>(prop,
OWL.Thing.getURI())), RoleLevel.NOBODY);
}
}
return new PropertyRestrictionPolicyHelperStub(namespaceSet, null,
null, thresholdMap);
null, thresholdMap, null);
}
private PropertyRestrictionPolicyHelperStub(
Set<String> modifyRestrictedNamespaces,
Set<String> modifyPermittedExceptions,
Map<Pair<String, Pair<String,String>>, RoleLevel> displayThresholds,
Map<Pair<String, Pair<String,String>>, RoleLevel> modifyThresholds) {
Map<Pair<String, Pair<String, String>>, RoleLevel> displayThresholds,
Map<Pair<String, Pair<String, String>>, RoleLevel> modifyThresholds,
Map<Pair<String, Pair<String, String>>, RoleLevel> publishThresholds) {
super(modifyRestrictedNamespaces, modifyPermittedExceptions,
displayThresholds, modifyThresholds, ModelFactory.createDefaultModel());
displayThresholds, modifyThresholds, publishThresholds);
}
}

View file

@ -84,12 +84,12 @@ public class IndividualStub implements Individual {
@Override
public String getLabel() {
return getName();
return getName();
}
@Override
public String getPickListName() {
return getName();
return getName();
}
@Override
@ -146,7 +146,6 @@ public class IndividualStub implements Individual {
return null;
}
@Override
public boolean isVClass(String vclassUri) {
for (VClass vc : vClasses) {
@ -263,6 +262,24 @@ public class IndividualStub implements Individual {
"ResourceBean.setProhibitedFromUpdateBelowRoleLevelUsingRoleUri() not implemented.");
}
@Override
public RoleLevel getHiddenFromPublishBelowRoleLevel() {
throw new RuntimeException(
"IndividualStub.getHiddenFromPublishBelowRoleLevel() not implemented.");
}
@Override
public void setHiddenFromPublishBelowRoleLevel(RoleLevel eR) {
throw new RuntimeException(
"IndividualStub.setHiddenFromPublishBelowRoleLevel() not implemented.");
}
@Override
public void setHiddenFromPublishBelowRoleLevelUsingRoleUri(String roleUri) {
throw new RuntimeException(
"IndividualStub.setHiddenFromPublishBelowRoleLevelUsingRoleUri() not implemented.");
}
@Override
public int compareTo(Individual o) {
throw new RuntimeException(
@ -271,7 +288,8 @@ public class IndividualStub implements Individual {
@Override
public List<String> getMostSpecificTypeURIs() {
throw new RuntimeException("Individual.getMostSpecificTypeURIs() not implemented.");
throw new RuntimeException(
"Individual.getMostSpecificTypeURIs() not implemented.");
}
@Override

View file

@ -125,13 +125,23 @@
<tr class="editformcell">
<td valign="top" colspan="2">
<b>Display level</b><br/>
<select name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"><form:option name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"/></select><br/>
<i>specify least restrictive level allowed</i><br/>
<select name="HiddenFromDisplayBelowRoleLevelUsingRoleUri">
<form:option name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"/>
</select>
</td>
<td valign="top" colspan="2">
<b>Update level</b><br />
<select name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"><form:option name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"/></select><br/>
<i>specify least restrictive level allowed</i><br/>
<select name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri">
<form:option name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"/>
</select>
</td>
</tr>
<tr class="editformcell">
<td valign="top" colspan="2">
<b>Publish level</b><br/>
<select name="HiddenFromPublishBelowRoleLevelUsingRoleUri">
<form:option name="HiddenFromPublishBelowRoleLevelUsingRoleUri"/>
</select>
</td>
</tr>
<tr><td colspan="5"><hr class="formDivider"/></td></tr>

View file

@ -190,13 +190,23 @@
<tr class="editformcell">
<td valign="top" colspan="2">
<b>Display level</b><br />
<select name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"><form:option name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"/></select><br/>
<i>specify least restrictive level allowed</i>
<select name="HiddenFromDisplayBelowRoleLevelUsingRoleUri">
<form:option name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"/>
</select>
</td>
<td valign="top" colspan="2">
<b>Update level</b><br/>
<select name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"><form:option name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"/></select><br/>
<i>specify least restrictive level allowed</i>
<select name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri">
<form:option name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"/>
</select>
</td>
</tr>
<tr class="editformcell">
<td valign="top" colspan="2">
<b>Publish level</b><br />
<select name="HiddenFromPublishBelowRoleLevelUsingRoleUri">
<form:option name="HiddenFromPublishBelowRoleLevelUsingRoleUri"/>
</select>
</td>
</tr>
<tr><td colspan="5"><hr class="formDivider"/></td></tr>

View file

@ -86,13 +86,23 @@
<tr class="editformcell">
<td valign="bottom" colspan="1">
<b>Display level</b><br/>
<select name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"><form:option name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"/></select><br/>
<i>specify least restrictive level allowed</i><br/>
<select name="HiddenFromDisplayBelowRoleLevelUsingRoleUri">
<form:option name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"/>
</select>
</td>
<td valign="bottom" colspan="1">
<b>Update level</b><br/>
<select name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"><form:option name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"/></select><br/>
<i>specify least restrictive level allowed</i><br />
<select name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri">
<form:option name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"/>
</select>
</td>
</tr>
<tr class="editformcell">
<td valign="bottom" colspan="1">
<b>Publish level</b><br/>
<select name="HiddenFromPublishBelowRoleLevelUsingRoleUri">
<form:option name="HiddenFromPublishBelowRoleLevelUsingRoleUri"/>
</select>
</td>
</tr>
<tr><td colspan="4"><hr class="formDivider"/></td></tr>

View file

@ -238,7 +238,8 @@ name will be used as the label. -->
(<span>${property.type?lower_case}</span> property);
order in group: <span>${verboseDisplay.displayRank};</span>
display level: <span>${verboseDisplay.displayLevel};</span>
update level: <span>${verboseDisplay.updateLevel}</span>
update level: <span>${verboseDisplay.updateLevel};</span>
publish level: <span>${verboseDisplay.publishLevel}</span>
</section>
</#if>
</#macro>