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:
Jim Blake 2014-11-09 16:11:45 -05:00
commit 2fa9583569
16 changed files with 294 additions and 207 deletions

View file

@ -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.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.criticalsection.LockableOntModel;
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockedOntModel; import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModelSelector;
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockingOntModelSelector; import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedOntModel;
/** /**
* TODO * TODO
@ -80,11 +80,11 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
// The instance // The instance
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
private final LockingOntModelSelector models; private final LockableOntModelSelector models;
public FauxPropertyDaoJena(WebappDaoFactoryJena wadf) { public FauxPropertyDaoJena(WebappDaoFactoryJena wadf) {
super(wadf); super(wadf);
this.models = new LockingOntModelSelector(wadf.getOntModelSelector()); this.models = new LockableOntModelSelector(wadf.getOntModelSelector());
} }
/** /**

View file

@ -126,4 +126,9 @@ public class LoggingRDFService implements RDFService {
public void close() { public void close() {
innerService.close(); innerService.close();
} }
@Override
public String toString() {
return "LoggingRDFService[inner=" + innerService + "]";
}
} }

View file

@ -40,4 +40,9 @@ public class LoggingRDFServiceFactory implements RDFServiceFactory {
factory.unregisterListener(changeListener); factory.unregisterListener(changeListener);
} }
@Override
public String toString() {
return "LoggingRDFServiceFactory[factory=" + factory + "]";
}
} }

View file

@ -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.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; 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.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.JenaDataSourceSetupBase;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ContentDataStructuresProvider; 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.startup.StartupStatus;
@ -122,7 +123,8 @@ public class ContentDataStructuresProviderSDB extends
setupSDB(store); setupSDB(store);
} }
return new RDFServiceFactorySDB(ds, storeDesc); return new LoggingRDFServiceFactory(new RDFServiceFactorySDB(ds,
storeDesc));
} }
/** /**

View file

@ -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.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; 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.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.rdfservice.impl.sparql.RDFServiceSparql;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ContentDataStructuresProvider; 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.startup.StartupStatus;
@ -58,8 +59,8 @@ public class ContentDataStructuresProviderSPARQL extends
this.updateEndpointURI = props this.updateEndpointURI = props
.getProperty(PROPERTY_SPARQL_UPDATE_ENDPOINT_URI); .getProperty(PROPERTY_SPARQL_UPDATE_ENDPOINT_URI);
this.rdfService = createRDFService(); this.rdfServiceFactory = createRDFServiceFactory(createRDFService());
this.rdfServiceFactory = createRDFServiceFactory(); this.rdfService = this.rdfServiceFactory.getRDFService();
this.dataset = createDataset(); this.dataset = createDataset();
this.modelMaker = createModelMaker(); this.modelMaker = createModelMaker();
} }
@ -75,8 +76,9 @@ public class ContentDataStructuresProviderSPARQL extends
} }
} }
private RDFServiceFactory createRDFServiceFactory() { private RDFServiceFactory createRDFServiceFactory(RDFService service) {
return new RDFServiceFactorySingle(this.rdfService); return new LoggingRDFServiceFactory(
new RDFServiceFactorySingle(service));
} }
private Dataset createDataset() { private Dataset createDataset() {

View file

@ -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.RDFServiceFactory;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle; 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.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.servlet.setup.rdfsetup.impl.ConfigurationDataStructuresProvider;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
@ -60,8 +61,8 @@ public class ConfigurationDataStructuresProviderTDB extends
+ DIRECTORY_TDB; + DIRECTORY_TDB;
try { try {
this.rdfService = new RDFServiceTDB(tdbPath); this.rdfServiceFactory = createRDFServiceFactory(tdbPath);
this.rdfServiceFactory = createRDFServiceFactory(); this.rdfService = this.rdfServiceFactory.getRDFService();
this.dataset = new RDFServiceDataset(this.rdfService); this.dataset = new RDFServiceDataset(this.rdfService);
this.modelMaker = createModelMaker(); this.modelMaker = createModelMaker();
ss.info(ctxListener, "Initialized the RDF source for TDB"); ss.info(ctxListener, "Initialized the RDF source for TDB");
@ -75,8 +76,10 @@ public class ConfigurationDataStructuresProviderTDB extends
TDB.getContext().setTrue(TDB.symUnionDefaultGraph); TDB.getContext().setTrue(TDB.symUnionDefaultGraph);
} }
private RDFServiceFactory createRDFServiceFactory() { private RDFServiceFactory createRDFServiceFactory(String tdbPath)
return new RDFServiceFactorySingle(this.rdfService); throws IOException {
return new LoggingRDFServiceFactory(new RDFServiceFactorySingle(
new RDFServiceTDB(tdbPath)));
} }
private ModelMaker createModelMaker() { private ModelMaker createModelMaker() {

View file

@ -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.RDFServiceFactory;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle; 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.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.servlet.setup.rdfsetup.impl.ContentDataStructuresProvider;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
@ -74,7 +75,8 @@ public class ContentDataStructuresProviderTDB extends
} }
private RDFServiceFactory createRDFServiceFactory() { private RDFServiceFactory createRDFServiceFactory() {
return new RDFServiceFactorySingle(this.rdfService); return new LoggingRDFServiceFactory(new RDFServiceFactorySingle(
this.rdfService));
} }
private ModelMaker createModelMaker() { private ModelMaker createModelMaker() {

View file

@ -6,6 +6,7 @@ import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import javax.servlet.ServletContext; 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.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDF; 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.criticalsection.LockableModel;
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockedModel; import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedModel;
/** /**
* Load one or more Configuration beans from a specified model. * Load one or more Configuration beans from a specified model.
@ -50,7 +51,7 @@ public class ConfigurationBeanLoader {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** Must not be null. */ /** 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 * May be null, but the loader will be unable to satisfy instances of
@ -65,26 +66,34 @@ public class ConfigurationBeanLoader {
private final HttpServletRequest req; private final HttpServletRequest req;
public ConfigurationBeanLoader(Model model) { 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) { 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) { public ConfigurationBeanLoader(Model model, HttpServletRequest req) {
this(model, this(new LockableModel(model), req);
(req == null) ? null : req.getSession().getServletContext(),
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) { HttpServletRequest req) {
if (model == null) { this.locking = Objects.requireNonNull(locking,
throw new NullPointerException("model may not be null."); "locking may not be null.");
}
this.model = new LockableModel(model);
this.req = req; this.req = req;
this.ctx = ctx; this.ctx = ctx;
} }
@ -102,8 +111,8 @@ public class ConfigurationBeanLoader {
} }
try { try {
ConfigurationRdf<T> parsedRdf = ConfigurationRdfParser.parse(model, ConfigurationRdf<T> parsedRdf = ConfigurationRdfParser.parse(
uri, resultClass); locking, uri, resultClass);
WrappedInstance<T> wrapper = InstanceWrapper.wrap(parsedRdf WrappedInstance<T> wrapper = InstanceWrapper.wrap(parsedRdf
.getConcreteClass()); .getConcreteClass());
wrapper.satisfyInterfaces(ctx, req); wrapper.satisfyInterfaces(ctx, req);
@ -122,7 +131,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 (LockedModel m = model.read()) { try (LockedModel m = locking.read()) {
List<Resource> resources = m.listResourcesWithProperty(RDF.type, List<Resource> resources = m.listResourcesWithProperty(RDF.type,
createResource(toJavaUri(resultClass))).toList(); createResource(toJavaUri(resultClass))).toList();
for (Resource r : resources) { for (Resource r : resources) {

View file

@ -11,6 +11,7 @@ import static edu.cornell.mannlib.vitro.webapp.utils.configuration.Configuration
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import com.hp.hpl.jena.rdf.model.Property; 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.PropertyStatement;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyTypeException; 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.criticalsection.LockableModel;
import edu.cornell.mannlib.vitro.webapp.utils.jena.Critical.LockedModel; import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedModel;
/** /**
* Parse the RDF for a single individual in the model to create a * Parse the RDF for a single individual in the model to create a
* ConfigurationRdf object. * ConfigurationRdf object.
*/ */
public class ConfigurationRdfParser { public class ConfigurationRdfParser {
public static <T> ConfigurationRdf<T> parse(LockableModel model, public static <T> ConfigurationRdf<T> parse(LockableModel locking,
String uri, Class<T> resultClass) String uri, Class<T> resultClass)
throws InvalidConfigurationRdfException { throws InvalidConfigurationRdfException {
if (model == null) { Objects.requireNonNull(locking, "locking may not be null.");
throw new NullPointerException("model may not be null."); Objects.requireNonNull(uri, "uri may not be null.");
} Objects.requireNonNull(resultClass, "resultClass 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.");
}
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); resultClass);
return new ConfigurationRdf<T>(concreteClass, properties); return new ConfigurationRdf<T>(concreteClass, properties);
} }
private static void confirmExistenceInModel(LockableModel model, String uri) private static void confirmExistenceInModel(LockableModel locking,
throws InvalidConfigurationRdfException { String uri) throws InvalidConfigurationRdfException {
Selector s = new SimpleSelector(createResource(uri), null, Selector s = new SimpleSelector(createResource(uri), null,
(RDFNode) null); (RDFNode) null);
try (LockedModel m = model.read()) { try (LockedModel m = locking.read()) {
if (m.listStatements(s).toList().isEmpty()) { if (m.listStatements(s).toList().isEmpty()) {
throw individualDoesNotAppearInModel(uri); throw individualDoesNotAppearInModel(uri);
} }
} }
} }
private static void confirmEligibilityForResultClass(LockableModel model, private static void confirmEligibilityForResultClass(LockableModel locking,
String uri, Class<?> resultClass) String uri, Class<?> resultClass)
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 (LockedModel m = model.read()) { try (LockedModel m = locking.read()) {
if (!m.contains(s)) { if (!m.contains(s)) {
throw noTypeStatementForResultClass(s); throw noTypeStatementForResultClass(s);
} }
} }
} }
private static Set<PropertyStatement> loadProperties(LockableModel model, private static Set<PropertyStatement> loadProperties(LockableModel locking,
String uri) throws InvalidConfigurationRdfException { String uri) throws InvalidConfigurationRdfException {
Set<PropertyStatement> set = new HashSet<>(); Set<PropertyStatement> set = new HashSet<>();
try (LockedModel m = model.read()) { try (LockedModel m = locking.read()) {
List<Statement> rawStatements = m.listStatements( List<Statement> rawStatements = m.listStatements(
m.getResource(uri), (Property) null, (RDFNode) null) m.getResource(uri), (Property) null, (RDFNode) null)
.toList(); .toList();
@ -108,11 +103,11 @@ public class ConfigurationRdfParser {
} }
private static <T> Class<? extends T> determineConcreteClass( private static <T> Class<? extends T> determineConcreteClass(
LockableModel model, String uri, Class<T> resultClass) LockableModel locking, String uri, Class<T> resultClass)
throws InvalidConfigurationRdfException { throws InvalidConfigurationRdfException {
Set<Class<? extends T>> concreteClasses = new HashSet<>(); Set<Class<? extends T>> concreteClasses = new HashSet<>();
try (LockedModel m = model.read()) { try (LockedModel m = locking.read()) {
for (RDFNode node : m.listObjectsOfProperty(createResource(uri), for (RDFNode node : m.listObjectsOfProperty(createResource(uri),
RDF.type).toSet()) { RDF.type).toSet()) {
if (!node.isURIResource()) { if (!node.isURIResource()) {

View file

@ -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();
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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());
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -101,7 +101,7 @@ public class ConfigurationBeanLoaderTest extends AbstractTestClass {
expectException(NullPointerException.class, "model may not be null"); expectException(NullPointerException.class, "model may not be null");
@SuppressWarnings("unused") @SuppressWarnings("unused")
Object unused = new ConfigurationBeanLoader(null); Object unused = new ConfigurationBeanLoader((Model) null);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------