Merge branch 'develop' into feature/fauxEditing
Conflicts: webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoader.java webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationRdfParser.java webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/Critical.java
This commit is contained in:
commit
2fa9583569
16 changed files with 294 additions and 207 deletions
|
@ -34,9 +34,9 @@ import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||
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;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModelSelector;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedOntModel;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
|
@ -80,11 +80,11 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
|
|||
// The instance
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private final LockingOntModelSelector models;
|
||||
private final LockableOntModelSelector models;
|
||||
|
||||
public FauxPropertyDaoJena(WebappDaoFactoryJena wadf) {
|
||||
super(wadf);
|
||||
this.models = new LockingOntModelSelector(wadf.getOntModelSelector());
|
||||
this.models = new LockableOntModelSelector(wadf.getOntModelSelector());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -126,4 +126,9 @@ public class LoggingRDFService implements RDFService {
|
|||
public void close() {
|
||||
innerService.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LoggingRDFService[inner=" + innerService + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,4 +40,9 @@ public class LoggingRDFServiceFactory implements RDFServiceFactory {
|
|||
factory.unregisterListener(changeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LoggingRDFServiceFactory[factory=" + factory + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.UnionModelsOntMode
|
|||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.sdb.RDFServiceFactorySDB;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
|
||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ContentDataStructuresProvider;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
|
@ -122,7 +123,8 @@ public class ContentDataStructuresProviderSDB extends
|
|||
setupSDB(store);
|
||||
}
|
||||
|
||||
return new RDFServiceFactorySDB(ds, storeDesc);
|
||||
return new LoggingRDFServiceFactory(new RDFServiceFactorySDB(ds,
|
||||
storeDesc));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,7 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache;
|
|||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sparql.RDFServiceSparql;
|
||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ContentDataStructuresProvider;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
|
@ -58,8 +59,8 @@ public class ContentDataStructuresProviderSPARQL extends
|
|||
this.updateEndpointURI = props
|
||||
.getProperty(PROPERTY_SPARQL_UPDATE_ENDPOINT_URI);
|
||||
|
||||
this.rdfService = createRDFService();
|
||||
this.rdfServiceFactory = createRDFServiceFactory();
|
||||
this.rdfServiceFactory = createRDFServiceFactory(createRDFService());
|
||||
this.rdfService = this.rdfServiceFactory.getRDFService();
|
||||
this.dataset = createDataset();
|
||||
this.modelMaker = createModelMaker();
|
||||
}
|
||||
|
@ -75,8 +76,9 @@ public class ContentDataStructuresProviderSPARQL extends
|
|||
}
|
||||
}
|
||||
|
||||
private RDFServiceFactory createRDFServiceFactory() {
|
||||
return new RDFServiceFactorySingle(this.rdfService);
|
||||
private RDFServiceFactory createRDFServiceFactory(RDFService service) {
|
||||
return new LoggingRDFServiceFactory(
|
||||
new RDFServiceFactorySingle(service));
|
||||
}
|
||||
|
||||
private Dataset createDataset() {
|
||||
|
|
|
@ -22,6 +22,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
|||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.tdb.RDFServiceTDB;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ConfigurationDataStructuresProvider;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
|
||||
|
@ -60,8 +61,8 @@ public class ConfigurationDataStructuresProviderTDB extends
|
|||
+ DIRECTORY_TDB;
|
||||
|
||||
try {
|
||||
this.rdfService = new RDFServiceTDB(tdbPath);
|
||||
this.rdfServiceFactory = createRDFServiceFactory();
|
||||
this.rdfServiceFactory = createRDFServiceFactory(tdbPath);
|
||||
this.rdfService = this.rdfServiceFactory.getRDFService();
|
||||
this.dataset = new RDFServiceDataset(this.rdfService);
|
||||
this.modelMaker = createModelMaker();
|
||||
ss.info(ctxListener, "Initialized the RDF source for TDB");
|
||||
|
@ -75,8 +76,10 @@ public class ConfigurationDataStructuresProviderTDB extends
|
|||
TDB.getContext().setTrue(TDB.symUnionDefaultGraph);
|
||||
}
|
||||
|
||||
private RDFServiceFactory createRDFServiceFactory() {
|
||||
return new RDFServiceFactorySingle(this.rdfService);
|
||||
private RDFServiceFactory createRDFServiceFactory(String tdbPath)
|
||||
throws IOException {
|
||||
return new LoggingRDFServiceFactory(new RDFServiceFactorySingle(
|
||||
new RDFServiceTDB(tdbPath)));
|
||||
}
|
||||
|
||||
private ModelMaker createModelMaker() {
|
||||
|
|
|
@ -21,6 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
|||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.tdb.RDFServiceTDB;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ContentDataStructuresProvider;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
|
||||
|
@ -74,7 +75,8 @@ public class ContentDataStructuresProviderTDB extends
|
|||
}
|
||||
|
||||
private RDFServiceFactory createRDFServiceFactory() {
|
||||
return new RDFServiceFactorySingle(this.rdfService);
|
||||
return new LoggingRDFServiceFactory(new RDFServiceFactorySingle(
|
||||
this.rdfService));
|
||||
}
|
||||
|
||||
private ModelMaker createModelMaker() {
|
||||
|
|
|
@ -6,6 +6,7 @@ import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
|
|||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
@ -15,8 +16,8 @@ import com.hp.hpl.jena.rdf.model.Model;
|
|||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
import com.hp.hpl.jena.vocabulary.RDF;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockableModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockedModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedModel;
|
||||
|
||||
/**
|
||||
* Load one or more Configuration beans from a specified model.
|
||||
|
@ -50,7 +51,7 @@ public class ConfigurationBeanLoader {
|
|||
// ----------------------------------------------------------------------
|
||||
|
||||
/** Must not be null. */
|
||||
private final LockableModel model;
|
||||
private final LockableModel locking;
|
||||
|
||||
/**
|
||||
* May be null, but the loader will be unable to satisfy instances of
|
||||
|
@ -65,26 +66,34 @@ public class ConfigurationBeanLoader {
|
|||
private final HttpServletRequest req;
|
||||
|
||||
public ConfigurationBeanLoader(Model model) {
|
||||
this(model, null, null);
|
||||
this(new LockableModel(model), null, null);
|
||||
}
|
||||
|
||||
public ConfigurationBeanLoader(LockableModel locking) {
|
||||
this(locking, null, null);
|
||||
}
|
||||
|
||||
public ConfigurationBeanLoader(Model model, ServletContext ctx) {
|
||||
this(model, ctx, null);
|
||||
this(new LockableModel(model), ctx, null);
|
||||
}
|
||||
|
||||
public ConfigurationBeanLoader(LockableModel locking, ServletContext ctx) {
|
||||
this(locking, ctx, null);
|
||||
}
|
||||
|
||||
public ConfigurationBeanLoader(Model model, HttpServletRequest req) {
|
||||
this(model,
|
||||
(req == null) ? null : req.getSession().getServletContext(),
|
||||
req);
|
||||
this(new LockableModel(model), req);
|
||||
}
|
||||
|
||||
private ConfigurationBeanLoader(Model model, ServletContext ctx,
|
||||
public ConfigurationBeanLoader(LockableModel locking, HttpServletRequest req) {
|
||||
this(locking, (req == null) ? null : req.getSession()
|
||||
.getServletContext(), req);
|
||||
}
|
||||
|
||||
private ConfigurationBeanLoader(LockableModel locking, ServletContext ctx,
|
||||
HttpServletRequest req) {
|
||||
if (model == null) {
|
||||
throw new NullPointerException("model may not be null.");
|
||||
}
|
||||
|
||||
this.model = new LockableModel(model);
|
||||
this.locking = Objects.requireNonNull(locking,
|
||||
"locking may not be null.");
|
||||
this.req = req;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
@ -102,8 +111,8 @@ public class ConfigurationBeanLoader {
|
|||
}
|
||||
|
||||
try {
|
||||
ConfigurationRdf<T> parsedRdf = ConfigurationRdfParser.parse(model,
|
||||
uri, resultClass);
|
||||
ConfigurationRdf<T> parsedRdf = ConfigurationRdfParser.parse(
|
||||
locking, uri, resultClass);
|
||||
WrappedInstance<T> wrapper = InstanceWrapper.wrap(parsedRdf
|
||||
.getConcreteClass());
|
||||
wrapper.satisfyInterfaces(ctx, req);
|
||||
|
@ -122,7 +131,7 @@ public class ConfigurationBeanLoader {
|
|||
public <T> Set<T> loadAll(Class<T> resultClass)
|
||||
throws ConfigurationBeanLoaderException {
|
||||
Set<String> uris = new HashSet<>();
|
||||
try (LockedModel m = model.read()) {
|
||||
try (LockedModel m = locking.read()) {
|
||||
List<Resource> resources = m.listResourcesWithProperty(RDF.type,
|
||||
createResource(toJavaUri(resultClass))).toList();
|
||||
for (Resource r : resources) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import static edu.cornell.mannlib.vitro.webapp.utils.configuration.Configuration
|
|||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Property;
|
||||
|
@ -22,67 +23,61 @@ 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.LockableModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockedModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedModel;
|
||||
|
||||
/**
|
||||
* Parse the RDF for a single individual in the model to create a
|
||||
* ConfigurationRdf object.
|
||||
*/
|
||||
public class ConfigurationRdfParser {
|
||||
public static <T> ConfigurationRdf<T> parse(LockableModel model,
|
||||
public static <T> ConfigurationRdf<T> parse(LockableModel locking,
|
||||
String uri, Class<T> resultClass)
|
||||
throws InvalidConfigurationRdfException {
|
||||
if (model == null) {
|
||||
throw new NullPointerException("model may not be null.");
|
||||
}
|
||||
if (uri == null) {
|
||||
throw new NullPointerException("uri may not be null.");
|
||||
}
|
||||
if (resultClass == null) {
|
||||
throw new NullPointerException("resultClass may not be null.");
|
||||
}
|
||||
Objects.requireNonNull(locking, "locking may not be null.");
|
||||
Objects.requireNonNull(uri, "uri may not be null.");
|
||||
Objects.requireNonNull(resultClass, "resultClass may not be null.");
|
||||
|
||||
confirmExistenceInModel(model, uri);
|
||||
confirmExistenceInModel(locking, uri);
|
||||
|
||||
confirmEligibilityForResultClass(model, uri, resultClass);
|
||||
confirmEligibilityForResultClass(locking, uri, resultClass);
|
||||
|
||||
Set<PropertyStatement> properties = loadProperties(model, uri);
|
||||
Set<PropertyStatement> properties = loadProperties(locking, uri);
|
||||
|
||||
Class<? extends T> concreteClass = determineConcreteClass(model, uri,
|
||||
Class<? extends T> concreteClass = determineConcreteClass(locking, uri,
|
||||
resultClass);
|
||||
|
||||
return new ConfigurationRdf<T>(concreteClass, properties);
|
||||
}
|
||||
|
||||
private static void confirmExistenceInModel(LockableModel model, String uri)
|
||||
throws InvalidConfigurationRdfException {
|
||||
private static void confirmExistenceInModel(LockableModel locking,
|
||||
String uri) throws InvalidConfigurationRdfException {
|
||||
Selector s = new SimpleSelector(createResource(uri), null,
|
||||
(RDFNode) null);
|
||||
try (LockedModel m = model.read()) {
|
||||
try (LockedModel m = locking.read()) {
|
||||
if (m.listStatements(s).toList().isEmpty()) {
|
||||
throw individualDoesNotAppearInModel(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void confirmEligibilityForResultClass(LockableModel model,
|
||||
private static void confirmEligibilityForResultClass(LockableModel locking,
|
||||
String uri, Class<?> resultClass)
|
||||
throws InvalidConfigurationRdfException {
|
||||
Statement s = createStatement(createResource(uri), RDF.type,
|
||||
createResource(toJavaUri(resultClass)));
|
||||
try (LockedModel m = model.read()) {
|
||||
try (LockedModel m = locking.read()) {
|
||||
if (!m.contains(s)) {
|
||||
throw noTypeStatementForResultClass(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<PropertyStatement> loadProperties(LockableModel model,
|
||||
private static Set<PropertyStatement> loadProperties(LockableModel locking,
|
||||
String uri) throws InvalidConfigurationRdfException {
|
||||
Set<PropertyStatement> set = new HashSet<>();
|
||||
|
||||
try (LockedModel m = model.read()) {
|
||||
try (LockedModel m = locking.read()) {
|
||||
List<Statement> rawStatements = m.listStatements(
|
||||
m.getResource(uri), (Property) null, (RDFNode) null)
|
||||
.toList();
|
||||
|
@ -108,11 +103,11 @@ public class ConfigurationRdfParser {
|
|||
}
|
||||
|
||||
private static <T> Class<? extends T> determineConcreteClass(
|
||||
LockableModel model, String uri, Class<T> resultClass)
|
||||
LockableModel locking, String uri, Class<T> resultClass)
|
||||
throws InvalidConfigurationRdfException {
|
||||
Set<Class<? extends T>> concreteClasses = new HashSet<>();
|
||||
|
||||
try (LockedModel m = model.read()) {
|
||||
try (LockedModel m = locking.read()) {
|
||||
for (RDFNode node : m.listObjectsOfProperty(createResource(uri),
|
||||
RDF.type).toSet()) {
|
||||
if (!node.isURIResource()) {
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.jena;
|
||||
|
||||
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<? extends Model>
|
||||
* LockerFor<? extends Model>
|
||||
* Add to develop.
|
||||
* Remove Critical and convert configurationBeanLoader
|
||||
* Merge to faux.
|
||||
*/
|
||||
public abstract class Critical {
|
||||
/**
|
||||
* 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. Cannot be used without locking.
|
||||
*
|
||||
* <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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be wrapped around a bare OntModel. Cannot be used without locking.
|
||||
*
|
||||
* <pre>
|
||||
* try (LockedModel m = lockableModel.read()) {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.shared.Lock;
|
||||
|
||||
/**
|
||||
* Makes it easy to use a Jena Model in a try-with-resources block. At the end
|
||||
* of the block, the close() method will not close the model, but will merely
|
||||
* release the lock.
|
||||
*
|
||||
* Wraps around a bare Model. Cannot be used without locking.
|
||||
*
|
||||
* <pre>
|
||||
* try (LockedModel m = new LockableModel(model).read()) {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public class LockableModel {
|
||||
private final Model model;
|
||||
|
||||
public LockableModel(Model model) {
|
||||
this.model = Objects.requireNonNull(model, "model may not be null.");
|
||||
}
|
||||
|
||||
public LockedModel read() {
|
||||
model.enterCriticalSection(Lock.READ);
|
||||
return new LockedModel(model);
|
||||
}
|
||||
|
||||
public LockedModel write() {
|
||||
model.enterCriticalSection(Lock.WRITE);
|
||||
return new LockedModel(model);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.shared.Lock;
|
||||
|
||||
/**
|
||||
* Makes it easy to use a Jena OntModel in a try-with-resources block. At the
|
||||
* end of the block, the close() method will not close the model, but will
|
||||
* merely release the lock.
|
||||
*
|
||||
* Returned by the LockableOntModelSelector, or it can be wrapped around a bare
|
||||
* OntModel. Cannot be used without locking.
|
||||
*
|
||||
* <pre>
|
||||
* try (LockedOntModel m = lockableOms.getDisplayModel.read()) {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* or
|
||||
*
|
||||
* <pre>
|
||||
* try (LockedOntModel m = new LockableOntModel(ontModel).read()) {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public class LockableOntModel {
|
||||
private final OntModel ontModel;
|
||||
|
||||
public LockableOntModel(OntModel ontModel) {
|
||||
this.ontModel = Objects.requireNonNull(ontModel,
|
||||
"ontModel may not be null.");
|
||||
}
|
||||
|
||||
public LockedOntModel read() {
|
||||
ontModel.enterCriticalSection(Lock.READ);
|
||||
return new LockedOntModel(ontModel);
|
||||
}
|
||||
|
||||
public LockedOntModel write() {
|
||||
ontModel.enterCriticalSection(Lock.WRITE);
|
||||
return new LockedOntModel(ontModel);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||
|
||||
/**
|
||||
* Makes it easy to use a Jena OntModel with a try-with-resources block. If you
|
||||
* have access to an OntModelSelector, you can wrap it and then use it obtain
|
||||
* LockableOntModels.
|
||||
*
|
||||
* <pre>
|
||||
* LockableOntModelSelector lockableOms = new LockableOntModelSelector(oms);
|
||||
*
|
||||
* try (LockedOntModel m = lockableOms.getDisplayModel.read()) {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public class LockableOntModelSelector {
|
||||
private final OntModelSelector oms;
|
||||
|
||||
public LockableOntModelSelector(OntModelSelector oms) {
|
||||
this.oms = Objects.requireNonNull(oms, "oms may not be null.");
|
||||
}
|
||||
|
||||
public LockableOntModel getFullModel() {
|
||||
return new LockableOntModel(oms.getFullModel());
|
||||
}
|
||||
|
||||
public LockableOntModel getABoxModel() {
|
||||
return new LockableOntModel(oms.getABoxModel());
|
||||
}
|
||||
|
||||
public LockableOntModel getTBoxModel() {
|
||||
return new LockableOntModel(oms.getTBoxModel());
|
||||
}
|
||||
|
||||
public LockableOntModel getApplicationMetadataModel() {
|
||||
return new LockableOntModel(oms.getApplicationMetadataModel());
|
||||
}
|
||||
|
||||
public LockableOntModel getUserAccountsModel() {
|
||||
return new LockableOntModel(oms.getUserAccountsModel());
|
||||
}
|
||||
|
||||
public LockableOntModel getDisplayModel() {
|
||||
return new LockableOntModel(oms.getDisplayModel());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.AbstractModelDecorator;
|
||||
|
||||
/**
|
||||
* A model that is easy to use in a try-with-resources code block. It can only
|
||||
* be created by locking a LockableModel.
|
||||
*
|
||||
* <pre>
|
||||
* try (LockedModel m = lockableModel.read()) {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* The close method has been hijacked to simply release the lock, and not to
|
||||
* actually close the wrapped model.
|
||||
*/
|
||||
public class LockedModel extends AbstractModelDecorator implements
|
||||
AutoCloseable {
|
||||
|
||||
/**
|
||||
* Should only be created by LockableModel.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.AbstractOntModelDecorator;
|
||||
|
||||
/**
|
||||
* 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 class LockedOntModel extends AbstractOntModelDecorator implements
|
||||
AutoCloseable {
|
||||
|
||||
/**
|
||||
* Can only be created by LockableOntModel.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
|
@ -101,7 +101,7 @@ public class ConfigurationBeanLoaderTest extends AbstractTestClass {
|
|||
expectException(NullPointerException.class, "model may not be null");
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
Object unused = new ConfigurationBeanLoader(null);
|
||||
Object unused = new ConfigurationBeanLoader((Model) null);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
|
Loading…
Add table
Reference in a new issue