Cleanup. Use the locking model classes.

This commit is contained in:
Jim Blake 2014-11-05 12:59:48 -05:00
parent 852da3ff2a
commit ec6f166f54
4 changed files with 235 additions and 234 deletions

View file

@ -24,11 +24,8 @@ import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.ModelFactory; 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.ResIterator; import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty; import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
@ -37,6 +34,9 @@ import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.QueryParser; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.QueryParser;
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockableOntModel;
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockedOntModel;
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockingOntModelSelector;
/** /**
* TODO * TODO
@ -79,84 +79,85 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
// The instance // The instance
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
private final LockingOntModelSelector models;
public FauxPropertyDaoJena(WebappDaoFactoryJena wadf) { public FauxPropertyDaoJena(WebappDaoFactoryJena wadf) {
super(wadf); super(wadf);
} this.models = new LockingOntModelSelector(wadf.getOntModelSelector());
@Override
protected OntModel getOntModel() {
return getOntModelSelector().getDisplayModel();
} }
@Override @Override
public List<FauxProperty> getFauxPropertiesForBaseUri(String uri) { public List<FauxProperty> getFauxPropertiesForBaseUri(String uri) {
List<FauxProperty> list = new ArrayList<>(); try (LockedOntModel displayModel = models.getDisplayModel().read()) {
if (uri == null) {
return Collections.emptyList();
}
getOntModel().enterCriticalSection(Lock.READ); List<String> contextUris = new ArrayList<>();
try { ResIterator contextResources = displayModel
if (uri != null) {
ResIterator contextResources = getOntModel()
.listSubjectsWithProperty(CONFIG_CONTEXT_FOR, .listSubjectsWithProperty(CONFIG_CONTEXT_FOR,
createResource(uri)); createResource(uri));
for (Resource context : contextResources.toList()) { for (Resource context : contextResources.toList()) {
if (!context.isURIResource()) { if (context.isURIResource()) {
continue; contextUris.add(context.asResource().getURI());
}
} }
FauxProperty fp = getFauxPropertyFromContextUri(context List<FauxProperty> fpList = new ArrayList<>();
.getURI()); for (String contextUri : contextUris) {
if (fp == null) { FauxProperty fp = getFauxPropertyFromContextUri(contextUri);
continue; if (fp != null) {
} fpList.add(fp);
}
list.add(fp); }
} return fpList;
} }
} finally {
getOntModel().leaveCriticalSection();
}
return list;
} }
/**
* Returns null if contextUri does not represent a valid CONFIG_CONTEXT.
*/
@Override @Override
public FauxProperty getFauxPropertyFromContextUri(String contextUri) { public FauxProperty getFauxPropertyFromContextUri(String contextUri) {
getOntModel().enterCriticalSection(Lock.READ); try (LockedOntModel displayModel = models.getDisplayModel().read()) {
try {
if (contextUri == null) { if (contextUri == null) {
return null; return null;
} }
Resource context = createResource(contextUri); OntResource context = displayModel.createOntResource(contextUri);
if (!getOntModel().contains(context, RDF.type, CONFIG_CONTEXT)) { if (!displayModel.contains(context, RDF.type, CONFIG_CONTEXT)) {
log.debug("'" + contextUri + "' is not a CONFIG_CONTEXT"); log.debug("'" + contextUri + "' is not a CONFIG_CONTEXT");
return null; return null;
} }
String baseUri = getUriValue(getOntModel(), context, Collection<String> baseUris = getPropertyResourceURIValues(context,
CONFIG_CONTEXT_FOR); CONFIG_CONTEXT_FOR);
if (baseUri == null) { if (baseUris.isEmpty()) {
log.debug("'" + contextUri + "' has no value for '" log.debug("'" + contextUri + "' has no value for '"
+ CONFIG_CONTEXT_FOR + "'"); + CONFIG_CONTEXT_FOR + "'");
return null; return null;
} }
String baseUri = baseUris.iterator().next();
String rangeUri = getUriValue(getOntModel(), context, Collection<String> rangeUris = getPropertyResourceURIValues(
QUALIFIED_BY_RANGE); context, QUALIFIED_BY_RANGE);
if (rangeUri == null) { if (rangeUris.isEmpty()) {
log.debug("'" + contextUri + "' has no value for '" log.debug("'" + contextUri + "' has no value for '"
+ QUALIFIED_BY_RANGE + "'"); + QUALIFIED_BY_RANGE + "'");
return null; return null;
} }
String rangeUri = rangeUris.iterator().next();
// domainURI is optional. // domainURI is optional.
String domainUri = getUriValue(getOntModel(), context, Collection<String> domainUris = getPropertyResourceURIValues(
QUALIFIED_BY_DOMAIN); context, QUALIFIED_BY_DOMAIN);
String domainUri = domainUris.isEmpty() ? null : domainUris
.iterator().next();
FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri); FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri);
populateInstance(fp, context); fp.setContextUri(contextUri);
populateInstance(fp);
return fp; return fp;
} finally {
getOntModel().leaveCriticalSection();
} }
} }
@ -164,36 +165,32 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
public FauxProperty getFauxPropertyByUris(String domainUri, String baseUri, public FauxProperty getFauxPropertyByUris(String domainUri, String baseUri,
String rangeUri) { String rangeUri) {
Set<ConfigContext> contexts = ConfigContext.findByQualifiers( Set<ConfigContext> contexts = ConfigContext.findByQualifiers(
getOntModelSelector().getDisplayModel(), domainUri, baseUri, models.getDisplayModel(), domainUri, baseUri, rangeUri);
rangeUri); if (contexts.isEmpty()) {
for (ConfigContext context : contexts) {
FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri);
populateInstance(fp, createResource(context.getContextUri()));
return fp;
}
log.debug("Can't find a FauxProperty for '" + domainUri + "', '" log.debug("Can't find a FauxProperty for '" + domainUri + "', '"
+ baseUri + "', '" + rangeUri + "'"); + baseUri + "', '" + rangeUri + "'");
return null; return null;
} else {
FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri);
fp.setContextUri(contexts.iterator().next().getContextUri());
populateInstance(fp);
return fp;
}
} }
@Override @Override
public void insertFauxProperty(FauxProperty fp) { public void insertFauxProperty(FauxProperty fp) {
if ((fp.getContextUri() != null) || (fp.getConfigUri() == null)) { if ((fp.getContextUri() != null) || (fp.getConfigUri() == null)) {
throw new IllegalStateException( throw new IllegalStateException(
"ContextUri and ConfigUri must be null on insert: contextUri=" "ContextUri and ConfigUri must be null on insert: " + fp);
+ fp.getContextUri() + ", configUri="
+ fp.getConfigUri());
} }
Set<ConfigContext> existingcontexts = ConfigContext.findByQualifiers( Set<ConfigContext> existingcontexts = ConfigContext.findByQualifiers(
getOntModelSelector().getDisplayModel(), fp.getDomainURI(), models.getDisplayModel(), fp.getDomainURI(), fp.getBaseURI(),
fp.getBaseURI(), fp.getRangeURI()); fp.getRangeURI());
if (!existingcontexts.isEmpty()) { if (!existingcontexts.isEmpty()) {
throw new IllegalStateException( throw new IllegalStateException(
"FauxProperty already exists with domainUri=" "FauxProperty with these qualifiers already exists: " + fp);
+ fp.getDomainURI() + ", baseUri="
+ fp.getBaseURI() + ", rangeUri="
+ fp.getRangeURI());
} }
try { try {
@ -203,10 +200,9 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
throw new RuntimeException(e); throw new RuntimeException(e);
} }
getOntModel().enterCriticalSection(Lock.WRITE); try (LockedOntModel displayModel = models.getDisplayModel().write()) {
try { OntResource context = displayModel.createOntResource(fp
OntResource context = getOntModel().createOntResource( .getContextUri());
fp.getContextUri());
addPropertyResourceValue(context, RDF.type, CONFIG_CONTEXT); addPropertyResourceValue(context, RDF.type, CONFIG_CONTEXT);
addPropertyResourceURIValue(context, HAS_CONFIGURATION, addPropertyResourceURIValue(context, HAS_CONFIGURATION,
fp.getConfigUri()); fp.getConfigUri());
@ -217,39 +213,36 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
addPropertyResourceURIValue(context, QUALIFIED_BY_DOMAIN, addPropertyResourceURIValue(context, QUALIFIED_BY_DOMAIN,
fp.getDomainURI()); fp.getDomainURI());
OntResource config = getOntModel().createOntResource( OntResource config = displayModel.createOntResource(fp
fp.getConfigUri()); .getConfigUri());
addPropertyResourceValue(config, RDF.type, addPropertyResourceValue(config, RDF.type,
OBJECT_PROPERTY_DISPLAY_CONFIG); OBJECT_PROPERTY_DISPLAY_CONFIG);
addPropertyResourceURIValue(config, PROPERTY_GROUP, addPropertyResourceURIValue(config, PROPERTY_GROUP,
fp.getGroupURI()); fp.getGroupURI());
addPropertyStringValue(config, DISPLAY_NAME, fp.getDisplayName(), addPropertyStringValue(config, DISPLAY_NAME, fp.getDisplayName(),
getOntModel()); displayModel);
addPropertyStringValue(config, PUBLIC_DESCRIPTION_ANNOT, addPropertyStringValue(config, PUBLIC_DESCRIPTION_ANNOT,
fp.getPublicDescription(), getOntModel()); fp.getPublicDescription(), displayModel);
addPropertyIntValue(config, DISPLAY_RANK_ANNOT, addPropertyIntValue(config, DISPLAY_RANK_ANNOT,
fp.getDisplayTier(), getOntModel()); fp.getDisplayTier(), displayModel);
addPropertyIntValue(config, DISPLAY_LIMIT, fp.getDisplayLimit(), addPropertyIntValue(config, DISPLAY_LIMIT, fp.getDisplayLimit(),
getOntModel()); displayModel);
addPropertyBooleanValue(config, PROPERTY_COLLATEBYSUBCLASSANNOT, addPropertyBooleanValue(config, PROPERTY_COLLATEBYSUBCLASSANNOT,
fp.isCollateBySubclass(), getOntModel()); fp.isCollateBySubclass(), displayModel);
addPropertyBooleanValue(config, PROPERTY_SELECTFROMEXISTINGANNOT, addPropertyBooleanValue(config, PROPERTY_SELECTFROMEXISTINGANNOT,
fp.isSelectFromExisting(), getOntModel()); fp.isSelectFromExisting(), displayModel);
addPropertyBooleanValue(config, PROPERTY_OFFERCREATENEWOPTIONANNOT, addPropertyBooleanValue(config, PROPERTY_OFFERCREATENEWOPTIONANNOT,
fp.isOfferCreateNewOption(), getOntModel()); fp.isOfferCreateNewOption(), displayModel);
addPropertyStringValue(config, PROPERTY_CUSTOMENTRYFORMANNOT, addPropertyStringValue(config, PROPERTY_CUSTOMENTRYFORMANNOT,
fp.getCustomEntryForm(), getOntModel()); fp.getCustomEntryForm(), displayModel);
addPropertyStringValue(config, LIST_VIEW_FILE, addPropertyStringValue(config, LIST_VIEW_FILE,
fp.getCustomListView(), getOntModel()); fp.getCustomListView(), displayModel);
} finally {
getOntModel().leaveCriticalSection();
} }
} }
@Override @Override
public void updateFauxProperty(FauxProperty fp) { public void updateFauxProperty(FauxProperty fp) {
getOntModel().enterCriticalSection(Lock.READ); try (LockedOntModel displayModel = models.getDisplayModel().read()) {
try {
if (fp.getContextUri() == null) { if (fp.getContextUri() == null) {
throw new IllegalStateException("ContextURI may not be null: " throw new IllegalStateException("ContextURI may not be null: "
+ fp); + fp);
@ -262,78 +255,71 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
} }
Resource config = createResource(fp.getConfigUri()); Resource config = createResource(fp.getConfigUri());
if (!getOntModel().contains(context, RDF.type, CONFIG_CONTEXT)) { if (!displayModel.contains(context, RDF.type, CONFIG_CONTEXT)) {
throw new IllegalStateException("'" + context + "' is not a '" throw new IllegalStateException("'" + context + "' is not a '"
+ CONFIG_CONTEXT + "'"); + CONFIG_CONTEXT + "'");
} }
if (!getOntModel().contains(config, RDF.type, if (!displayModel.contains(config, RDF.type,
OBJECT_PROPERTY_DISPLAY_CONFIG)) { OBJECT_PROPERTY_DISPLAY_CONFIG)) {
throw new IllegalStateException("'" + config + "' is not a '" throw new IllegalStateException("'" + config + "' is not a '"
+ OBJECT_PROPERTY_DISPLAY_CONFIG + "'"); + OBJECT_PROPERTY_DISPLAY_CONFIG + "'");
} }
if (!getOntModel().contains(context, HAS_CONFIGURATION, config)) { if (!displayModel.contains(context, HAS_CONFIGURATION, config)) {
throw new IllegalStateException("'" + config throw new IllegalStateException("'" + config
+ "' is not a configuration for '" + context + "'"); + "' is not a configuration for '" + context + "'");
} }
} finally {
getOntModel().leaveCriticalSection();
} }
getOntModel().enterCriticalSection(Lock.WRITE); try (LockedOntModel displayModel = models.getDisplayModel().write()) {
try { OntResource context = displayModel.createOntResource(fp
OntResource context = getOntModel().createOntResource( .getContextUri());
fp.getContextUri());
updatePropertyResourceURIValue(context, QUALIFIED_BY_RANGE, updatePropertyResourceURIValue(context, QUALIFIED_BY_RANGE,
fp.getRangeURI()); fp.getRangeURI());
updatePropertyResourceURIValue(context, QUALIFIED_BY_DOMAIN, updatePropertyResourceURIValue(context, QUALIFIED_BY_DOMAIN,
fp.getDomainURI()); fp.getDomainURI());
OntResource config = getOntModel().createOntResource( OntResource config = displayModel.createOntResource(fp
fp.getConfigUri()); .getConfigUri());
updatePropertyResourceURIValue(config, PROPERTY_GROUP, updatePropertyResourceURIValue(config, PROPERTY_GROUP,
fp.getGroupURI()); fp.getGroupURI());
updatePropertyStringValue(config, DISPLAY_NAME, fp.getDisplayName(), updatePropertyStringValue(config, DISPLAY_NAME,
getOntModel()); fp.getDisplayName(), displayModel);
updatePropertyStringValue(config, PUBLIC_DESCRIPTION_ANNOT, updatePropertyStringValue(config, PUBLIC_DESCRIPTION_ANNOT,
fp.getPublicDescription(), getOntModel()); fp.getPublicDescription(), displayModel);
updatePropertyIntValue(config, DISPLAY_RANK_ANNOT, updatePropertyIntValue(config, DISPLAY_RANK_ANNOT,
fp.getDisplayTier(), getOntModel()); fp.getDisplayTier(), displayModel);
updatePropertyIntValue(config, DISPLAY_LIMIT, fp.getDisplayLimit(), updatePropertyIntValue(config, DISPLAY_LIMIT, fp.getDisplayLimit(),
getOntModel()); displayModel);
updatePropertyBooleanValue(config, PROPERTY_COLLATEBYSUBCLASSANNOT, updatePropertyBooleanValue(config, PROPERTY_COLLATEBYSUBCLASSANNOT,
fp.isCollateBySubclass(), getOntModel(), true); fp.isCollateBySubclass(), displayModel, true);
updatePropertyBooleanValue(config, PROPERTY_SELECTFROMEXISTINGANNOT, updatePropertyBooleanValue(config,
fp.isSelectFromExisting(), getOntModel(), true); PROPERTY_SELECTFROMEXISTINGANNOT,
updatePropertyBooleanValue(config, PROPERTY_OFFERCREATENEWOPTIONANNOT, fp.isSelectFromExisting(), displayModel, true);
fp.isOfferCreateNewOption(), getOntModel(), true); updatePropertyBooleanValue(config,
PROPERTY_OFFERCREATENEWOPTIONANNOT,
fp.isOfferCreateNewOption(), displayModel, true);
updatePropertyStringValue(config, PROPERTY_CUSTOMENTRYFORMANNOT, updatePropertyStringValue(config, PROPERTY_CUSTOMENTRYFORMANNOT,
fp.getCustomEntryForm(), getOntModel()); fp.getCustomEntryForm(), displayModel);
updatePropertyStringValue(config, LIST_VIEW_FILE, updatePropertyStringValue(config, LIST_VIEW_FILE,
fp.getCustomListView(), getOntModel()); fp.getCustomListView(), displayModel);
} finally {
getOntModel().leaveCriticalSection();
} }
} }
@Override @Override
public void deleteFauxProperty(FauxProperty fp) { public void deleteFauxProperty(FauxProperty fp) {
Set<ConfigContext> contexts = ConfigContext.findByQualifiers( Set<ConfigContext> contexts = ConfigContext.findByQualifiers(
getOntModelSelector().getDisplayModel(), fp.getDomainURI(), models.getDisplayModel(), fp.getDomainURI(), fp.getURI(),
fp.getURI(), fp.getRangeURI()); fp.getRangeURI());
getOntModel().enterCriticalSection(Lock.READ); try (LockedOntModel displayModel = models.getDisplayModel().write()) {
try {
for (ConfigContext context : contexts) { for (ConfigContext context : contexts) {
Resource configResource = createResource(context.getConfigUri()); Resource configResource = createResource(context.getConfigUri());
getOntModel().removeAll(configResource, null, null); displayModel.removeAll(configResource, null, null);
getOntModel().removeAll(null, null, configResource); displayModel.removeAll(null, null, configResource);
Resource contextResource = createResource(context Resource contextResource = createResource(context
.getContextUri()); .getContextUri());
getOntModel().removeAll(contextResource, null, null); displayModel.removeAll(contextResource, null, null);
getOntModel().removeAll(null, null, contextResource); displayModel.removeAll(null, null, contextResource);
} }
} finally {
getOntModel().leaveCriticalSection();
} }
} }
@ -357,11 +343,8 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
} }
private boolean isUriUsed(String uri) { private boolean isUriUsed(String uri) {
getOntModel().enterCriticalSection(Lock.READ); try (LockedOntModel displayModel = models.getDisplayModel().read()) {
try { return (displayModel.getOntResource(uri) != null);
return (getOntModel().getOntResource(uri) != null);
} finally {
getOntModel().leaveCriticalSection();
} }
} }
@ -369,9 +352,9 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
* Add labels, annotations, and whatever else we can find on the * Add labels, annotations, and whatever else we can find on the
* ObjectPropertyDisplayConfig. * ObjectPropertyDisplayConfig.
*/ */
private void populateInstance(FauxProperty fp, Resource context) { private void populateInstance(FauxProperty fp) {
populateLabelsFromTBox(fp); populateLabelsFromTBox(fp);
populateFieldsFromDisplayModel(fp, context); populateFieldsFromDisplayModel(fp);
} }
private void populateLabelsFromTBox(FauxProperty fp) { private void populateLabelsFromTBox(FauxProperty fp) {
@ -383,23 +366,19 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
if (classUri == null) { if (classUri == null) {
return null; return null;
} else { } else {
OntModel tboxModel = getOntModelSelector().getTBoxModel(); try (LockedOntModel tboxModel = models.getTBoxModel().read()) {
tboxModel.enterCriticalSection(Lock.READ); return getPropertyStringValue(
try { tboxModel.createOntResource(classUri), RDFS_LABEL);
return getStringValue(tboxModel, createResource(classUri),
RDFS_LABEL);
} finally {
tboxModel.leaveCriticalSection();
} }
} }
} }
private void populateFieldsFromDisplayModel(FauxProperty fp, private void populateFieldsFromDisplayModel(FauxProperty fp) {
Resource context) { String configUri = locateConfigurationFromContext(fp.getContextUri());
OntResource config = locateConfigurationFromContext(context); fp.setConfigUri(configUri);
if (config != null) { if (configUri != null) {
getOntModel().enterCriticalSection(Lock.READ); try (LockedOntModel displayModel = models.getDisplayModel().read()) {
try { OntResource config = displayModel.createOntResource(configUri);
fp.setDisplayName(getPropertyStringValue(config, DISPLAY_NAME)); fp.setDisplayName(getPropertyStringValue(config, DISPLAY_NAME));
fp.setPublicDescription(getPropertyStringValue(config, fp.setPublicDescription(getPropertyStringValue(config,
PUBLIC_DESCRIPTION_ANNOT)); PUBLIC_DESCRIPTION_ANNOT));
@ -417,24 +396,20 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
PROPERTY_OFFERCREATENEWOPTIONANNOT)); PROPERTY_OFFERCREATENEWOPTIONANNOT));
fp.setCustomEntryForm(getPropertyStringValue(config, fp.setCustomEntryForm(getPropertyStringValue(config,
PROPERTY_CUSTOMENTRYFORMANNOT)); PROPERTY_CUSTOMENTRYFORMANNOT));
} finally {
getOntModel().leaveCriticalSection();
} }
} }
} }
private OntResource locateConfigurationFromContext(Resource context) { private String locateConfigurationFromContext(String contextUri) {
getOntModel().enterCriticalSection(Lock.READ); try (LockedOntModel displayModel = models.getDisplayModel().read()) {
try { Collection<String> configUris = getPropertyResourceURIValues(
String configUri = getUriValue(getOntModel(), context, displayModel.createOntResource(contextUri),
HAS_CONFIGURATION); HAS_CONFIGURATION);
if (configUri == null) { if (configUris.isEmpty()) {
return null; return null;
} else { } else {
return getOntModel().createOntResource(configUri); return configUris.iterator().next();
} }
} finally {
getOntModel().leaveCriticalSection();
} }
} }
@ -448,64 +423,6 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
} }
} }
/**
* Returns a single URI that is the object of this subject and property.
* Returns null if no valid statement is found.
*
* The model should already be locked.
*/
private String getUriValue(OntModel model, Resource subject,
Property property) {
List<RDFNode> nodeList = model.listObjectsOfProperty(subject, property)
.toList();
if (nodeList.isEmpty()) {
log.warn("'" + subject.getURI() + "' has no value for '"
+ property.getURI() + "'.");
return null;
}
RDFNode node = nodeList.get(0);
if (nodeList.size() > 1) {
log.warn("'" + subject.getURI() + "' has " + nodeList.size()
+ " values for ''. Using '" + node + "'");
}
if (!node.isURIResource()) {
log.warn("Value of '" + subject.getURI() + property.getURI()
+ "' '' is not a URI resource.");
return null;
}
return node.asResource().getURI();
}
/**
* Returns a single String value that is the object of this subject and
* property. Returns null if no valid statement is found.
*
* The model should already be locked.
*/
private String getStringValue(OntModel model, Resource subject,
Property property) {
List<RDFNode> nodeList = model.listObjectsOfProperty(subject, property)
.toList();
if (nodeList.isEmpty()) {
log.warn("'" + subject.getURI() + "' has no value for '"
+ property.getURI() + "'.");
return null;
}
RDFNode node = nodeList.get(0);
if (nodeList.size() > 1) {
log.warn("'" + subject.getURI() + "' has " + nodeList.size()
+ " values for ''. Using '" + node + "'");
}
if (!node.isLiteral()) {
log.warn("Value of '" + subject.getURI() + property.getURI()
+ "' '' is not a Literal.");
return null;
}
return node.asLiteral().getString();
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// ConfigContext // ConfigContext
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -572,10 +489,9 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
private static class ConfigContext { private static class ConfigContext {
public static Set<ConfigContext> findByQualifiers( public static Set<ConfigContext> findByQualifiers(
OntModel displayModel, String domainUri, String baseUri, LockableOntModel lockableDisplayModel, String domainUri,
String rangeUri) { String baseUri, String rangeUri) {
displayModel.enterCriticalSection(Lock.READ); try (LockedOntModel displayModel = lockableDisplayModel.read()) {
try {
String queryString; String queryString;
if (domainUri == null) { if (domainUri == null) {
queryString = bindValues( queryString = bindValues(
@ -594,8 +510,6 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
domainUri, baseUri, rangeUri); domainUri, baseUri, rangeUri);
return new SparqlQueryRunner(displayModel).executeSelect( return new SparqlQueryRunner(displayModel).executeSelect(
parser, queryString); parser, queryString);
} finally {
displayModel.leaveCriticalSection();
} }
} }

View file

@ -120,7 +120,7 @@ public class ConfigurationBeanLoader {
public <T> Set<T> loadAll(Class<T> resultClass) public <T> Set<T> loadAll(Class<T> resultClass)
throws ConfigurationBeanLoaderException { throws ConfigurationBeanLoaderException {
Set<String> uris = new HashSet<>(); Set<String> uris = new HashSet<>();
try (Critical section = Critical.read(model)) { try (Critical.Section section = Critical.Section.read(model)) {
List<Resource> resources = model.listResourcesWithProperty( List<Resource> resources = model.listResourcesWithProperty(
RDF.type, createResource(toJavaUri(resultClass))).toList(); RDF.type, createResource(toJavaUri(resultClass))).toList();
for (Resource r : resources) { for (Resource r : resources) {

View file

@ -58,7 +58,7 @@ public class ConfigurationRdfParser {
throws InvalidConfigurationRdfException { throws InvalidConfigurationRdfException {
Selector s = new SimpleSelector(createResource(uri), null, Selector s = new SimpleSelector(createResource(uri), null,
(RDFNode) null); (RDFNode) null);
try (Critical section = Critical.read(model)) { try (Critical.Section section = Critical.Section.read(model)) {
if (model.listStatements(s).toList().isEmpty()) { if (model.listStatements(s).toList().isEmpty()) {
throw individualDoesNotAppearInModel(uri); throw individualDoesNotAppearInModel(uri);
} }
@ -70,7 +70,7 @@ public class ConfigurationRdfParser {
throws InvalidConfigurationRdfException { throws InvalidConfigurationRdfException {
Statement s = createStatement(createResource(uri), RDF.type, Statement s = createStatement(createResource(uri), RDF.type,
createResource(toJavaUri(resultClass))); createResource(toJavaUri(resultClass)));
try (Critical section = Critical.read(model)) { try (Critical.Section section = Critical.Section.read(model)) {
if (!model.contains(s)) { if (!model.contains(s)) {
throw noTypeStatementForResultClass(s); throw noTypeStatementForResultClass(s);
} }
@ -81,7 +81,7 @@ public class ConfigurationRdfParser {
throws InvalidConfigurationRdfException { throws InvalidConfigurationRdfException {
Set<PropertyStatement> set = new HashSet<>(); Set<PropertyStatement> set = new HashSet<>();
try (Critical section = Critical.read(model)) { try (Critical.Section section = Critical.Section.read(model)) {
List<Statement> rawStatements = model.listStatements( List<Statement> rawStatements = model.listStatements(
model.getResource(uri), (Property) null, (RDFNode) null) model.getResource(uri), (Property) null, (RDFNode) null)
.toList(); .toList();
@ -111,7 +111,7 @@ public class ConfigurationRdfParser {
throws InvalidConfigurationRdfException { throws InvalidConfigurationRdfException {
Set<Class<? extends T>> concreteClasses = new HashSet<>(); Set<Class<? extends T>> concreteClasses = new HashSet<>();
try (Critical section = Critical.read(model)) { try (Critical.Section section = Critical.Section.read(model)) {
for (RDFNode node : model.listObjectsOfProperty( for (RDFNode node : model.listObjectsOfProperty(
createResource(uri), RDF.type).toSet()) { createResource(uri), RDF.type).toSet()) {
if (!node.isURIResource()) { if (!node.isURIResource()) {

View file

@ -5,28 +5,39 @@ 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.READ;
import static com.hp.hpl.jena.shared.Lock.WRITE; 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.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.AbstractOntModelDecorator;
/** /**
* Use this in a try-with-resources block. * AutoCloseable helper classes for using models in a try-with-resources block.
*/
public abstract class Critical {
/**
* Use this when you have a bare model, and you want to control a critical
* section.
* *
* <pre> * <pre>
* try (Critical section = Critical.read(model)) { * try (Critical.Section section = Critical.Section.read(model)) {
* ...
* } * }
* </pre> * </pre>
*/ */
public class Critical implements AutoCloseable { public static class Section implements AutoCloseable {
public static Critical read(Model model) { public static Section read(Model model) {
return new Critical(model, READ); return new Section(model, READ);
} }
public static Critical write(Model model) { public static Section write(Model model) {
return new Critical(model, WRITE); return new Section(model, WRITE);
} }
private final Model model; private final Model model;
private Critical(Model model, boolean readLockRequested) { private Section(Model model, boolean readLockRequested) {
this.model = model; this.model = model;
this.model.enterCriticalSection(readLockRequested); this.model.enterCriticalSection(readLockRequested);
} }
@ -35,5 +46,81 @@ public class Critical implements AutoCloseable {
public void close() { public void close() {
this.model.leaveCriticalSection(); this.model.leaveCriticalSection();
} }
}
/**
* Use this when you have a bare OntModelSelector. It returns
* LockableOntModels, which can then be locked in a critical section.
*
* <pre>
* LockingOntModelSelector lockingOms = new LockingOntModelSelector(oms);
* </pre>
*/
public static class LockingOntModelSelector {
private final OntModelSelector oms;
public LockingOntModelSelector(OntModelSelector oms) {
this.oms = oms;
}
public LockableOntModel getDisplayModel() {
return new LockableOntModel(oms.getDisplayModel());
}
public LockableOntModel getTBoxModel() {
return new LockableOntModel(oms.getTBoxModel());
}
}
/**
* Returned by the LockingOntModelSelector, or it can be wrapped around a
* bare OntModel.
*
* <pre>
* try (LockedOntModel m = lockingOms.getDisplayModel.read()) {
* ...
* }
* </pre>
*/
public static class LockableOntModel {
private final OntModel ontModel;
public LockableOntModel(OntModel ontModel) {
this.ontModel = ontModel;
}
public LockedOntModel read() {
ontModel.enterCriticalSection(Lock.READ);
return new LockedOntModel(ontModel);
}
public LockedOntModel write() {
ontModel.enterCriticalSection(Lock.WRITE);
return new LockedOntModel(ontModel);
}
}
/**
* 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.
*/
public static class LockedOntModel extends AbstractOntModelDecorator
implements AutoCloseable {
private LockedOntModel(OntModel 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();
}
}
} }