From daac8c3c4f4fcb8fe0c7844de16f1bc05c9b0850 Mon Sep 17 00:00:00 2001 From: Jim Blake Date: Thu, 6 Nov 2014 10:28:40 -0500 Subject: [PATCH] Populate the new bean from the base property. Handle policy restrictions. --- .../vitro/webapp/beans/BaseResourceBean.java | 1 + .../vitro/webapp/beans/FauxProperty.java | 3 +- .../edit/FauxPropertyRetryController.java | 20 +++- .../webapp/dao/jena/FauxPropertyDaoJena.java | 96 +++++++++++++----- .../vitro/webapp/dao/jena/JenaBaseDao.java | 15 +++ .../ConfigurationBeanLoader.java | 18 ++-- .../configuration/ConfigurationRdfParser.java | 41 ++++---- .../vitro/webapp/utils/jena/Critical.java | 97 ++++++++++++------- .../edit/specific/fauxProperty_retry.jsp | 2 +- 9 files changed, 203 insertions(+), 90 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java index 67e02fad8..e782aab44 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java @@ -79,6 +79,7 @@ public class BaseResourceBean implements ResourceBean { return shorthand; } + // Never returns null. public static RoleLevel getRoleByUri(String uri2) { if (uri2 == null) return RoleLevel.values()[0]; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java index a7aebf510..67bb52923 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java @@ -214,7 +214,8 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean, return "FauxProperty[domainURI=" + domainURI + ", baseUri=" + getURI() + ", rangeURI=" + rangeURI + ", rangeLabel=" + rangeLabel + ", domainLabel=" + domainLabel + ", pickListName=" - + getPickListName() + ", groupURI=" + groupURI + + getPickListName() + ", contextUri=" + contextUri + + ", configUri=" + configUri + ", groupURI=" + groupURI + "publicDescription=" + publicDescription + ", displayTier=" + displayTier + ", displayLimit=" + displayLimit + ", collateBySubclass=" + collateBySubclass diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/FauxPropertyRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/FauxPropertyRetryController.java index ad328e240..250f52723 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/FauxPropertyRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/FauxPropertyRetryController.java @@ -31,12 +31,14 @@ import edu.cornell.mannlib.vedit.validator.impl.RequiredFieldValidator; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener; import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup; import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao; +import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; @@ -141,7 +143,7 @@ public class FauxPropertyRetryController extends BaseEditController { String domainUri = req.getParameter("domainUri"); if (epo.getAction().equals("insert")) { - return new FauxProperty(null, baseUri, null); + return newFauxProperty(baseUri); } FauxProperty bean = fpDao.getFauxPropertyByUris(domainUri, baseUri, @@ -155,6 +157,22 @@ public class FauxPropertyRetryController extends BaseEditController { return bean; } + /** + * Create a new FauxProperty object and let it inherit some values from its base property. + */ + private FauxProperty newFauxProperty(String baseUri) { + FauxProperty fp = new FauxProperty(null, baseUri, null); + ObjectPropertyDao opDao = wadf.getObjectPropertyDao(); + ObjectProperty base = opDao.getObjectPropertyByURI(baseUri); + fp.setGroupURI(base.getGroupURI()); + fp.setRangeURI(base.getRangeVClassURI()); + fp.setDomainURI(base.getDomainVClassURI()); + fp.setHiddenFromDisplayBelowRoleLevel(base.getHiddenFromDisplayBelowRoleLevel()); + fp.setHiddenFromPublishBelowRoleLevel(base.getHiddenFromPublishBelowRoleLevel()); + fp.setProhibitedFromUpdateBelowRoleLevel(base.getProhibitedFromUpdateBelowRoleLevel()); + return fp; + } + private void setFieldValidators() { epo.getValidatorMap() .put("RangeURI", diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/FauxPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/FauxPropertyDaoJena.java index fb90a2471..95f7e78f4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/FauxPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/FauxPropertyDaoJena.java @@ -180,7 +180,7 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao @Override public void insertFauxProperty(FauxProperty fp) { - if ((fp.getContextUri() != null) || (fp.getConfigUri() == null)) { + if ((fp.getContextUri() != null) || (fp.getConfigUri() != null)) { throw new IllegalStateException( "ContextUri and ConfigUri must be null on insert: " + fp); } @@ -193,31 +193,28 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao "FauxProperty with these qualifiers already exists: " + fp); } - try { - fp.setContextUri(getUnusedURI()); - fp.setConfigUri(getUnusedURI()); - } catch (InsertException e) { - throw new RuntimeException(e); - } - try (LockedOntModel displayModel = models.getDisplayModel().write()) { + fp.setContextUri(getUnusedURI()); + OntResource context = displayModel.createOntResource(fp .getContextUri()); addPropertyResourceValue(context, RDF.type, CONFIG_CONTEXT); - addPropertyResourceURIValue(context, HAS_CONFIGURATION, - fp.getConfigUri()); addPropertyResourceURIValue(context, CONFIG_CONTEXT_FOR, fp.getBaseURI()); addPropertyResourceURIValue(context, QUALIFIED_BY_RANGE, fp.getRangeURI()); - addPropertyResourceURIValue(context, QUALIFIED_BY_DOMAIN, + addPropertyResourceURINotEmpty(context, QUALIFIED_BY_DOMAIN, fp.getDomainURI()); + fp.setConfigUri(getUnusedURI()); + addPropertyResourceURIValue(context, HAS_CONFIGURATION, + fp.getConfigUri()); + OntResource config = displayModel.createOntResource(fp .getConfigUri()); addPropertyResourceValue(config, RDF.type, OBJECT_PROPERTY_DISPLAY_CONFIG); - addPropertyResourceURIValue(config, PROPERTY_GROUP, + addPropertyResourceURINotEmpty(config, PROPERTY_GROUP, fp.getGroupURI()); addPropertyStringValue(config, DISPLAY_NAME, fp.getDisplayName(), displayModel); @@ -237,6 +234,26 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao fp.getCustomEntryForm(), displayModel); addPropertyStringValue(config, LIST_VIEW_FILE, fp.getCustomListView(), displayModel); + + updatePropertyResourceURIValue(config, + HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT, fp + .getHiddenFromDisplayBelowRoleLevel().getURI()); + updatePropertyResourceURIValue(config, + HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT, fp + .getHiddenFromPublishBelowRoleLevel().getURI()); + updatePropertyResourceURIValue(config, + PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, fp + .getProhibitedFromUpdateBelowRoleLevel().getURI()); + + } catch (InsertException e) { + throw new RuntimeException(e); + } + } + + private void addPropertyResourceURINotEmpty(OntResource context, + ObjectProperty prop, String uri) { + if (uri != null && !uri.isEmpty()) { + addPropertyResourceURIValue(context, prop, uri); } } @@ -302,6 +319,16 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao fp.getCustomEntryForm(), displayModel); updatePropertyStringValue(config, LIST_VIEW_FILE, fp.getCustomListView(), displayModel); + + updatePropertyResourceURIValue(config, + HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT, fp + .getHiddenFromDisplayBelowRoleLevel().getURI()); + updatePropertyResourceURIValue(config, + HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT, fp + .getHiddenFromPublishBelowRoleLevel().getURI()); + updatePropertyResourceURIValue(config, + PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, fp + .getProhibitedFromUpdateBelowRoleLevel().getURI()); } } @@ -388,14 +415,24 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao fp.setDisplayTier(getPropertyIntValue(config, DISPLAY_RANK_ANNOT)); fp.setDisplayLimit(getPropertyIntValue(config, DISPLAY_LIMIT)); - fp.setCollateBySubclass(getPropertyBooleanValue(config, - PROPERTY_COLLATEBYSUBCLASSANNOT)); - fp.setSelectFromExisting(getPropertyBooleanValue(config, - PROPERTY_SELECTFROMEXISTINGANNOT)); - fp.setOfferCreateNewOption(getPropertyBooleanValue(config, - PROPERTY_OFFERCREATENEWOPTIONANNOT)); + fp.setCollateBySubclass(Boolean.TRUE + .equals(getPropertyBooleanValue(config, + PROPERTY_COLLATEBYSUBCLASSANNOT))); + fp.setSelectFromExisting(Boolean.TRUE + .equals(getPropertyBooleanValue(config, + PROPERTY_SELECTFROMEXISTINGANNOT))); + fp.setOfferCreateNewOption(Boolean.TRUE + .equals(getPropertyBooleanValue(config, + PROPERTY_OFFERCREATENEWOPTIONANNOT))); fp.setCustomEntryForm(getPropertyStringValue(config, PROPERTY_CUSTOMENTRYFORMANNOT)); + + fp.setHiddenFromDisplayBelowRoleLevel(getMostRestrictiveRoleLevel( + config, HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT)); + fp.setHiddenFromPublishBelowRoleLevel(getMostRestrictiveRoleLevel( + config, HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT)); + fp.setProhibitedFromUpdateBelowRoleLevel(getMostRestrictiveRoleLevel( + config, PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT)); } } } @@ -444,7 +481,7 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN = "" // + "PREFIX : \n" // + "\n" // - + "SELECT DISTINCT ?context \n" // + + "SELECT DISTINCT ?context ?config \n" // + "WHERE { \n" // + " ?context a :ConfigContext ; \n" // + " :configContextFor ?baseUri ; \n" // @@ -493,7 +530,7 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao String baseUri, String rangeUri) { try (LockedOntModel displayModel = lockableDisplayModel.read()) { String queryString; - if (domainUri == null) { + if (domainUri == null || domainUri.trim().isEmpty()) { queryString = bindValues( QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN, uriValue("baseUri", baseUri), @@ -505,11 +542,19 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao uriValue("rangeUri", rangeUri), uriValue("domainUri", domainUri)); } + if (log.isDebugEnabled()) { + log.debug("domainUri=" + domainUri + ", baseUri=" + baseUri + + ", rangeUri=" + rangeUri + ", queryString=" + + queryString); + } ParserLocateConfigContext parser = new ParserLocateConfigContext( domainUri, baseUri, rangeUri); - return new SparqlQueryRunner(displayModel).executeSelect( - parser, queryString); + Set contexts = new SparqlQueryRunner( + displayModel).executeSelect(parser, queryString); + + log.debug("found " + contexts.size() + " contexts: " + contexts); + return contexts; } } @@ -548,6 +593,13 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao return rangeUri; } + @Override + public String toString() { + return "ConfigContext[contextUri=" + contextUri + ", configUri=" + + configUri + ", domainUri=" + domainUri + ", baseUri=" + + baseUri + ", rangeUri=" + rangeUri + "]"; + } + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java index 085c4dc4e..814b80e72 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java @@ -48,6 +48,7 @@ import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDFS; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; public class JenaBaseDao extends JenaBaseDaoCon { @@ -573,6 +574,20 @@ public class JenaBaseDao extends JenaBaseDaoCon { return list; } + protected RoleLevel getMostRestrictiveRoleLevel(Resource res, Property prop) { + RoleLevel level = RoleLevel.getRoleByUri(null); + for (Statement stmt : res.listProperties(prop).toList()) { + if (stmt.getObject().isURIResource()) { + RoleLevel roleFromModel = RoleLevel.getRoleByUri(stmt + .getObject().as(Resource.class).getURI()); + if (roleFromModel.compareTo(level) > 0) { + level = roleFromModel; + } + } + } + return level; + } + /** * convenience method for use with functional object properties */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoader.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoader.java index 9286527d9..584797e5b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoader.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoader.java @@ -2,19 +2,21 @@ package edu.cornell.mannlib.vitro.webapp.utils.configuration; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource; + import java.util.HashSet; import java.util.List; import java.util.Set; -import static com.hp.hpl.jena.rdf.model.ResourceFactory.*; + import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.vocabulary.RDF; -import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical; +import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockableModel; +import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockedModel; /** * Load one or more Configuration beans from a specified model. @@ -48,7 +50,7 @@ public class ConfigurationBeanLoader { // ---------------------------------------------------------------------- /** Must not be null. */ - private final Model model; + private final LockableModel model; /** * May be null, but the loader will be unable to satisfy instances of @@ -82,7 +84,7 @@ public class ConfigurationBeanLoader { throw new NullPointerException("model may not be null."); } - this.model = model; + this.model = new LockableModel(model); this.req = req; this.ctx = ctx; } @@ -120,9 +122,9 @@ public class ConfigurationBeanLoader { public Set loadAll(Class resultClass) throws ConfigurationBeanLoaderException { Set uris = new HashSet<>(); - try (Critical.Section section = Critical.Section.read(model)) { - List resources = model.listResourcesWithProperty( - RDF.type, createResource(toJavaUri(resultClass))).toList(); + try (LockedModel m = model.read()) { + List resources = m.listResourcesWithProperty(RDF.type, + createResource(toJavaUri(resultClass))).toList(); for (Resource r : resources) { if (r.isURIResource()) { uris.add(r.getURI()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationRdfParser.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationRdfParser.java index 530dbdd31..88df4d53f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationRdfParser.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationRdfParser.java @@ -13,7 +13,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Selector; @@ -23,15 +22,17 @@ import com.hp.hpl.jena.vocabulary.RDF; import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyStatement; import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyTypeException; -import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical; +import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockableModel; +import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockedModel; /** * Parse the RDF for a single individual in the model to create a * ConfigurationRdf object. */ public class ConfigurationRdfParser { - public static ConfigurationRdf parse(Model model, String uri, - Class resultClass) throws InvalidConfigurationRdfException { + public static ConfigurationRdf parse(LockableModel model, + String uri, Class resultClass) + throws InvalidConfigurationRdfException { if (model == null) { throw new NullPointerException("model may not be null."); } @@ -54,36 +55,36 @@ public class ConfigurationRdfParser { return new ConfigurationRdf(concreteClass, properties); } - private static void confirmExistenceInModel(Model model, String uri) + private static void confirmExistenceInModel(LockableModel model, String uri) throws InvalidConfigurationRdfException { Selector s = new SimpleSelector(createResource(uri), null, (RDFNode) null); - try (Critical.Section section = Critical.Section.read(model)) { - if (model.listStatements(s).toList().isEmpty()) { + try (LockedModel m = model.read()) { + if (m.listStatements(s).toList().isEmpty()) { throw individualDoesNotAppearInModel(uri); } } } - private static void confirmEligibilityForResultClass(Model model, + private static void confirmEligibilityForResultClass(LockableModel model, String uri, Class resultClass) throws InvalidConfigurationRdfException { Statement s = createStatement(createResource(uri), RDF.type, createResource(toJavaUri(resultClass))); - try (Critical.Section section = Critical.Section.read(model)) { - if (!model.contains(s)) { + try (LockedModel m = model.read()) { + if (!m.contains(s)) { throw noTypeStatementForResultClass(s); } } } - private static Set loadProperties(Model model, String uri) - throws InvalidConfigurationRdfException { + private static Set loadProperties(LockableModel model, + String uri) throws InvalidConfigurationRdfException { Set set = new HashSet<>(); - try (Critical.Section section = Critical.Section.read(model)) { - List rawStatements = model.listStatements( - model.getResource(uri), (Property) null, (RDFNode) null) + try (LockedModel m = model.read()) { + List rawStatements = m.listStatements( + m.getResource(uri), (Property) null, (RDFNode) null) .toList(); if (rawStatements.isEmpty()) { throw noRdfStatements(uri); @@ -106,14 +107,14 @@ public class ConfigurationRdfParser { } } - private static Class determineConcreteClass(Model model, - String uri, Class resultClass) + private static Class determineConcreteClass( + LockableModel model, String uri, Class resultClass) throws InvalidConfigurationRdfException { Set> concreteClasses = new HashSet<>(); - try (Critical.Section section = Critical.Section.read(model)) { - for (RDFNode node : model.listObjectsOfProperty( - createResource(uri), RDF.type).toSet()) { + try (LockedModel m = model.read()) { + for (RDFNode node : m.listObjectsOfProperty(createResource(uri), + RDF.type).toSet()) { if (!node.isURIResource()) { throw typeMustBeUriResource(node); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/Critical.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/Critical.java index c1262b20b..f0d85122a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/Critical.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/Critical.java @@ -2,52 +2,25 @@ package edu.cornell.mannlib.vitro.webapp.utils.jena; -import static com.hp.hpl.jena.shared.Lock.READ; -import static com.hp.hpl.jena.shared.Lock.WRITE; - import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.shared.Lock; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.AbstractModelDecorator; import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.AbstractOntModelDecorator; /** * AutoCloseable helper classes for using models in a try-with-resources block. + * + * TODO - create separate classes in criticalsection package + * Locked + * LockerFor + * Add to develop. + * Remove Critical and convert configurationBeanLoader + * Merge to faux. */ public abstract class Critical { - /** - * Use this when you have a bare model, and you want to control a critical - * section. - * - *
-	 * try (Critical.Section section = Critical.Section.read(model)) {
-	 *     ...
-	 * }
-	 * 
- */ - public static class Section implements AutoCloseable { - public static Section read(Model model) { - return new Section(model, READ); - } - - public static Section write(Model model) { - return new Section(model, WRITE); - } - - private final Model model; - - private Section(Model model, boolean readLockRequested) { - this.model = model; - this.model.enterCriticalSection(readLockRequested); - } - - @Override - public void close() { - this.model.leaveCriticalSection(); - } - } - /** * Use this when you have a bare OntModelSelector. It returns * LockableOntModels, which can then be locked in a critical section. @@ -74,7 +47,7 @@ public abstract class Critical { /** * Returned by the LockingOntModelSelector, or it can be wrapped around a - * bare OntModel. + * bare OntModel. Cannot be used without locking. * *
 	 * try (LockedOntModel m = lockingOms.getDisplayModel.read()) {
@@ -104,7 +77,7 @@ public abstract class Critical {
 	 * A simple OntModel, except that it can only be created by locking a
 	 * LockableOntModel. It is AutoCloseable, but the close method has been
 	 * hijacked to simply release the lock, and not to actually close the
-	 * wrapped model. 
+	 * wrapped model.
 	 */
 	public static class LockedOntModel extends AbstractOntModelDecorator
 			implements AutoCloseable {
@@ -123,4 +96,54 @@ public abstract class Critical {
 		}
 	}
 
