merging trunk changes from r9590:9646 into dev branch

This commit is contained in:
brianjlowe 2012-04-11 17:16:36 +00:00
commit 65c0898997
54 changed files with 2184 additions and 1045 deletions

View file

@ -1,110 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyList;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
/**
* Tests and gives info about the auth sysetm
*
* @author bdc34
*
*/
public class AuthTestController extends VitroHttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res )
throws IOException, ServletException{
super.doGet(req,res);
IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(req);
ServletOutputStream out = res.getOutputStream();
listIdentifiers(out,ids);
checkAuths(out,ids, getServletContext());
}
private void listIdentifiers(ServletOutputStream out, IdentifierBundle ids) throws IOException{
out.println("<h1>Identifiers: </h1>");
out.println("<table>");
for( Object obj: ids){
if( obj == null ){
out.println("<tr>obj was null</tr>");
continue;
}
out.println("<tr>");
out.println("<td>"+obj.getClass().getName() + "</td>");
out.println("<td>"+obj.toString() + "</td>");
out.println("</tr>");
}
out.println("</table>");
}
private void checkAuths(ServletOutputStream out, IdentifierBundle ids, ServletContext servletContext)
throws IOException{
PolicyList policy = ServletPolicyList.getPolicies(servletContext);
out.println("<h1>Authorization tests:</h1>");
if (policy.isEmpty()) {
out.println("No Policy objects found in ServletContext. ");
}
out.println("<table>");
for(RequestedAction action: actions){
out.println("<tr><td>"+action.getClass().getName()+"</td>");
try {
PolicyDecision pd = policy.isAuthorized(ids, action);
if( pd == null)
out.println("<td>ERROR: PolicyDecision was null</td><td/>");
else{
out.println("<td>"+ pd.getAuthorized() +"</td>");
out.println("<td>"+ pd.getMessage() +"</td>");
}
} catch (Exception e) {
out.println("<td> exception: " + e + "</td>");
e.printStackTrace();
}
}
out.println("</table>");
}
private static List<RequestedAction> actions = new ArrayList<RequestedAction>();
static{
actions.add(new AddDataPropStmt("http://some.non.existing.resource", "http://some.non.existing.dataproperty", "bogus value", null, null));
actions.add(new AddObjectPropStmt("http://vivo.library.cornell.edu/abox#entity11821","vitro:headOf","http://vivo.library.cornell.edu/abox#entity1"));
actions.add(new AddObjectPropStmt("http://vivo.library.cornell.edu/abox#entity123","vitro:headOf","http://vivo.library.cornell.edu/abox#entity1"));
// actions.add(new AddResource("http://bogus.REsourceType.uri","http://bogus.uri"));
// actions.add(new DropObjectPropStmt());
// actions.add(new DefineObjectProperty());
// actions.add(new DefineDataProperty());
// actions.add(new RemoveOwlClass());
// actions.add(new CreateOwlClass());
//
// actions.add(new AddNewUser());
// actions.add(new LoadOntology());
// actions.add(new RebuildTextIndex());
// actions.add(new RemoveUser());
// actions.add(new ServerStatus());
// actions.add(new UpdateTextIndex());
// actions.add(new UploadFile("http://uri.of.entity.to.associate/uploaded/file/with","http://uri.of.association.property"));
}
}

View file

