diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java new file mode 100644 index 000000000..fb5972346 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java @@ -0,0 +1,96 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; + +import javax.servlet.ServletContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; + +import edu.cornell.mannlib.vedit.beans.EditProcessObject; +import edu.cornell.mannlib.vedit.listener.ChangeListener; +import edu.cornell.mannlib.vitro.webapp.beans.Property; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; + +/** + * Add this ChangeListener to your EditProcessObject when modifying the + * ontology, and we will refresh the PropertyRestrictionPolicyHelper bean as + * appropriate. + */ +public class PropertyRestrictionListener implements ChangeListener { + private static final Log log = LogFactory + .getLog(PropertyRestrictionListener.class); + + private final ServletContext ctx; + + public PropertyRestrictionListener(ServletContext ctx) { + this.ctx = ctx; + } + + /** + * If the deleted property had a non-null restriction, rebuild the bean. + */ + @Override + public void doDeleted(Object oldObj, EditProcessObject epo) { + Property p = (Property) oldObj; + if (eitherRoleChanged(p.getHiddenFromDisplayBelowRoleLevel(), + p.getProhibitedFromUpdateBelowRoleLevel(), null, null)) { + log.debug("replacing all prohibition policies after deletion"); + createAndSetBean(); + } + } + + /** + * If the inserted property has a non-null restriction, rebuild the bean. + */ + @Override + public void doInserted(Object newObj, EditProcessObject epo) { + Property p = (Property) newObj; + if (eitherRoleChanged(null, null, + p.getHiddenFromDisplayBelowRoleLevel(), + p.getProhibitedFromUpdateBelowRoleLevel())) { + log.debug("replacing all prohibition policies after insertion"); + createAndSetBean(); + } + } + + /** + * If the updated property has changed its restrictions, rebuild the bean. + */ + @Override + public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) { + Property oldP = (Property) oldObj; + Property newP = (Property) newObj; + if (eitherRoleChanged(oldP.getHiddenFromDisplayBelowRoleLevel(), + oldP.getProhibitedFromUpdateBelowRoleLevel(), + newP.getHiddenFromDisplayBelowRoleLevel(), + newP.getProhibitedFromUpdateBelowRoleLevel())) { + log.debug("replacing all prohibition policies after update"); + createAndSetBean(); + } + } + + private boolean eitherRoleChanged(RoleLevel oldDisplayRole, + RoleLevel oldUpdateRole, RoleLevel newDisplayRole, + RoleLevel newUpdateRole) { + return (!isTheSame(oldDisplayRole, newDisplayRole)) + || (!isTheSame(oldUpdateRole, newUpdateRole)); + } + + private boolean isTheSame(RoleLevel oldRole, RoleLevel newRole) { + if ((oldRole == null) && (newRole == null)) { + return true; + } else if ((oldRole == null) || (newRole == null)) { + return false; + } else { + return oldRole.compareTo(newRole) == 0; + } + } + + private void createAndSetBean() { + OntModel model = (OntModel) ctx.getAttribute("jenaOntModel"); + PropertyRestrictionPolicyHelper.createAndSetBean(ctx, model); + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java new file mode 100644 index 000000000..d08ec142b --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java @@ -0,0 +1,360 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.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.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.rdf.model.impl.Util; +import com.hp.hpl.jena.shared.Lock; + +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; + +/** + * Assists the role-based policies in determining whether a property or resource + * may be displayed or modified. + */ +public class PropertyRestrictionPolicyHelper { + private static final Log log = LogFactory + .getLog(PropertyRestrictionPolicyHelper.class); + + private static final Collection PROHIBITED_NAMESPACES = setProhibitedNamespaces(); + private static final Collection PERMITTED_EXCEPTIONS = setPermittedExceptions(); + + private static Collection setProhibitedNamespaces() { + Set prohibitedNs = new HashSet(); + prohibitedNs.add(VitroVocabulary.vitroURI); + prohibitedNs.add(VitroVocabulary.OWL); + prohibitedNs.add(""); + return Collections.unmodifiableSet(prohibitedNs); + } + + private static Collection setPermittedExceptions() { + Set editableVitroUris = new HashSet(); + + editableVitroUris.add(VitroVocabulary.MONIKER); + editableVitroUris.add(VitroVocabulary.BLURB); + editableVitroUris.add(VitroVocabulary.DESCRIPTION); + editableVitroUris.add(VitroVocabulary.MODTIME); + editableVitroUris.add(VitroVocabulary.TIMEKEY); + + editableVitroUris.add(VitroVocabulary.CITATION); + editableVitroUris.add(VitroVocabulary.IND_MAIN_IMAGE); + + editableVitroUris.add(VitroVocabulary.LINK); + editableVitroUris.add(VitroVocabulary.PRIMARY_LINK); + editableVitroUris.add(VitroVocabulary.ADDITIONAL_LINK); + editableVitroUris.add(VitroVocabulary.LINK_ANCHOR); + editableVitroUris.add(VitroVocabulary.LINK_URL); + + editableVitroUris.add(VitroVocabulary.KEYWORD_INDIVIDUALRELATION); + editableVitroUris + .add(VitroVocabulary.KEYWORD_INDIVIDUALRELATION_INVOLVESKEYWORD); + editableVitroUris + .add(VitroVocabulary.KEYWORD_INDIVIDUALRELATION_INVOLVESINDIVIDUAL); + editableVitroUris.add(VitroVocabulary.KEYWORD_INDIVIDUALRELATION_MODE); + + return Collections.unmodifiableSet(editableVitroUris); + } + + // ---------------------------------------------------------------------- + // static methods + // ---------------------------------------------------------------------- + + /** + * The bean is attached to the ServletContext using this attribute name. + */ + private static final String ATTRIBUTE_NAME = PropertyRestrictionPolicyHelper.class + .getName(); + + public static PropertyRestrictionPolicyHelper getBean(ServletContext ctx) { + Object attribute = ctx.getAttribute(ATTRIBUTE_NAME); + if (!(attribute instanceof PropertyRestrictionPolicyHelper)) { + throw new IllegalStateException( + "PropertyRestrictionPolicyHelper has not been initialized."); + } + return (PropertyRestrictionPolicyHelper) attribute; + } + + private static void removeBean(ServletContext ctx) { + ctx.removeAttribute(ATTRIBUTE_NAME); + } + + /** + * Initialize the bean with the standard prohibitions and exceptions, and + * with the thresholds obtained from the model. + */ + public static void createAndSetBean(ServletContext ctx, OntModel model) { + Map displayThresholdMap = new HashMap(); + Map modifyThresholdMap = new HashMap(); + + if (model != null) { + populateThresholdMap(model, displayThresholdMap, + VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT); + populateThresholdMap( + model, + modifyThresholdMap, + VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT); + } + + PropertyRestrictionPolicyHelper bean = new PropertyRestrictionPolicyHelper( + PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS, + displayThresholdMap, modifyThresholdMap); + + ctx.setAttribute(ATTRIBUTE_NAME, bean); + } + + /** + * Find all the resources that possess this property, and map the resource + * URI to the require RoleLevel. + */ + private static void populateThresholdMap(OntModel model, + Map map, String propertyUri) { + model.enterCriticalSection(Lock.READ); + try { + Property property = model.getProperty(propertyUri); + StmtIterator stmts = model.listStatements((Resource) null, + property, (Resource) null); + while (stmts.hasNext()) { + Statement stmt = stmts.next(); + Resource subject = stmt.getSubject(); + RDFNode objectNode = stmt.getObject(); + if ((subject == null) || (!(objectNode instanceof Resource))) { + continue; + } + Resource object = (Resource) objectNode; + RoleLevel role = RoleLevel.getRoleByUri(object.getURI()); + map.put(subject.getURI(), role); + } + stmts.close(); + } finally { + model.leaveCriticalSection(); + } + } + + // ---------------------------------------------------------------------- + // the bean + // ---------------------------------------------------------------------- + + /** + * URIs in these namespaces can't be modified, unless they are listed in the + * exceptions. + */ + private final Collection modifyProhibitedNamespaces; + + /** + * These URIs can be modified, even if they are in the prohibited + * namespaces. + */ + private final Collection modifyExceptionsAllowedUris; + + /** + * URIs in here can be displayed only if the user's role is at least as high + * as the threshold role. + */ + private final Map displayThresholdMap; + + /** + * URIs in here can be modified only if the user's role is at least as high + * as the threshold role. + */ + private final Map modifyThresholdMap; + + /** + * Store unmodifiable versions of the inputs. + * + * Protected access: should only be created by the static methods, or by + * unit tests. + */ + protected PropertyRestrictionPolicyHelper( + Collection modifyProhibitedNamespaces, + Collection modifyExceptionsAllowedUris, + Map displayThresholdMap, + Map modifyThresholdMap) { + this.modifyProhibitedNamespaces = unmodifiable(modifyProhibitedNamespaces); + this.modifyExceptionsAllowedUris = unmodifiable(modifyExceptionsAllowedUris); + this.displayThresholdMap = unmodifiable(displayThresholdMap); + this.modifyThresholdMap = unmodifiable(modifyThresholdMap); + + if (log.isDebugEnabled()) { + log.debug("prohibited namespaces: " + this.modifyProhibitedNamespaces); + log.debug("exceptions: " + this.modifyExceptionsAllowedUris); + log.debug("display thresholds: " + this.displayThresholdMap); + log.debug("modify thresholds: " + this.modifyThresholdMap); + } + } + + private Collection unmodifiable(Collection raw) { + if (raw == null) { + return Collections.emptyList(); + } else { + return Collections.unmodifiableCollection(new HashSet(raw)); + } + } + + private Map unmodifiable(Map raw) { + if (raw == null) { + return Collections.emptyMap(); + } else { + return Collections.unmodifiableMap(new HashMap( + raw)); + } + } + + /** + * Any resource can be displayed. + * + * (Someday we may want to implement display restrictions based on VClass.) + */ + @SuppressWarnings("unused") + public boolean canDisplayResource(String resourceUri, RoleLevel userRole) { + if (resourceUri == null) { + log.debug("can't display resource: resourceUri was null"); + return false; + } + + log.debug("can display resource '" + resourceUri + "'"); + return true; + } + + /** + * A resource cannot be modified if its namespace is in the prohibited list + * (but some exceptions are allowed). + * + * (Someday we may want to implement modify restrictions based on VClass.) + */ + @SuppressWarnings("unused") + public boolean canModifyResource(String resourceUri, RoleLevel userRole) { + if (resourceUri == null) { + log.debug("can't modify resource: resourceUri was null"); + return false; + } + + if (modifyProhibitedNamespaces.contains(namespace(resourceUri))) { + if (modifyExceptionsAllowedUris.contains(resourceUri)) { + log.debug("'" + resourceUri + "' is a permitted exception"); + } else { + log.debug("can't modify resource '" + resourceUri + + "': prohibited namespace: '" + namespace(resourceUri) + + "'"); + return false; + } + } + + log.debug("can modify resource '" + resourceUri + "'"); + return true; + } + + /** + * If display of a predicate is restricted, the user's role must be at least + * as high as the restriction level. + */ + public boolean canDisplayPredicate(String predicateUri, RoleLevel userRole) { + if (predicateUri == null) { + log.debug("can't display predicate: predicateUri was null"); + return false; + } + + RoleLevel displayThreshold = displayThresholdMap.get(predicateUri); + if (isAuthorized(userRole, displayThreshold)) { + log.debug("can display predicate: '" + predicateUri + + "', userRole=" + userRole + ", thresholdRole=" + + displayThreshold); + return true; + } + + log.debug("can't display predicate: '" + predicateUri + "', userRole=" + + userRole + ", thresholdRole=" + displayThreshold); + return false; + } + + /** + * A predicate cannot be modified if its namespace is in the prohibited list + * (some exceptions are allowed). + * + * If modification of a predicate is restricted, the user's role must be at + * least as high as the restriction level. + */ + public boolean canModifyPredicate(String predicateUri, RoleLevel userRole) { + if (predicateUri == null) { + log.debug("can't modify predicate: predicateUri was null"); + return false; + } + + if (modifyProhibitedNamespaces.contains(namespace(predicateUri))) { + if (modifyExceptionsAllowedUris.contains(predicateUri)) { + log.debug("'" + predicateUri + "' is a permitted exception"); + } else { + log.debug("can't modify resource '" + predicateUri + + "': prohibited namespace: '" + + namespace(predicateUri) + "'"); + return false; + } + } + + RoleLevel modifyThreshold = modifyThresholdMap.get(predicateUri); + if (isAuthorized(userRole, modifyThreshold)) { + log.debug("can modify predicate: '" + predicateUri + "', userRole=" + + userRole + ", thresholdRole=" + modifyThreshold); + return true; + } + + log.debug("can't modify predicate: '" + predicateUri + "', userRole=" + + userRole + ", thresholdRole=" + modifyThreshold); + return false; + } + + private boolean isAuthorized(RoleLevel userRole, RoleLevel thresholdRole) { + if (userRole == null) { + return false; + } + if (thresholdRole == null) { + return true; + } + return userRole.compareTo(thresholdRole) >= 0; + } + + private String namespace(String uri) { + return uri.substring(0, Util.splitNamespace(uri)); + } + + // ---------------------------------------------------------------------- + // Setup class + // ---------------------------------------------------------------------- + + /** + * Create the bean at startup and remove it at shutdown. + */ + public static class Setup implements ServletContextListener { + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext ctx = sce.getServletContext(); + OntModel model = (OntModel) ctx.getAttribute("jenaOntModel"); + createAndSetBean(ctx, model); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + removeBean(sce.getServletContext()); + } + } + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java new file mode 100644 index 000000000..cc305a451 --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java @@ -0,0 +1,247 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; + +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.CURATOR; +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.DB_ADMIN; +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.EDITOR; +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.NOBODY; +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.PUBLIC; +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.SELF; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.log4j.Level; +import org.junit.Before; +import org.junit.Test; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Property; +import com.hp.hpl.jena.rdf.model.Resource; + +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; + +/** + * Check that the bean gets built properly, and check that the bean works properly. + */ +public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass { + private static final Log log = LogFactory + .getLog(PropertyRestrictionPolicyHelperTest.class); + + private static final String PROPERTY_DISPLAY_THRESHOLD = VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT; + private static final String PROPERTY_MODIFY_THRESHOLD = VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT; + + private static final String[] PROHIBITED_NAMESPACES = new String[] { + VitroVocabulary.vitroURI, "" }; + + private static final String[] PERMITTED_EXCEPTIONS = new String[] { + VitroVocabulary.MONIKER, VitroVocabulary.BLURB }; + + private OntModel ontModel; + private ModelWrapper wrapper; + private PropertyRestrictionPolicyHelper bean; + + @Before + public void setLoggingLevel() { +// setLoggerLevel(PropertyRestrictionPolicyHelper.class, Level.DEBUG); + } + + @Before + public void createTheBean() { + Map displayLevels = new HashMap(); + displayLevels.put("http://predicates#display_self", SELF); + displayLevels.put("http://predicates#display_curator", CURATOR); + displayLevels.put("http://predicates#display_hidden", NOBODY); + + Map modifyLevels = new HashMap(); + modifyLevels.put("http://predicates#modify_self", SELF); + modifyLevels.put("http://predicates#modify_curator", CURATOR); + modifyLevels.put("http://predicates#modify_hidden", NOBODY); + + bean = new PropertyRestrictionPolicyHelper( + Arrays.asList(PROHIBITED_NAMESPACES), + Arrays.asList(PERMITTED_EXCEPTIONS), displayLevels, + modifyLevels); + } + + @Before + public void createTheModel() { + ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM); + + wrapper = new ModelWrapper(ontModel); + + wrapper.add("http://thresholds#display_public", + PROPERTY_DISPLAY_THRESHOLD, PUBLIC.getURI()); + wrapper.add("http://thresholds#display_hidden", + PROPERTY_DISPLAY_THRESHOLD, NOBODY.getURI()); + + wrapper.add("http://thresholds#modify_editor", + PROPERTY_MODIFY_THRESHOLD, EDITOR.getURI()); + wrapper.add("http://thresholds#modify_curator", + PROPERTY_MODIFY_THRESHOLD, CURATOR.getURI()); + } + + // ---------------------------------------------------------------------- + // test the bean + // ---------------------------------------------------------------------- + + @Test + public void displayResource() { + assertEquals("display a random resource", true, + bean.canDisplayResource("http://someRandom#string", null)); + } + + @Test + public void modifyResourceNoRestriction() { + assertEquals("modify a random resource", true, + bean.canModifyResource("http://someRandom#string", null)); + } + + @Test + public void modifyResourceProhibitedNamespace() { + assertEquals("modify a prohibited resource", false, + bean.canModifyResource(PROHIBITED_NAMESPACES[0] + "random", + null)); + } + + @Test + public void modifyResourcePermittedException() { + assertEquals("modify a exception resource", true, + bean.canModifyResource(PERMITTED_EXCEPTIONS[0], null)); + } + + @Test + public void displayPredicateNoRestriction() { + assertEquals("displayPredicate: open", true, + bean.canDisplayPredicate("http://predicates#open", PUBLIC)); + } + + @Test + public void displayPredicateRestrictionLower() { + assertEquals("displayPredicate: lower restriction", true, + bean.canDisplayPredicate("http://predicates#display_self", + CURATOR)); + } + + @Test + public void displayPredicateRestrictionEqual() { + assertEquals("displayPredicate: equal restriction", true, + bean.canDisplayPredicate("http://predicates#display_curator", + CURATOR)); + } + + @Test + public void displayPredicateRestrictionHigher() { + assertEquals("displayPredicate: higher restriction", false, + bean.canDisplayPredicate("http://predicates#display_hidden", + CURATOR)); + } + + @Test + public void modifyPredicateNoRestriction() { + assertEquals("modifyPredicate: open", true, + bean.canModifyPredicate("http://predicates#open", PUBLIC)); + } + + @Test + public void modifyPredicateRestrictionLower() { + assertEquals("modifyPredicate: lower restriction", true, + bean.canModifyPredicate("http://predicates#modify_self", + CURATOR)); + } + + @Test + public void modifyPredicateRestrictionEqual() { + assertEquals("modifyPredicate: equal restriction", true, + bean.canModifyPredicate("http://predicates#modify_curator", + CURATOR)); + } + + @Test + public void modifyPredicateRestrictionHigher() { + assertEquals("modifyPredicate: higher restriction", false, + bean.canModifyPredicate("http://predicates#modify_hidden", + CURATOR)); + } + + @Test + public void modifyPredicateProhibitedNamespace() { + assertEquals("modifyPredicate: prohibited namespace", false, + bean.canModifyPredicate(PROHIBITED_NAMESPACES[0] + "randoom", + DB_ADMIN)); + } + + @Test + public void modifyPredicatePermittedException() { + assertEquals("modifyPredicate: permitted exception", true, + bean.canModifyPredicate(PERMITTED_EXCEPTIONS[0], DB_ADMIN)); + } + + // ---------------------------------------------------------------------- + // test the bean builder + // ---------------------------------------------------------------------- + + @Test + public void buildDisplayThresholds() { + Map expectedMap = new HashMap(); + expectedMap.put("http://thresholds#display_public", PUBLIC); + expectedMap.put("http://thresholds#display_hidden", NOBODY); + + Map actualMap = populateThresholdMap(PROPERTY_DISPLAY_THRESHOLD); + assertEquals("display thresholds", expectedMap, actualMap); + } + + @Test + public void buildModifyThresholds() { + Map expectedMap = new HashMap(); + expectedMap.put("http://thresholds#modify_editor", EDITOR); + expectedMap.put("http://thresholds#modify_curator", CURATOR); + + Map actualMap = populateThresholdMap(PROPERTY_MODIFY_THRESHOLD); + assertEquals("modify thresholds", expectedMap, actualMap); + } + + /** Invoke the private static method "populateThresholdMap" */ + private Map populateThresholdMap(String propertyUri) { + Map map = new HashMap(); + try { + Class clazz = PropertyRestrictionPolicyHelper.class; + Method method = clazz.getDeclaredMethod("populateThresholdMap", + OntModel.class, Map.class, String.class); + method.setAccessible(true); + method.invoke(null, ontModel, map, propertyUri); + return map; + } catch (Exception e) { + fail("failed to populate the map: propertyUri='" + propertyUri + + "', " + e); + return null; + } + } + + private static class ModelWrapper { + private final OntModel model; + + public ModelWrapper(OntModel model) { + this.model = model; + } + + public void add(String subjectUri, String propertyUri, String objectUri) { + Resource subject = model.getResource(subjectUri); + Property property = model.getProperty(propertyUri); + Resource object = model.getResource(objectUri); + model.add(subject, property, object); + } + } +}