+	/**
+	 * Can be wrapped around a bare OntModel. Cannot be used without locking.
+	 * 
+	 * 
+	 * try (LockedModel m = lockableModel.read()) {
+	 *    ...
+	 * }
+	 * 
+ */ + public static class LockableModel { + private final Model model; + + public LockableModel(Model model) { + this.model = model; + } + + public LockedModel read() { + model.enterCriticalSection(Lock.READ); + return new LockedModel(model); + } + + public LockedModel write() { + model.enterCriticalSection(Lock.WRITE); + return new LockedModel(model); + } + } + + /** + * A simple Model, except that it can only be created by locking a + * LockableModel. It is AutoCloseable, but the close method has been + * hijacked to simply release the lock, and not to actually close the + * wrapped model. + */ + public static class LockedModel extends AbstractModelDecorator + implements AutoCloseable { + + private LockedModel(Model m) { + super(m); + } + + /** + * Just unlocks the model. Doesn't actually close it, because we may + * want to use it again. + */ + @Override + public void close() { + super.leaveCriticalSection(); + } + } + } diff --git a/webapp/web/templates/edit/specific/fauxProperty_retry.jsp b/webapp/web/templates/edit/specific/fauxProperty_retry.jsp index 7110daddd..d8bd7fffe 100644 --- a/webapp/web/templates/edit/specific/fauxProperty_retry.jsp +++ b/webapp/web/templates/edit/specific/fauxProperty_retry.jsp @@ -6,7 +6,7 @@ Base property
- " disabled="disabled" />
+ " disabled="disabled" />
a specification of this property