@ -9,8 +9,8 @@ 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.propstmt.AbstractDataPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
/**
@ -55,10 +55,10 @@ public class EditByRolePermission extends Permission {
public boolean isAuthorized(RequestedAction whatToAuth) {
boolean result;
if (whatToAuth instanceof AbstractDataPropertyAction) {
result = isAuthorized((AbstractDataPropertyAction) whatToAuth);
} else if (whatToAuth instanceof AbstractObjectPropertyAction) {
result = isAuthorized((AbstractObjectPropertyAction) whatToAuth);
if (whatToAuth instanceof AbstractDataPropertyStatementAction) {
result = isAuthorized((AbstractDataPropertyStatementAction) whatToAuth);
} else if (whatToAuth instanceof AbstractObjectPropertyStatementAction) {
result = isAuthorized((AbstractObjectPropertyStatementAction) whatToAuth);
} else {
result = false;
}
@ -76,7 +76,7 @@ public class EditByRolePermission extends Permission {
* The user may add, edit, or delete this data property if they are allowed
* to modify its subject and its predicate.
*/
private boolean isAuthorized(AbstractDataPropertyAction action) {
private boolean isAuthorized(AbstractDataPropertyStatementAction action) {
String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri();
return canModifyResource(subjectUri)
@ -87,10 +87,10 @@ public class EditByRolePermission extends Permission {
* The user may add, edit, or delete this data property if they are allowed
* to modify its subject, its predicate, and its object.
*/
private boolean isAuthorized(AbstractObjectPropertyAction action) {
String subjectUri = action.getUriOfSubject();
String predicateUri = action.getUriOfPredicate();
String objectUri = action.getUriOfObject();
private boolean isAuthorized(AbstractObjectPropertyStatementAction action) {
String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri();
String objectUri = action.getObjectUri();
return canModifyResource(subjectUri)
&& canModifyPredicate(predicateUri)
&& canModifyResource(objectUri);

View file

@ -145,6 +145,11 @@ public class PermissionRegistry {
}
}
/**
* There is no DisplayByRolePermission for self-editors. They get the
* same rights as PUBLIC. Other permissions give them their self-editing
* privileges.
*/
private Collection<Permission> createDisplayByRolePermissions(
ServletContext ctx) {
List<Permission> list = new ArrayList<Permission>();
@ -159,13 +164,20 @@ public class PermissionRegistry {
return list;
}
/**
* There is no EditByRolePermission for PUBLIC or for self-editors. A
* property may be given an edit-level of "PUBLIC", but that may also
* simply be the default assigned to it when editing, and we don't want
* to recognize that.
*
* Other permissions give self-editors their editing privileges.
*/
private Collection<Permission> createEditByRolePermissions(
ServletContext ctx) {
List<Permission> list = new ArrayList<Permission>();
list.add(new EditByRolePermission("Admin", RoleLevel.DB_ADMIN, ctx));
list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR, ctx));
list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR, ctx));
list.add(new EditByRolePermission("Public", RoleLevel.PUBLIC, ctx));
return list;
}

View file

@ -7,7 +7,10 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
@ -19,10 +22,10 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement;
/**
* A collection of static methods to help determine whether requested actions
@ -60,35 +63,14 @@ public class PolicyHelper {
}
/**
* Do the current policies authorize the current user to add all of the
* statements in this model?
*/
public static boolean isAuthorizedToAdd(HttpServletRequest req, Model model) {
if ((req == null) || (model == null)) {
return false;
}
StmtIterator stmts = model.listStatements();
try {
while (stmts.hasNext()) {
if (!isAuthorizedToAdd(req, stmts.next())) {
return false;
}
}
return true;
} finally {
stmts.close();
}
}
/**
* Do the current policies authorize the current user to add this statement?
* Do the current policies authorize the current user to add this statement
* to this model?
*
* The statement is expected to be fully-populated, with no null fields.
*/
public static boolean isAuthorizedToAdd(HttpServletRequest req,
Statement stmt) {
if ((req == null) || (stmt == null)) {
Statement stmt, OntModel modelToBeModified) {
if ((req == null) || (stmt == null) || (modelToBeModified == null)) {
return false;
}
@ -101,46 +83,25 @@ public class PolicyHelper {
RequestedAction action;
if (objectNode.isResource()) {
action = new AddObjectPropStmt(subject.getURI(),
predicate.getURI(), objectNode.asResource().getURI());
action = new AddObjectPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI(), objectNode
.asResource().getURI());
} else {
action = new AddDataPropStmt(subject.getURI(), predicate.getURI(),
objectNode.asLiteral());
action = new AddDataPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI());
}
return isAuthorizedForActions(req, action);
}
/**
* Do the current policies authorize the current user to drop all of the
* statements in this model?
*/
public static boolean isAuthorizedToDrop(HttpServletRequest req, Model model) {
if ((req == null) || (model == null)) {
return false;
}
StmtIterator stmts = model.listStatements();
try {
while (stmts.hasNext()) {
if (!isAuthorizedToDrop(req, stmts.next())) {
return false;
}
}
return true;
} finally {
stmts.close();
}
}
/**
* Do the current policies authorize the current user to drop this
* statement?
* Do the current policies authorize the current user to drop this statement
* from this model?
*
* The statement is expected to be fully-populated, with no null fields.
*/
public static boolean isAuthorizedToDrop(HttpServletRequest req,
Statement stmt) {
if ((req == null) || (stmt == null)) {
Statement stmt, OntModel modelToBeModified) {
if ((req == null) || (stmt == null) || (modelToBeModified == null)) {
return false;
}
@ -153,15 +114,152 @@ public class PolicyHelper {
RequestedAction action;
if (objectNode.isResource()) {
action = new DropObjectPropStmt(subject.getURI(),
predicate.getURI(), objectNode.asResource().getURI());
action = new DropObjectPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI(), objectNode
.asResource().getURI());
} else {
action = new DropDataPropStmt(subject.getURI(), predicate.getURI(),
objectNode.asLiteral());
action = new DropDataPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI());
}
return isAuthorizedForActions(req, action);
}
/**
* Do the current policies authorize the current user to modify this model
* by adding all of the statments in the additions model and dropping all of
* the statements in the retractions model?
*
* This differs from the other calls to "isAuthorized..." because we always
* expect the answer to be true. If the answer is false, it should be logged
* as an error.
*
* Even if a statement fails the test, continue to test the others, so the
* log will contain a full record of all failures. This is no more expensive
* than if all statements succeeded.
*/
public static boolean isAuthorizedAsExpected(HttpServletRequest req,
Model additions, Model retractions, OntModel modelBeingModified) {
if (req == null) {
log.warn("Can't evaluate authorization if req is null");
return false;
}
if (additions == null) {
log.warn("Can't evaluate authorization if additions model is null");
return false;
}
if (retractions == null) {
log.warn("Can't evaluate authorization if retractions model is null");
return false;
}
if (modelBeingModified == null) {
log.warn("Can't evaluate authorization if model being modified is null");
return false;
}
/*
* The naive way to test the additions is to test each statement against
* the JenaOntModel. However, some of the statements may not be
* authorized unless others are added first. The client code should not
* need to know which sequence will be successful. The client code only
* cares that such a sequence does exist.
*
* There are 3 obvious ways to test this, ranging from the most rigorous
* (and most costly) to the least costly (and least rigorous).
*
* 1. Try all sequences to find one that works. First, try to add each
* statement to the modelBeingModified. If any statement succeeds,
* construct a temporary model that joins that statement to the
* modelBeingModified. Now try the remaining statements against that
* temporary model, adding the statement each time we are successful. If
* we eventually find all of the statements authorized, declare success.
* This is logically rigorous, but could become geometrically expensive
* as statements are repeatedly tried against incremented models. O(n!).
*
* 2. Try each statement on the assumption that all of the others have
* already been added. So for each statement we create a temporary
* modeol that joins the other additions to the JenaOntModel. If all
* statements pass this test, declare success. This is logically flawed
* since it is possible that two statements would circularly authorize
* each other, but that neither statement could be added first. However,
* that seems like a small risk, and the algorithm is considerably less
* expensive. O(n).
*
* 3. Try each statement on the assumption that all of the statements
* (including itself) have already been added. If all statements pass
* this test, declare success. This has the additional minor flaw of
* allowing a statement to authorize its own addition, but this seems
* very unlikely. This is about as expensive as choice 2., but much
* simpler to code.
*
* For now, I am going with choice 3.
*/
boolean result = true;
OntModel modelToTestAgainst = ModelFactory
.createOntologyModel(OntModelSpec.OWL_MEM);
modelToTestAgainst.addSubModel(additions);
modelToTestAgainst.addSubModel(modelBeingModified);
StmtIterator addStmts = additions.listStatements();
try {
while (addStmts.hasNext()) {
Statement stmt = addStmts.next();
if (isAuthorizedToAdd(req, stmt, modelToTestAgainst)) {
if (log.isDebugEnabled()) {
log.debug("Last-chance authorization check: "
+ "authorized to add statement: "
+ formatStatement(stmt));
}
} else {
log.warn("Last-chance authorization check reveals not "
+ "authorized to add statement: "
+ formatStatement(stmt));
result = false;
}
}
} finally {
addStmts.close();
}
/*
* For retractions, there is no such conundrum. Assume that all of the
* additions have been added, and check the authorization of each
* retraction.
*/
StmtIterator dropStmts = retractions.listStatements();
try {
while (dropStmts.hasNext()) {
Statement stmt = dropStmts.next();
if (isAuthorizedToDrop(req, stmt, modelToTestAgainst)) {
if (log.isDebugEnabled()) {
log.debug("Last-chance authorization check: "
+ "authorized to drop statement: "
+ formatStatement(stmt));
}
} else {
log.warn("Last-chance authorization check reveals not "
+ "authorized to drop statement: "
+ formatStatement(stmt));
result = false;
}
}
} finally {
dropStmts.close();
}
return result;
}
private static String formatStatement(Statement stmt) {
if (stmt == null) {
return "null statement";
}
return "<" + stmt.getSubject() + "> <" + stmt.getPredicate() + "> <"
+ stmt.getObject() + ">";
}
/**
* No need to instantiate this helper class - all methods are static.
*/

View file

@ -10,9 +10,9 @@ 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.propstmt.AbstractObjectPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
/**
@ -23,19 +23,20 @@ public class RestrictHomeMenuItemEditingPolicy implements PolicyIface {
@Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
RequestedAction whatToAuth) {
if (whatToAuth instanceof EditObjPropStmt) {
return isAuthorized((EditObjPropStmt) whatToAuth);
} else if (whatToAuth instanceof DropObjectPropStmt) {
return isAuthorized((DropObjectPropStmt) whatToAuth);
if (whatToAuth instanceof EditObjectPropertyStatement) {
return isAuthorized((EditObjectPropertyStatement) whatToAuth);
} else if (whatToAuth instanceof DropObjectPropertyStatement) {
return isAuthorized((DropObjectPropertyStatement) whatToAuth);
} else {
return notHandled();
}
}
private PolicyDecision isAuthorized(AbstractObjectPropertyAction whatToAuth) {
if (whatToAuth.getUriOfPredicate()
private PolicyDecision isAuthorized(
AbstractObjectPropertyStatementAction whatToAuth) {
if (whatToAuth.getPredicateUri()
.equals(DisplayVocabulary.HAS_ELEMENT)
&& whatToAuth.getUriOfObject().equals(
&& whatToAuth.getObjectUri().equals(
DisplayVocabulary.HOME_MENU_ITEM)) {
return notAuthorized();
} else {

View file

@ -12,8 +12,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndi
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.propstmt.AbstractDataPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AbstractResourceAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
@ -44,14 +44,14 @@ public class SelfEditingPolicy extends BaseSelfEditingPolicy implements
return inconclusiveDecision("Not self-editing.");
}
if (whatToAuth instanceof AbstractObjectPropertyAction) {
if (whatToAuth instanceof AbstractObjectPropertyStatementAction) {
return isAuthorizedForObjectPropertyAction(userUris,
(AbstractObjectPropertyAction) whatToAuth);
(AbstractObjectPropertyStatementAction) whatToAuth);
}
if (whatToAuth instanceof AbstractDataPropertyAction) {
if (whatToAuth instanceof AbstractDataPropertyStatementAction) {
return isAuthorizedForDataPropertyAction(userUris,
(AbstractDataPropertyAction) whatToAuth);
(AbstractDataPropertyStatementAction) whatToAuth);
}
if (whatToAuth instanceof AbstractResourceAction) {
@ -67,10 +67,10 @@ public class SelfEditingPolicy extends BaseSelfEditingPolicy implements
* about him.
*/
private PolicyDecision isAuthorizedForObjectPropertyAction(
List<String> userUris, AbstractObjectPropertyAction action) {
String subject = action.getUriOfSubject();
String predicate = action.getUriOfPredicate();
String object = action.getUriOfObject();
List<String> userUris, AbstractObjectPropertyStatementAction action) {
String subject = action.getSubjectUri();
String predicate = action.getPredicateUri();
String object = action.getObjectUri();
if (!canModifyResource(subject)) {
return cantModifyResource(subject);
@ -94,7 +94,7 @@ public class SelfEditingPolicy extends BaseSelfEditingPolicy implements
* about him.
*/
private PolicyDecision isAuthorizedForDataPropertyAction(
List<String> userUris, AbstractDataPropertyAction action) {
List<String> userUris, AbstractDataPropertyStatementAction action) {
String subject = action.getSubjectUri();
String predicate = action.getPredicateUri();

View file

@ -46,8 +46,7 @@ public class PropertyRestrictionPolicyHelper {
.getLog(PropertyRestrictionPolicyHelper.class);
private static final Collection<String> PROHIBITED_NAMESPACES = Arrays
.asList(new String[] { VitroVocabulary.vitroURI,
VitroVocabulary.OWL, "" });
.asList(new String[] { VitroVocabulary.vitroURI, "" });
private static final Collection<String> PERMITTED_EXCEPTIONS = Arrays
.asList(new String[] {

View file

@ -2,30 +2,17 @@
package edu.cornell.mannlib.vitro.webapp.auth.policy.specialrelationships;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Selector;
import com.hp.hpl.jena.rdf.model.SimpleSelector;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.auth.policy.BasicPolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.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.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
/**
* A collection of building-block methods so we can code a policy based on the
@ -37,11 +24,9 @@ public abstract class AbstractRelationshipPolicy implements PolicyIface {
.getLog(AbstractRelationshipPolicy.class);
protected final ServletContext ctx;
protected final OntModel model;
public AbstractRelationshipPolicy(ServletContext ctx, OntModel model) {
public AbstractRelationshipPolicy(ServletContext ctx) {
this.ctx = ctx;
this.model = model;
}
protected boolean canModifyResource(String uri) {
@ -54,133 +39,6 @@ public abstract class AbstractRelationshipPolicy implements PolicyIface {
uri, RoleLevel.SELF);
}
protected boolean isResourceOfType(String resourceUri, String typeUri) {
Selector selector = createSelector(resourceUri,
VitroVocabulary.RDF_TYPE, typeUri);
StmtIterator stmts = null;
model.enterCriticalSection(Lock.READ);
try {
stmts = model.listStatements(selector);
if (stmts.hasNext()) {
log.debug("resource '" + resourceUri + "' is of type '"
+ typeUri + "'");
return true;
} else {
log.debug("resource '" + resourceUri + "' is not of type '"
+ typeUri + "'");
return false;
}
} finally {
if (stmts != null) {
stmts.close();
}
model.leaveCriticalSection();
}
}
protected List<String> getObjectsOfProperty(String resourceUri,
String propertyUri) {
List<String> list = new ArrayList<String>();
Selector selector = createSelector(resourceUri, propertyUri, null);
StmtIterator stmts = null;
model.enterCriticalSection(Lock.READ);
try {
stmts = model.listStatements(selector);
while (stmts.hasNext()) {
list.add(stmts.next().getObject().toString());
}
log.debug("Objects of property '" + propertyUri + "' on resource '"
+ resourceUri + "': " + list);
return list;
} finally {
if (stmts != null) {
stmts.close();
}
model.leaveCriticalSection();
}
}
protected List<String> getObjectsOfLinkedProperty(String resourceUri,
String linkUri, String propertyUri) {
List<String> list = new ArrayList<String>();
Selector selector = createSelector(resourceUri, linkUri, null);
StmtIterator stmts = null;
model.enterCriticalSection(Lock.READ);
try {
stmts = model.listStatements(selector);
while (stmts.hasNext()) {
RDFNode objectNode = stmts.next().getObject();
if (objectNode.isResource()) {
log.debug("found authorship for '" + resourceUri + "': "
+ objectNode);
list.addAll(getUrisOfAuthors(objectNode.asResource(),
propertyUri));
}
}
log.debug("Objects of linked properties '" + linkUri + "' ==> '"
+ propertyUri + "' on '" + resourceUri + "': " + list);
return list;
} finally {
if (stmts != null) {
stmts.close();
}
model.leaveCriticalSection();
}
}
/** Note that we must already be in a critical section! */
private List<String> getUrisOfAuthors(Resource authorship,
String propertyUri) {
List<String> list = new ArrayList<String>();
Selector selector = createSelector(authorship, propertyUri, null);
StmtIterator stmts = null;
try {
stmts = model.listStatements(selector);
while (stmts.hasNext()) {
list.add(stmts.next().getObject().toString());
}
return list;
} finally {
if (stmts != null) {
stmts.close();
}
}
}
protected Selector createSelector(String subjectUri, String predicateUri,
String objectUri) {
Resource subject = (subjectUri == null) ? null : model
.getResource(subjectUri);
return createSelector(subject, predicateUri, objectUri);
}
protected Selector createSelector(Resource subject, String predicateUri,
String objectUri) {
Property predicate = (predicateUri == null) ? null : model
.getProperty(predicateUri);
RDFNode object = (objectUri == null) ? null : model
.getResource(objectUri);
return new SimpleSelector(subject, predicate, object);
}
protected boolean anyUrisInCommon(List<String> userUris,
List<String> editorsOrAuthors) {
for (String userUri : userUris) {
if (editorsOrAuthors.contains(userUri)) {
return true;
}
}
return false;
}
protected PolicyDecision cantModifyResource(String uri) {
return inconclusiveDecision("No access to admin resources; cannot modify "
+ uri);
@ -201,10 +59,4 @@ public abstract class AbstractRelationshipPolicy implements PolicyIface {
.getSimpleName() + ": " + message);
}
/** An AUTHORIZED decision with a message like "PolicyClass: message". */
protected PolicyDecision authorizedDecision(String message) {
return new BasicPolicyDecision(Authorization.AUTHORIZED, getClass()
.getSimpleName() + ": " + message);
}
}

View file

@ -0,0 +1,172 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy.specialrelationships;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Selector;
import com.hp.hpl.jena.rdf.model.SimpleSelector;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.auth.policy.BasicPolicyDecision;
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.dao.VitroVocabulary;
/**
* Look for relationships within an OntModel. Types of resources, links between
* resources, and links between resources via a context node.
*
* Also provides some convenience methods for test lists of URIs and for
* creating PolicyDecisions.
*/
public class RelationshipChecker {
private static final Log log = LogFactory.getLog(RelationshipChecker.class);
private final OntModel ontModel;
public RelationshipChecker(OntModel ontModel) {
this.ontModel = ontModel;
}
/**
* Are there any URIs that appear in both of these lists?
*/
public boolean anyUrisInCommon(List<String> list1, List<String> list2) {
List<String> urisInCommon = new ArrayList<String>(list1);
urisInCommon.retainAll(list2);
return !urisInCommon.isEmpty();
}
/**
* Is this resource a member of this type? That is, is there an statement of
* the form: <resourceUri> rdfs:type <typeUri>
*/
public boolean isResourceOfType(String resourceUri, String typeUri) {
Selector selector = createSelector(resourceUri,
VitroVocabulary.RDF_TYPE, typeUri);
StmtIterator stmts = null;
ontModel.enterCriticalSection(Lock.READ);
try {
stmts = ontModel.listStatements(selector);
if (stmts.hasNext()) {
log.debug("resource '" + resourceUri + "' is of type '"
+ typeUri + "'");
return true;
} else {
log.debug("resource '" + resourceUri + "' is not of type '"
+ typeUri + "'");
return false;
}
} finally {
if (stmts != null) {
stmts.close();
}
ontModel.leaveCriticalSection();
}
}
/**
* Get a list of the object URIs that satisfy this statement:
*
* <resourceUri> <propertyUri> <objectUri>
*
* May return an empty list, but never returns null.
*/
public List<String> getObjectsOfProperty(String resourceUri,
String propertyUri) {
List<String> list = new ArrayList<String>();
Selector selector = createSelector(resourceUri, propertyUri, null);
StmtIterator stmts = null;
ontModel.enterCriticalSection(Lock.READ);
try {
stmts = ontModel.listStatements(selector);
while (stmts.hasNext()) {
list.add(stmts.next().getObject().toString());
}
log.debug("Objects of property '" + propertyUri + "' on resource '"
+ resourceUri + "': " + list);
return list;
} finally {
if (stmts != null) {
stmts.close();
}
ontModel.leaveCriticalSection();
}
}
/**
* Get a list of the object URIs that satisfy these statements:
*
* <resourceUri> <linkUri> <contextNodeUri>
*
* <contextNodeUri> <propertyUri> <objectUri>
*
* May return an empty list, but never returns null.
*/
public List<String> getObjectsOfLinkedProperty(String resourceUri,
String linkUri, String propertyUri) {
List<String> list = new ArrayList<String>();
Selector selector = createSelector(resourceUri, linkUri, null);
StmtIterator stmts = null;
ontModel.enterCriticalSection(Lock.READ);
try {
stmts = ontModel.listStatements(selector);
while (stmts.hasNext()) {
RDFNode contextNode = stmts.next().getObject();
if (contextNode.isResource()) {
log.debug("found context node for '" + resourceUri + "': "
+ contextNode);
list.addAll(getObjectsOfProperty(contextNode.asResource()
.getURI(), propertyUri));
}
}
log.debug("Objects of linked properties '" + linkUri + "' ==> '"
+ propertyUri + "' on '" + resourceUri + "': " + list);
return list;
} finally {
if (stmts != null) {
stmts.close();
}
ontModel.leaveCriticalSection();
}
}
public Selector createSelector(String subjectUri, String predicateUri,
String objectUri) {
Resource subject = (subjectUri == null) ? null : ontModel
.getResource(subjectUri);
return createSelector(subject, predicateUri, objectUri);
}
public Selector createSelector(Resource subject, String predicateUri,
String objectUri) {
Property predicate = (predicateUri == null) ? null : ontModel
.getProperty(predicateUri);
RDFNode object = (objectUri == null) ? null : ontModel
.getResource(objectUri);
return new SimpleSelector(subject, predicate, object);
}
/** An AUTHORIZED decision with a message like "PolicyClass: message". */
protected PolicyDecision authorizedDecision(String message) {
return new BasicPolicyDecision(Authorization.AUTHORIZED, getClass()
.getSimpleName() + ": " + message);
}
}

View file

@ -16,4 +16,9 @@ public class DisplayDataProperty extends RequestedAction {
public DataProperty getDataProperty() {
return dataProperty;
}
@Override
public String toString() {
return "DisplayDataProperty[" + dataProperty + "]";
}
}

View file

@ -16,4 +16,9 @@ public class DisplayObjectProperty extends RequestedAction {
public ObjectProperty getObjectProperty() {
return objectProperty;
}
@Override
public String toString() {
return "DisplayObjectProperty[" + objectProperty.getLocalName() + "]";
}
}

View file

@ -1,32 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/**
* A base class for requestion actions that relate to data properties.
*/
public abstract class AbstractDataPropertyAction extends RequestedAction {
private final String subjectUri;
private final String predicateUri;
public AbstractDataPropertyAction(String subjectUri, String predicateUri) {
this.subjectUri = subjectUri;
this.predicateUri = predicateUri;
}
public String getSubjectUri() {
return subjectUri;
}
public String getPredicateUri() {
return predicateUri;
}
@Override
public String toString() {
return getClass().getSimpleName() + ": <" + subjectUri + "> <"
+ predicateUri + ">";
}
}

View file

@ -0,0 +1,52 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
/**
* A base class for requested actions that involve adding, editing, or dropping
* data property statements from a model.
*/
public abstract class AbstractDataPropertyStatementAction extends
AbstractPropertyStatementAction {
private final String subjectUri;
private final String predicateUri;
public AbstractDataPropertyStatementAction(OntModel ontModel,
String subjectUri, String predicateUri) {
super(ontModel);
this.subjectUri = subjectUri;
this.predicateUri = predicateUri;
}
public AbstractDataPropertyStatementAction(OntModel ontModel,
DataPropertyStatement dps) {
super(ontModel);
this.subjectUri = (dps.getIndividual() == null) ? dps
.getIndividualURI() : dps.getIndividual().getURI();
this.predicateUri = dps.getDatapropURI();
}
public String getSubjectUri() {
return subjectUri;
}
@Override
public String getPredicateUri() {
return predicateUri;
}
@Override
public String[] getResourceUris() {
return new String[] {subjectUri};
}
@Override
public String toString() {
return getClass().getSimpleName() + ": <" + subjectUri + "> <"
+ predicateUri + ">";
}
}

View file

@ -1,40 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/**
* A base class for requested actions that involve manipulating an object
* property.
*/
public abstract class AbstractObjectPropertyAction extends RequestedAction {
public final String uriOfSubject;
public final String uriOfPredicate;
public final String uriOfObject;
public AbstractObjectPropertyAction(String uriOfSubject, String uriOfPredicate,
String uriOfObject) {
this.uriOfSubject = uriOfSubject;
this.uriOfPredicate = uriOfPredicate;
this.uriOfObject = uriOfObject;
}
public String getUriOfSubject() {
return uriOfSubject;
}
public String getUriOfPredicate() {
return uriOfPredicate;
}
public String getUriOfObject() {
return uriOfObject;
}
@Override
public String toString() {
return this.getClass().getSimpleName() + ": <" + uriOfSubject + "> <"
+ uriOfPredicate + "> <" + uriOfObject + ">";
}
}

View file

@ -0,0 +1,60 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
/**
* A base class for requested actions that involve adding, editing, or deleting
* object property statements from a model.
*/
public abstract class AbstractObjectPropertyStatementAction extends
AbstractPropertyStatementAction {
private final String subjectUri;
private final String predicateUri;
private final String objectUri;
public AbstractObjectPropertyStatementAction(OntModel ontModel, String subjectUri,
String predicateUri, String objectUri) {
super(ontModel);
this.subjectUri = subjectUri;
this.predicateUri = predicateUri;
this.objectUri = objectUri;
}
public AbstractObjectPropertyStatementAction(OntModel ontModel, ObjectPropertyStatement ops) {
super(ontModel);
this.subjectUri = (ops.getSubject() == null) ? ops.getSubjectURI()
: ops.getSubject().getURI();
this.predicateUri = (ops.getProperty() == null) ? ops.getPropertyURI()
: ops.getProperty().getURI();
this.objectUri = (ops.getObject() == null) ? ops.getObjectURI() : ops
.getObject().getURI();
}
public String getSubjectUri() {
return subjectUri;
}
public String getObjectUri() {
return objectUri;
}
@Override
public String getPredicateUri() {
return predicateUri;
}
@Override
public String[] getResourceUris() {
return new String[] {subjectUri, objectUri};
}
@Override
public String toString() {
return this.getClass().getSimpleName() + ": <" + subjectUri + "> <"
+ predicateUri + "> <" + objectUri + ">";
}
}

View file

@ -0,0 +1,31 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/**
* A base class for requested actions that involve adding, editing, or deleting
* statements from a model.
*/
public abstract class AbstractPropertyStatementAction extends RequestedAction {
private final OntModel ontModel;
public AbstractPropertyStatementAction(OntModel ontModel) {
this.ontModel = ontModel;
}
public OntModel getOntModel() {
return ontModel;
}
/**
* Get the URI of the Resources that are involved in this statement. Those
* are the Subject, and the Object if this is an ObjectProperty request.
*/
public abstract String[] getResourceUris();
public abstract String getPredicateUri();
}

View file

@ -1,38 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.rdf.model.Literal;
/** Should we allow the user to add this DataPropertyStatement? */
public class AddDataPropStmt extends AbstractDataPropertyAction {
protected String data;
protected String dataType;
protected String lang;
public AddDataPropStmt(String subjectUri, String predicateUri, String value, String dataType, String lang) {
super(subjectUri, predicateUri);
this.data= value;
this.dataType = dataType;
this.lang = lang;
}
public AddDataPropStmt(String subjectUri, String predicateUri, Literal literal) {
super(subjectUri, predicateUri);
this.data= literal.getValue().toString();
this.dataType = literal.getDatatypeURI();
this.lang = literal.getLanguage();
}
public String getData() {
return data;
}
public String getDataType() {
return dataType;
}
public String getLang() {
return lang;
}
}

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.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
/**
* Should we allow the user to add this DataPropertyStatement to this model?
*/
public class AddDataPropertyStatement extends
AbstractDataPropertyStatementAction {
public AddDataPropertyStatement(OntModel ontModel, String subjectUri,
String predicateUri) {
super(ontModel, subjectUri, predicateUri);
}
public AddDataPropertyStatement(OntModel ontModel, DataPropertyStatement dps) {
super(ontModel, dps);
}
}

View file

@ -1,11 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
/** Should we allow the user to add this ObjectPropertyStatement? */
public class AddObjectPropStmt extends AbstractObjectPropertyAction {
public AddObjectPropStmt(String uriOfSub, String uriOfPred, String uriOfObj) {
super(uriOfSub, uriOfPred, uriOfObj);
}
}

View file

@ -0,0 +1,23 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
/**
* Should we allow the user to add this ObjectPropertyStatement to this model?
*/
public class AddObjectPropertyStatement extends
AbstractObjectPropertyStatementAction {
public AddObjectPropertyStatement(OntModel ontModel, String uriOfSub,
String uriOfPred, String uriOfObj) {
super(ontModel, uriOfSub, uriOfPred, uriOfObj);
}
public AddObjectPropertyStatement(OntModel ontModel,
ObjectPropertyStatement ops) {
super(ontModel, ops);
}
}

View file

@ -1,41 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
/** Should we allow the user to delete this DataPropertyStatement? */
public class DropDataPropStmt extends AbstractDataPropertyAction {
private final DataPropertyStatement dataPropStmt;
public DropDataPropStmt(DataPropertyStatement dps){
super(dps.getIndividualURI(),dps.getDatapropURI() );
this.dataPropStmt = dps;
}
public DropDataPropStmt(String subjectUri, String predicateUri, String data) {
super(subjectUri, predicateUri);
dataPropStmt = new DataPropertyStatementImpl();
dataPropStmt.setIndividualURI(subjectUri);
dataPropStmt.setDatapropURI(predicateUri);
dataPropStmt.setData(data);
}
public DropDataPropStmt(String subjectUri, String predicateUri, Literal data) {
super(subjectUri, predicateUri);
dataPropStmt = new DataPropertyStatementImpl();
dataPropStmt.setIndividualURI(subjectUri);
dataPropStmt.setDatapropURI(predicateUri);
dataPropStmt.setData(data.getValue().toString());
}
public String data(){ return dataPropStmt.getData(); }
public String lang(){ return dataPropStmt.getLanguage(); }
public String datatype(){return dataPropStmt.getDatatypeURI(); }
// TODO: needs to be fixed to work with lang/datatype literals
}

View file

@ -0,0 +1,25 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
/**
* Should we allow the user to delete this DataPropertyStatement from this
* model?
*/
public class DropDataPropertyStatement extends
AbstractDataPropertyStatementAction {
public DropDataPropertyStatement(OntModel ontModel, String subjectUri,
String predicateUri) {
super(ontModel, subjectUri, predicateUri);
}
public DropDataPropertyStatement(OntModel ontModel,
DataPropertyStatement dps) {
super(ontModel, dps);
}
}

View file

@ -1,11 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
/** Should we allow the user to delete this ObjectPropertyStatement? */
public class DropObjectPropStmt extends AbstractObjectPropertyAction {
public DropObjectPropStmt(String sub, String pred, String obj) {
super(sub, pred, obj);
}
}

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.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
/**
* Should we allow the user to delete this ObjectPropertyStatement from this
* model?
*/
public class DropObjectPropertyStatement extends
AbstractObjectPropertyStatementAction {
public DropObjectPropertyStatement(OntModel ontModel, String sub,
String pred, String obj) {
super(ontModel, sub, pred, obj);
}
public DropObjectPropertyStatement(OntModel ontModel,
ObjectPropertyStatement ops) {
super(ontModel, ops);
}
}

View file

@ -1,21 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
/** Should we allow the user to edit this DataPropertyStatement? */
public class EditDataPropStmt extends AbstractDataPropertyAction {
private final DataPropertyStatement dataPropStmt;
public EditDataPropStmt(DataPropertyStatement dps){
super(dps.getIndividualURI(), dps.getDatapropURI());
this.dataPropStmt = dps;
}
public String data(){ return dataPropStmt.getData(); }
public String lang(){ return dataPropStmt.getLanguage(); }
public String datatype(){return dataPropStmt.getDatatypeURI(); }
}

View file

@ -0,0 +1,23 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
/**
* Should we allow the user to edit this DataPropertyStatement in this model?
*/
public class EditDataPropertyStatement extends
AbstractDataPropertyStatementAction {
public EditDataPropertyStatement(OntModel ontModel, String subjectUri,
String predicateUri) {
super(ontModel, subjectUri, predicateUri);
}
public EditDataPropertyStatement(OntModel ontModel,
DataPropertyStatement dps) {
super(ontModel, dps);
}
}

View file

@ -1,19 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
/** Should we allow the user to edit this ObjectPropertyStatement? */
public class EditObjPropStmt extends AbstractObjectPropertyAction {
public EditObjPropStmt(ObjectPropertyStatement ops) {
super(ops.getSubjectURI(), ops.getPropertyURI(), ops.getObjectURI());
}
public EditObjPropStmt(String subjectUri, String keywordPredUri,
String objectUri) {
super(subjectUri, keywordPredUri, objectUri);
}
}

View file

@ -0,0 +1,23 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
/**
* Should we allow the user to edit this ObjectPropertyStatement in this model?
*/
public class EditObjectPropertyStatement extends
AbstractObjectPropertyStatementAction {
public EditObjectPropertyStatement(OntModel ontModel, String subjectUri,
String keywordPredUri, String objectUri) {
super(ontModel, subjectUri, keywordPredUri, objectUri);
}
public EditObjectPropertyStatement(OntModel ontModel,
ObjectPropertyStatement ops) {
super(ontModel, ops);
}
}

View file

@ -21,7 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
@ -58,7 +58,7 @@ public class ShowAuthController extends FreemarkerHttpServlet {
private List<Identifier> getSortedIdentifiers(VitroRequest vreq) {
Map<String, Identifier> idMap = new TreeMap<String, Identifier>();
for (Identifier id: RequestIdentifiers.getIdBundleForRequest(vreq)) {
for (Identifier id : RequestIdentifiers.getIdBundleForRequest(vreq)) {
idMap.put(id.toString(), id);
}
return new ArrayList<Identifier>(idMap.values());
@ -89,7 +89,8 @@ public class ShowAuthController extends FreemarkerHttpServlet {
* this individual?
*/
private boolean mayEditIndividual(VitroRequest vreq, String individualUri) {
RequestedAction action = new EditObjPropStmt(individualUri,
RequestedAction action = new EditObjectPropertyStatement(
vreq.getJenaOntModel(), individualUri,
RequestActionConstants.SOME_URI,
RequestActionConstants.SOME_URI);
return PolicyHelper.isAuthorizedForActions(vreq, action);

View file

@ -32,7 +32,7 @@ public class PrimitiveRdfEdit extends VitroAjaxController {
private static final long serialVersionUID = 1L;
//Using the same setsup as primitive delete
//Using the same setup as primitive delete
@Override
protected Actions requiredActions(VitroRequest vreq) {
return SimplePermission.USE_BASIC_AJAX_CONTROLLERS.ACTIONS;

View file

@ -9,8 +9,6 @@ import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
public class FreemarkerSetup implements ServletContextListener {
private static final Log log = LogFactory.getLog(FreemarkerSetup.class);
@ -18,7 +16,6 @@ public class FreemarkerSetup implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
ServletContext sc = event.getServletContext();
BaseTemplateModel.setServletContext(sc);
FreemarkerComponentGenerator.setServletContext(sc);
UrlBuilder.contextPath = sc.getContextPath();

View file

@ -19,9 +19,9 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -138,14 +138,16 @@ public class ImageUploadController extends FreemarkerHttpServlet {
RequestedAction ra;
if (ACTION_DELETE.equals(action)
|| ACTION_DELETE_EDIT.equals(action)) {
ra = new DropObjectPropStmt(entity.getURI(),
VitroVocabulary.IND_MAIN_IMAGE, imageUri);
ra = new DropObjectPropertyStatement(vreq.getJenaOntModel(),
entity.getURI(), VitroVocabulary.IND_MAIN_IMAGE,
imageUri);
} else if (imageUri != null) {
ra = new EditObjPropStmt(entity.getURI(),
VitroVocabulary.IND_MAIN_IMAGE, imageUri);
ra = new EditObjectPropertyStatement(vreq.getJenaOntModel(),
entity.getURI(), VitroVocabulary.IND_MAIN_IMAGE,
imageUri);
} else {
ra = new AddObjectPropStmt(entity.getURI(),
VitroVocabulary.IND_MAIN_IMAGE,
ra = new AddObjectPropertyStatement(vreq.getJenaOntModel(),
entity.getURI(), VitroVocabulary.IND_MAIN_IMAGE,
RequestActionConstants.SOME_URI);
}
return new Actions(ra);

View file

@ -45,7 +45,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
*/
public class RDFSLabelGenerator implements EditConfigurationGenerator {
private Log log = LogFactory.getLog(DefaultObjectPropertyFormGenerator.class);
private Log log = LogFactory.getLog(RDFSLabelGenerator.class);
private String subjectUri = null;
private String predicateUri = null;

View file

@ -110,7 +110,7 @@ public class FileServingServlet extends VitroHttpServlet {
in = fileStorage.getInputStream(fileInfo.getBytestreamUri(),
actualFilename);
} catch (FileNotFoundException e) {
log.error(e, e);
log.error("Expected file doesn't exist: " + e);
response.sendError(SC_INTERNAL_SERVER_ERROR, e.toString());
return;
}

View file

@ -4,8 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -20,8 +18,6 @@ public abstract class BaseTemplateModel {
private static final String URI_CHARACTERS =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&%'()*+,;=";
protected static ServletContext servletContext;
// Convenience method so subclasses can call getUrl(path)
protected String getUrl(String path) {
return UrlBuilder.getUrl(path);
@ -73,12 +69,4 @@ public abstract class BaseTemplateModel {
AntiScript.cleanMapValues(map);
}
protected static ServletContext getServletContext() {
return servletContext;
}
public static void setServletContext(ServletContext context) {
servletContext = context;
}
}

View file

@ -450,7 +450,7 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
predicateUri,
objectKey,
statementDisplay,
false, null, vreq);
null, vreq);
ReadOnlyBeansWrapper wrapper = new ReadOnlyBeansWrapper();
return wrapper.wrap(osm);
}

View file

@ -6,6 +6,8 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -15,8 +17,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
@ -37,12 +39,14 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
protected final Individual individual;
protected final LoginStatusBean loginStatusBean;
protected final VitroRequest vreq;
private final ServletContext ctx;
private final boolean editing;
protected GroupedPropertyList propertyList;
public BaseIndividualTemplateModel(Individual individual, VitroRequest vreq) {
this.vreq = vreq;
this.ctx = vreq.getSession().getServletContext();
this.individual = individual;
this.loginStatusBean = LoginStatusBean.getBean(vreq);
// Needed for getting portal-sensitive urls. Remove if multi-portal support is removed.
@ -54,7 +58,7 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
boolean isVClass = individual.isVClass(vClassUri);
// If reasoning is asynchronous (under RDB), this inference may not have been made yet.
// Check the superclasses of the individual's vclass.
SimpleReasoner simpleReasoner = (SimpleReasoner)getServletContext().getAttribute(SimpleReasoner.class.getName());
SimpleReasoner simpleReasoner = (SimpleReasoner) ctx.getAttribute(SimpleReasoner.class.getName());
if (!isVClass && simpleReasoner != null && simpleReasoner.isABoxReasoningAsynchronous()) {
log.debug("Checking superclasses to see if individual is a " + vClassUri + " because reasoning is asynchronous");
List<VClass> directVClasses = individual.getVClasses(true);
@ -108,10 +112,11 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
* an object property to the Individual being shown.
*/
public boolean isEditable() {
AddDataPropStmt adps = new AddDataPropStmt(individual.getURI(),
RequestActionConstants.SOME_URI,
RequestActionConstants.SOME_LITERAL, null, null);
AddObjectPropStmt aops = new AddObjectPropStmt(individual.getURI(),
AddDataPropertyStatement adps = new AddDataPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI);
AddObjectPropertyStatement aops = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI,
RequestActionConstants.SOME_URI);
return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops));
@ -127,7 +132,7 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
* are handled like ordinary ObjectProperty instances.
*/
public NameStatementTemplateModel getNameStatement() {
return new NameStatementTemplateModel(getUri(), vreq, editing);
return new NameStatementTemplateModel(getUri(), vreq);
}
/* These methods simply forward to the methods of the wrapped individual. It would be desirable to
@ -216,7 +221,7 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
public String selfEditingId() {
String id = null;
String idMatchingProperty =
ConfigurationProperties.getBean(getServletContext()).getProperty("selfEditing.idMatchingProperty");
ConfigurationProperties.getBean(ctx).getProperty("selfEditing.idMatchingProperty");
if (! StringUtils.isBlank(idMatchingProperty)) {
WebappDaoFactory wdf = vreq.getUnfilteredWebappDaoFactory();
Collection<DataPropertyStatement> ids =

View file

@ -218,7 +218,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
}
listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(subjectUri,
propertyUri, objectKey, map, editing, getTemplateName(), vreq));
propertyUri, objectKey, map, getTemplateName(), vreq));
}

View file

@ -9,8 +9,8 @@ import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -20,97 +20,61 @@ import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
public class DataPropertyStatementTemplateModel extends PropertyStatementTemplateModel {
private static final Log log = LogFactory.getLog(DataPropertyStatementTemplateModel.class);
private static final String EDIT_PATH = "editRequestDispatch";
protected String value;
private final Literal literalValue;
private final String deleteUrl;
private final String editUrl;
//Extended to include vitro request to check for special parameters
public DataPropertyStatementTemplateModel(String subjectUri, String propertyUri,
Literal literal, boolean editing, VitroRequest vreq) {
Literal literal, VitroRequest vreq) {
super(subjectUri, propertyUri, vreq);
//attempt to strip any odd HTML
this.value = cleanTextForDisplay( literal.getLexicalForm() );
this.literalValue = literal;
setEditUrls(literal, editing, propertyUri);
}
/*
* This method handles the special case where we are creating a DataPropertyStatementTemplateModel outside the GroupedPropertyList.
* Specifically, it allows rdfs:label to be treated like a data property statement and thus have editing links. It is not possible
* to handle rdfs:label like vitro links and vitroPublic image, because it is not possible to construct a DataProperty from
* rdfs:label.
*/
DataPropertyStatementTemplateModel(String subjectUri, String propertyUri, VitroRequest vreq) {
super(subjectUri, propertyUri, vreq);
}
public void setValue(String value) {
this.value = value;
}
protected void setEditUrls(Literal value, boolean editing, String propertyUri) {
if ( ! editing ) {
return;
}
DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri, propertyUri, value.getLexicalForm());
// Language and datatype are needed to get the correct hash value
dps.setLanguage(value.getLanguage());
dps.setDatatypeURI(value.getDatatypeURI());
String dataPropHash = String.valueOf(RdfLiteralHash.makeRdfLiteralHash(dps));
// Do delete url first, since used in building edit url
setDeleteUrl(propertyUri, dps, dataPropHash);
setEditUrl(propertyUri, dps, dataPropHash);
this.deleteUrl = makeDeleteUrl();
this.editUrl = makeEditUrl();
}
protected void setDeleteUrl(String propertyUri, DataPropertyStatement dps, String dataPropHash) {
// Hack for rdfs:label - the policy doesn't prevent deletion.
if (propertyUri.equals(VitroVocabulary.LABEL)) {
return;
}
private String makeDeleteUrl() {
// Determine whether the statement can be deleted
RequestedAction action = new DropDataPropStmt(dps);
DataPropertyStatement dps = makeStatement();
RequestedAction action = new DropDataPropertyStatement(vreq.getJenaOntModel(), dps);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return;
return "";
}
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"datapropKey", dataPropHash,
"datapropKey", makeHash(dps),
"cmd", "delete");
params.putAll(UrlBuilder.getModelParams(vreq));
deleteUrl = UrlBuilder.getUrl(EDIT_PATH, params);
}
protected void setEditUrl(String propertyUri, DataPropertyStatement dps, String dataPropHash) {
return UrlBuilder.getUrl(EDIT_PATH, params);
}
private String makeEditUrl() {
// vitro:moniker is deprecated. We display existing data values so editors can
// move them to other properties and delete, but don't allow editing.
if ( propertyUri.equals(VitroVocabulary.MONIKER) ) {
return;
return "";
}
// Determine whether the statement can be edited
RequestedAction action = new EditDataPropStmt(dps);
DataPropertyStatement dps = makeStatement();
RequestedAction action = new EditDataPropertyStatement(vreq.getJenaOntModel(), dps);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return;
return "";
}
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"datapropKey", dataPropHash);
"datapropKey", makeHash(dps));
if ( deleteUrl.isEmpty() ) {
params.put("deleteProhibited", "prohibited");
@ -118,14 +82,36 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
params.putAll(UrlBuilder.getModelParams(vreq));
editUrl = UrlBuilder.getUrl(EDIT_PATH, params);
}
return UrlBuilder.getUrl(EDIT_PATH, params);
}
private DataPropertyStatement makeStatement() {
DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri, propertyUri, literalValue.getLexicalForm());
// Language and datatype are needed to get the correct hash value
dps.setLanguage(literalValue.getLanguage());
dps.setDatatypeURI(literalValue.getDatatypeURI());
return dps;
}
private String makeHash(DataPropertyStatement dps) {
// Language and datatype are needed to get the correct hash value
return String.valueOf(RdfLiteralHash.makeRdfLiteralHash(dps));
}
/* Template properties */
public String getValue() {
return value;
//attempt to strip any odd HTML
return cleanTextForDisplay( literalValue.getLexicalForm() );
}
@Override
public String getDeleteUrl() {
return deleteUrl;
}
@Override
public String getEditUrl() {
return editUrl;
}
}

View file

@ -11,9 +11,8 @@ import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
@ -47,7 +46,7 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
DataPropertyStatementDao dpDao = vreq.getWebappDaoFactory().getDataPropertyStatementDao();
List<Literal> values = dpDao.getDataPropertyValuesForIndividualByProperty(subject, dp);
for (Literal value : values) {
statements.add(new DataPropertyStatementTemplateModel(subjectUri, propertyUri, value, editing, vreq));
statements.add(new DataPropertyStatementTemplateModel(subjectUri, propertyUri, value, vreq));
}
} else {
log.debug("Data property " + getUri() + " is unpopulated.");
@ -77,7 +76,8 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
}
// Determine whether a new statement can be added
RequestedAction action = new AddDataPropStmt(subjectUri, propertyUri, RequestActionConstants.SOME_LITERAL, null, null);
RequestedAction action = new AddDataPropertyStatement(
vreq.getJenaOntModel(), subjectUri, propertyUri);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return;
}

View file

@ -0,0 +1,94 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* Sometimes we don't want to show an Add, Edit, or Delete link for a particular
* property, no matter who the user is.
*
* TODO These are hard-coded while we wait for the Application Ontology to be
* implemented.
*/
public class EditLinkSuppressor {
private static final Log log = LogFactory.getLog(EditLinkSuppressor.class);
private static final String CORE = "http://vivoweb.org/ontology/core#";
private static final String PUB_TO_AUTHORSHIP = core("informationResourceInAuthorship");
private static final String PERSON_TO_AUTHORSHIP = core("authorInAuthorship");
private static final String AUTHORSHIP_TO_PERSON = core("linkedAuthor");
private static final String AUTHORSHIP_TO_PUB = core("linkedInformationResource");
private static final String INDIVIDUAL_TO_WEBPAGE = core("webpage");
private static final String WEBPAGE_TO_INDIVIDUAL = core("webpageOf");
private static final String HAS_RESEARCH_AREA = core("hasResearchArea");
private static final String HAS_SUBJECT_AREA = core("hasSubjectArea");
private static final String RESEARCH_AREA_OF = core("researchAreaOf");
private static final String SUBJECT_AREA_FOR = core("subjectAreaFor");
private static String core(String localName) {
return CORE + localName;
}
private static final List<String> suppressAddLinksForThese = Arrays
.asList(new String[] { AUTHORSHIP_TO_PERSON, AUTHORSHIP_TO_PUB,
WEBPAGE_TO_INDIVIDUAL });
private static final List<String> suppressEditLinksForThese = Arrays
.asList(new String[] { WEBPAGE_TO_INDIVIDUAL });
private static final List<String> suppressDeleteLinksForThese = Arrays
.asList(new String[] { PUB_TO_AUTHORSHIP, PERSON_TO_AUTHORSHIP,
AUTHORSHIP_TO_PERSON, AUTHORSHIP_TO_PUB,
INDIVIDUAL_TO_WEBPAGE, WEBPAGE_TO_INDIVIDUAL,
HAS_RESEARCH_AREA, RESEARCH_AREA_OF, HAS_SUBJECT_AREA,
SUBJECT_AREA_FOR });
// TODO When we remove the hard-coding, vreq will allow us to find the
// application ontology model.
@SuppressWarnings("unused")
private final VitroRequest vreq;
public EditLinkSuppressor(VitroRequest vreq) {
this.vreq = vreq;
}
/**
* Should we suppress the Add link on this property?
*/
public boolean isAddLinkSuppressed(String propertyUri) {
if (propertyUri == null) {
log.error("Suppressing the add link on a null property.");
return true;
}
return suppressAddLinksForThese.contains(propertyUri);
}
/**
* Should we suppress the Edit link on this property?
*/
public boolean isEditLinkSuppressed(String propertyUri) {
if (propertyUri == null) {
log.error("Suppressing the edit link on a null property.");
return true;
}
return suppressEditLinksForThese.contains(propertyUri);
}
/**
* Should we suppress the Delete link on this property?
*/
public boolean isDeleteLinkSuppressed(String propertyUri) {
if (propertyUri == null) {
log.error("Suppressing the delete link on a null property.");
return true;
}
return suppressDeleteLinksForThese.contains(propertyUri);
}
}

View file

@ -7,42 +7,105 @@ import org.apache.commons.logging.LogFactory;
import org.openrdf.model.URI;
import org.openrdf.model.impl.URIImpl;
import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.edit.EditLiteral;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
public class NameStatementTemplateModel extends
DataPropertyStatementTemplateModel {
/**
* This allows the template to treat an rdfs:label like a data property statement, and thus
* have an editing link.
*
* This has the same accessor methods as a DataPropertyStatementTemplateModel, but it is never
* part of the GroupedPropertyList, and it never has a deleteUrl.
*/
public class NameStatementTemplateModel extends PropertyStatementTemplateModel {
private static final Log log = LogFactory.getLog(NameStatementTemplateModel.class);
private static final Log log = LogFactory.getLog(NameStatementTemplateModel.class);
private final String stringValue;
private final String editUrl;
/*
* This method handles the special case where we are creating a DataPropertyStatementTemplateModel outside the GroupedPropertyList.
* Specifically, it allows rdfs:label to be treated like a data property statement and thus have editing links.
*/
NameStatementTemplateModel(String subjectUri, VitroRequest vreq, boolean editing) {
NameStatementTemplateModel(String subjectUri, VitroRequest vreq) {
super(subjectUri, VitroVocabulary.LABEL, vreq);
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
// NIHVIVO-2466 Use the same methods to get the label that are used elsewhere in the
// application, to guarantee consistent results for individuals with multiple labels
// across the application.
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
IndividualDao iDao = wdf.getIndividualDao();
EditLiteral literal = iDao.getLabelEditLiteral(subjectUri);
if (literal != null) {
value = cleanTextForDisplay( literal.getLexicalForm() );
setEditUrls(literal, editing, propertyUri);
if (literal == null) {
// If the individual has no rdfs:label, use the local name. It will not be editable. (This replicates previous behavior;
// perhaps we would want to allow a label to be added. But such individuals do not usually have their profiles viewed or
// edited directly.)
URI uri = new URIImpl(subjectUri);
this.stringValue = uri.getLocalName();
this.editUrl = "";
} else {
// If the individual has no rdfs:label, use the local name. It will not be editable. (This replicates previous behavior;
// perhaps we would want to allow a label to be added. But such individuals do not usually have their profiles viewed or
// edited directly.)
URI uri = new URIImpl(subjectUri);
value = uri.getLocalName();
this.stringValue = cleanTextForDisplay( literal.getLexicalForm() );
this.editUrl = makeEditUrl(literal);
}
}
private String makeEditUrl(Literal literal) {
// Determine whether the statement can be edited
DataPropertyStatement dps = makeStatement(literal);
RequestedAction action = new EditDataPropertyStatement(vreq.getJenaOntModel(), dps);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return "";
}
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"datapropKey", makeHash(dps),
"deleteProhibited", "prohibited");
params.putAll(UrlBuilder.getModelParams(vreq));
return UrlBuilder.getUrl(EDIT_PATH, params);
}
private DataPropertyStatement makeStatement(Literal literalValue) {
DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri,
propertyUri, literalValue.getLexicalForm());
// Language and datatype are needed to get the correct hash value
dps.setLanguage(literalValue.getLanguage());
dps.setDatatypeURI(literalValue.getDatatypeURI());
return dps;
}
private String makeHash(DataPropertyStatement dps) {
// Language and datatype are needed to get the correct hash value
return String.valueOf(RdfLiteralHash.makeRdfLiteralHash(dps));
}
/* Template properties */
public String getValue() {
return stringValue;
}
@Override
public String getDeleteUrl() {
return "";
}
@Override
public String getEditUrl() {
return editUrl;
}
}

View file

@ -2,6 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
@ -9,8 +11,8 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -19,107 +21,104 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMa
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class ObjectPropertyStatementTemplateModel extends PropertyStatementTemplateModel {
private static final Log log = LogFactory.getLog(ObjectPropertyStatementTemplateModel.class);
private static final String EDIT_PATH = "editRequestDispatch";
private final Map<String, String> data;
// Used for editing
private final String objectUri;
private final String templateName;
private final String objectKey;
private final String editUrl;
private final String deleteUrl;
public ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, String objectKey,
Map<String, String> data, boolean editing, String templateName, VitroRequest vreq) {
Map<String, String> data, String templateName, VitroRequest vreq) {
super(subjectUri, propertyUri, vreq);
this.data = data;
this.data = Collections.unmodifiableMap(new HashMap<String, String>(data));
this.objectUri = data.get(objectKey);
this.templateName = templateName;
//to keep track of later
this.objectKey = objectKey;
if ( editing ) {
setEditUrls();
}
ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(subjectUri, propertyUri, objectUri);
// Do delete url first, since it is used in building edit url
this.deleteUrl = makeDeleteUrl();
this.editUrl = makeEditUrl(ops);
}
protected void setEditUrls() {
// If we are in edit mode, create the list of editing permissions.
// We do this now rather than in getEditUrl() and getDeleteUrl(), because getEditUrl() also needs to know
// whether a delete is allowed.
ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(subjectUri, propertyUri, objectUri);
// Do delete url first, since used in building edit url
setDeleteUrl();
setEditUrl(ops);
}
protected void setDeleteUrl() {
private String makeDeleteUrl() {
// Is the delete link suppressed for this property?
if (new EditLinkSuppressor(vreq).isDeleteLinkSuppressed(propertyUri)) {
return "";
}
// Determine whether the statement can be deleted
RequestedAction action = new DropObjectPropStmt(subjectUri, propertyUri, objectUri);
RequestedAction action = new DropObjectPropertyStatement(
vreq.getJenaOntModel(), subjectUri, propertyUri, objectUri);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return;
return "";
}
if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) {
deleteUrl = ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "delete");
} else {
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"objectUri", objectUri,
"cmd", "delete",
"objectKey", objectKey);
for ( String key : data.keySet() ) {
String value = data.get(key);
// Remove an entry with a null value instead of letting it get passed
// as a param with an empty value, in order to align with behavior on
// profile page. E.g., if statement.moniker is null, a test for
// statement.moniker?? will yield different results if null on the
// profile page but an empty string on the deletion page.
if (value != null) {
params.put("statement_" + key, data.get(key));
}
}
params.put("templateName", templateName);
params.putAll(UrlBuilder.getModelParams(vreq));
deleteUrl = UrlBuilder.getUrl(EDIT_PATH, params);
}
}
protected void setEditUrl(ObjectPropertyStatement ops) {
return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "delete");
}
// Determine whether the statement can be edited
RequestedAction action = new EditObjPropStmt(ops);
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"objectUri", objectUri,
"cmd", "delete",
"objectKey", objectKey);
for ( String key : data.keySet() ) {
String value = data.get(key);
// Remove an entry with a null value instead of letting it get passed
// as a param with an empty value, in order to align with behavior on
// profile page. E.g., if statement.moniker is null, a test for
// statement.moniker?? will yield different results if null on the
// profile page but an empty string on the deletion page.
if (value != null) {
params.put("statement_" + key, data.get(key));
}
}
params.put("templateName", templateName);
params.putAll(UrlBuilder.getModelParams(vreq));
return UrlBuilder.getUrl(EDIT_PATH, params);
}
private String makeEditUrl(ObjectPropertyStatement ops) {
// Is the edit link suppressed for this property?
if (new EditLinkSuppressor(vreq).isEditLinkSuppressed(propertyUri)) {
return "";
}
// Determine whether the statement can be edited
RequestedAction action = new EditObjectPropertyStatement(vreq.getJenaOntModel(), ops);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return;
return "";
}
if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) {
editUrl = ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "edit");
} else {
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"objectUri", objectUri);
if ( deleteUrl.isEmpty() ) {
params.put("deleteProhibited", "prohibited");
}
params.putAll(UrlBuilder.getModelParams(vreq));
editUrl = UrlBuilder.getUrl(EDIT_PATH, params);
}
}
return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "edit");
}
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"objectUri", objectUri);
if ( deleteUrl.isEmpty() ) {
params.put("deleteProhibited", "prohibited");
}
params.putAll(UrlBuilder.getModelParams(vreq));
return UrlBuilder.getUrl(EDIT_PATH, params);
}
/* Template methods */
@ -130,5 +129,15 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
public String uri(String key) {
return cleanURIForDisplay(data.get(key));
}
@Override
public String getDeleteUrl() {
return deleteUrl;
}
@Override
public String getEditUrl() {
return editUrl;
}
}

