diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java index c238d246c..f04053f71 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java @@ -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 getObjectsOfProperty(String resourceUri, - String propertyUri) { - List list = new ArrayList(); - - 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 getObjectsOfLinkedProperty(String resourceUri, - String linkUri, String propertyUri) { - List list = new ArrayList(); - - 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 getUrisOfAuthors(Resource authorship, - String propertyUri) { - List list = new ArrayList(); - - 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 userUris, - List 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); - } - } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/RelationshipChecker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/RelationshipChecker.java new file mode 100644 index 000000000..b06407887 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/RelationshipChecker.java @@ -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 list1, List list2) { + List urisInCommon = new ArrayList(list1); + urisInCommon.retainAll(list2); + return !urisInCommon.isEmpty(); + } + + /** + * Is this resource a member of this type? That is, is there an statement of + * the form: rdfs:type + */ + 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: + * + * + * + * May return an empty list, but never returns null. + */ + public List getObjectsOfProperty(String resourceUri, + String propertyUri) { + List list = new ArrayList(); + + 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: + * + * + * + * + * + * May return an empty list, but never returns null. + */ + public List getObjectsOfLinkedProperty(String resourceUri, + String linkUri, String propertyUri) { + List list = new ArrayList(); + + 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); + } + +}