View file

@ -17,7 +17,7 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
@ -102,9 +102,15 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
}
protected void setAddUrl(Property property) {
// Is the add link suppressed for this property?
if (new EditLinkSuppressor(vreq).isAddLinkSuppressed(propertyUri)) {
return;
}
// Determine whether a new statement can be added
RequestedAction action = new AddObjectPropStmt(subjectUri, propertyUri, RequestActionConstants.SOME_URI);
RequestedAction action = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), subjectUri, propertyUri,
RequestActionConstants.SOME_URI);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return;
}

View file

@ -2,46 +2,28 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
public abstract class PropertyStatementTemplateModel extends BaseTemplateModel {
protected static final String EDIT_PATH = "editRequestDispatch";
private static final Log log = LogFactory.getLog(PropertyStatementTemplateModel.class);
protected final VitroRequest vreq;
// Used for editing
protected final String subjectUri;
protected final String propertyUri;
protected String editUrl;
protected String deleteUrl;
PropertyStatementTemplateModel(String subjectUri, String propertyUri, VitroRequest vreq) {
this.vreq = vreq;
this.subjectUri = subjectUri;
this.propertyUri = propertyUri;
editUrl = "";
deleteUrl = "";
}
/* Template properties */
public String getEditUrl() {
return editUrl;
}
public String getDeleteUrl() {
return deleteUrl;
}
public abstract String getEditUrl();
public abstract String getDeleteUrl();
public boolean isEditable() {
return ! editUrl.isEmpty();
return ! getEditUrl().isEmpty();
}
}

View file

@ -41,7 +41,7 @@ public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplat
String objectKey = getObjectKey();
for (Map<String, String> map : statementData) {
statements.add(new ObjectPropertyStatementTemplateModel(subjectUri,
propertyUri, objectKey, map, editing, getTemplateName(), vreq));
propertyUri, objectKey, map, getTemplateName(), vreq));
}
postprocessStatementList(statements);