diff --git a/webapp/lib/hamcrest-all-1.3.jar b/webapp/lib/hamcrest-all-1.3.jar new file mode 100644 index 000000000..6f62ba00c Binary files /dev/null and b/webapp/lib/hamcrest-all-1.3.jar differ diff --git a/webapp/lib/junit-4.11.jar b/webapp/lib/junit-4.11.jar new file mode 100644 index 000000000..aaf744484 Binary files /dev/null and b/webapp/lib/junit-4.11.jar differ diff --git a/webapp/lib/junit-4.9.jar b/webapp/lib/junit-4.9.jar deleted file mode 100644 index 142081561..000000000 Binary files a/webapp/lib/junit-4.9.jar and /dev/null differ diff --git a/webapp/src/edu/cornell/mannlib/vedit/beans/LoginStatusBean.java b/webapp/src/edu/cornell/mannlib/vedit/beans/LoginStatusBean.java index d9a719483..8762771dc 100644 --- a/webapp/src/edu/cornell/mannlib/vedit/beans/LoginStatusBean.java +++ b/webapp/src/edu/cornell/mannlib/vedit/beans/LoginStatusBean.java @@ -10,7 +10,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; diff --git a/webapp/src/edu/cornell/mannlib/vedit/controller/BaseEditController.java b/webapp/src/edu/cornell/mannlib/vedit/controller/BaseEditController.java index 1017f26be..c1f7537a6 100644 --- a/webapp/src/edu/cornell/mannlib/vedit/controller/BaseEditController.java +++ b/webapp/src/edu/cornell/mannlib/vedit/controller/BaseEditController.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vedit.controller; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.ASSERTIONS_ONLY; + import java.text.Collator; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -29,7 +31,8 @@ import edu.cornell.mannlib.vedit.util.FormUtils; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; public class BaseEditController extends VitroHttpServlet { @@ -193,7 +196,7 @@ public class BaseEditController extends VitroHttpServlet { } protected WebappDaoFactory getWebappDaoFactory() { - return ModelAccess.on(getServletContext()).getBaseWebappDaoFactory(); + return ModelAccess.on(getServletContext()).getWebappDaoFactory(ASSERTIONS_ONLY); } protected WebappDaoFactory getWebappDaoFactory(String userURI) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/application/ApplicationImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/application/ApplicationImpl.java index 7ca265c10..6ecdf18f7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/application/ApplicationImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/application/ApplicationImpl.java @@ -13,7 +13,7 @@ import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus; import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage; import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine; -import edu.cornell.mannlib.vitro.webapp.searchengine.SearchEngineWrapper; +import edu.cornell.mannlib.vitro.webapp.searchengine.InstrumentedSearchEngineWrapper; import edu.cornell.mannlib.vitro.webapp.searchengine.solr.SolrSearchEngine; import edu.cornell.mannlib.vitro.webapp.startup.ComponentStartupStatusImpl; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; @@ -85,7 +85,7 @@ public class ApplicationImpl implements Application { ComponentStartupStatus css = new ComponentStartupStatusImpl( this, ss); - SearchEngine searchEngine = new SearchEngineWrapper( + SearchEngine searchEngine = new InstrumentedSearchEngineWrapper( new SolrSearchEngine()); searchEngine.startup(application, css); application.setSearchEngine(searchEngine); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java index 21e19433e..d5a880cf7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java @@ -28,7 +28,7 @@ import com.hp.hpl.jena.rdf.model.RDFNode; import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * The current user is blacklisted for this reason. @@ -153,7 +153,7 @@ public class IsBlacklisted extends AbstractCommonIdentifier implements return NOT_BLACKLISTED; } - OntModel model = ModelAccess.on(context).getJenaOntModel(); + OntModel model = ModelAccess.on(context).getOntModel(); queryString = queryString.replaceAll("\\?individualURI", "<" + ind.getURI() + ">"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java index 2a45c4769..039f000e2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java @@ -6,7 +6,7 @@ import javax.servlet.ServletContext; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsSmokeTest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsSmokeTest.java index 74c0f8c08..79292502f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsSmokeTest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsSmokeTest.java @@ -11,7 +11,7 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java index 87a1a971f..d8d795815 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java @@ -21,7 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java index e61d798db..abf488f6d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; + import javax.servlet.ServletContext; import org.apache.commons.logging.Log; @@ -14,7 +16,7 @@ import edu.cornell.mannlib.vedit.beans.EditProcessObject; import edu.cornell.mannlib.vedit.listener.ChangeListener; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.Property; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * Add this ChangeListener to your EditProcessObject when modifying the @@ -98,8 +100,8 @@ public class PropertyRestrictionListener implements ChangeListener { } private void createAndSetBean() { - OntModel model = ModelAccess.on(ctx).getJenaOntModel(); - Model displayModel = ModelAccess.on(ctx).getDisplayModel(); + OntModel model = ModelAccess.on(ctx).getOntModel(); + Model displayModel = ModelAccess.on(ctx).getOntModel(DISPLAY); PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper .createBean(model, displayModel); PropertyRestrictionPolicyHelper.setBean(ctx, bean); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java index e6832d531..f7ecddc47 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -33,8 +35,8 @@ import com.hp.hpl.jena.vocabulary.OWL; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.Property; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.utils.ApplicationConfigurationOntologyUtils; @@ -489,12 +491,12 @@ public class PropertyRestrictionPolicyHelper { StartupStatus ss = StartupStatus.getBean(ctx); try { - OntModel model = ModelAccess.on(ctx).getJenaOntModel(); + OntModel model = ModelAccess.on(ctx).getOntModel(); if (model == null) { throw new NullPointerException( "jenaOntModel has not been initialized."); } - Model displayModel = ModelAccess.on(ctx).getDisplayModel(); + Model displayModel = ModelAccess.on(ctx).getOntModel(DISPLAY); if (displayModel == null) { throw new NullPointerException( "display model has not been initialized."); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/AbstractPageHandler.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/AbstractPageHandler.java index d695429c5..ad51979ec 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/AbstractPageHandler.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/AbstractPageHandler.java @@ -2,6 +2,9 @@ package edu.cornell.mannlib.vitro.webapp.controller; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -19,14 +22,13 @@ import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.i18n.I18n; import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * A base class with some utility routines for page handler (created by @@ -56,8 +58,8 @@ public abstract class AbstractPageHandler { this.i18n = I18n.bundle(vreq); this.ctx = vreq.getSession().getServletContext(); - userAccountsModel = ModelAccess.on(ctx).getUserAccountsModel(); - unionModel = ModelAccess.on(ctx).getOntModel(ModelNames.FULL_UNION); + userAccountsModel = ModelAccess.on(ctx).getOntModel(USER_ACCOUNTS); + unionModel = ModelAccess.on(ctx).getOntModel(FULL_UNION); WebappDaoFactory wdf = ModelAccess.on(ctx).getWebappDaoFactory(); userAccountsDao = wdf.getUserAccountsDao(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/FedoraDatastreamController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/FedoraDatastreamController.java index 9ae6b7b86..21a61724f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/FedoraDatastreamController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/FedoraDatastreamController.java @@ -42,9 +42,9 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import fedora.client.FedoraClient; import fedora.common.Constants; import fedora.server.management.FedoraAPIM; @@ -101,7 +101,7 @@ public class FedoraDatastreamController extends VitroHttpServlet implements Cons log.debug("In doGet"); VitroRequest vreq = new VitroRequest(req); - OntModel sessionOntModel = ModelAccess.on(vreq.getSession()).getJenaOntModel(); + OntModel sessionOntModel = ModelAccess.on(getServletContext()).getOntModel(); synchronized (FedoraDatastreamController.class) { if( fedoraUrl == null ){ @@ -241,7 +241,7 @@ public class FedoraDatastreamController extends VitroHttpServlet implements Cons } //check if fedora is on line - OntModel sessionOntModel = ModelAccess.on(rawRequest.getSession()).getJenaOntModel(); + OntModel sessionOntModel = ModelAccess.on(getServletContext()).getOntModel(); synchronized (FedoraDatastreamController.class) { if( fedoraUrl == null ){ setup( sessionOntModel, getServletContext() ); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/IndividualListRdfController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/IndividualListRdfController.java index 3cd56ce9d..0dbbe0b60 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/IndividualListRdfController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/IndividualListRdfController.java @@ -3,6 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.controller; import static edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.RdfResultMediaType.RDF_XML; import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.RDF_TYPE; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS; import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; import static javax.servlet.http.HttpServletResponse.SC_NOT_ACCEPTABLE; @@ -29,7 +30,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.api.VitroApiServlet; import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.InvalidQueryTypeException; import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.RdfResultMediaType; import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.SparqlQueryApiExecutor; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; @@ -94,7 +95,7 @@ public class IndividualListRdfController extends VitroApiServlet { ObjectProperty property = new ObjectProperty(); property.setURI(RDF_TYPE); RequestedAction dops = new PublishObjectPropertyStatement(ModelAccess - .on(req).getBaseOntModel(), RequestedAction.SOME_URI, property, + .on(req).getOntModel(FULL_ASSERTIONS), RequestedAction.SOME_URI, property, vclassUri); return !PolicyHelper.isAuthorizedForActions(req, dops); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/OntologyController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/OntologyController.java index 0e961c262..bb89a55c2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/OntologyController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/OntologyController.java @@ -11,7 +11,6 @@ import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -27,7 +26,7 @@ import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.shared.Lock; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaOutputUtils; import edu.cornell.mannlib.vitro.webapp.web.ContentType; @@ -128,7 +127,7 @@ public class OntologyController extends VitroHttpServlet{ String url = ontology; - OntModel ontModel = ModelAccess.on(vreq.getSession()).getJenaOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(); boolean found = false; Model newModel = ModelFactory.createDefaultModel(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java index b1f0da510..62a0fb1c2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java @@ -6,6 +6,12 @@ package edu.cornell.mannlib.vitro.webapp.controller; import static edu.cornell.mannlib.vitro.webapp.controller.MultipartRequestWrapper.ATTRIBUTE_FILE_ITEM_MAP; import static edu.cornell.mannlib.vitro.webapp.controller.MultipartRequestWrapper.ATTRIBUTE_FILE_SIZE_EXCEPTION; import static edu.cornell.mannlib.vitro.webapp.controller.MultipartRequestWrapper.ATTRIBUTE_IS_MULTIPART; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ASSERTIONS_ONLY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.CONTENT; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LANGUAGE_NEUTRAL; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.POLICY_NEUTRAL; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS; import java.text.Collator; import java.util.Collections; @@ -24,13 +30,12 @@ import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.query.Dataset; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.FactoryID; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource.ModelName; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; public class VitroRequest extends HttpServletRequestWrapper { @@ -52,64 +57,34 @@ public class VitroRequest extends HttpServletRequestWrapper { } public RDFService getRDFService() { - Object o = getAttribute("rdfService"); - if (o instanceof RDFService) { - return (RDFService) o; - } else { - RDFService rdfService = RDFServiceUtils.getRDFService(this); - setAttribute("rdfService", rdfService); - return rdfService; - } + return ModelAccess.on(this).getRDFService(); } public RDFService getUnfilteredRDFService() { - Object o = getAttribute("unfilteredRDFService"); - if (o instanceof RDFService) { - return (RDFService) o; - } else { - RDFService rdfService = RDFServiceUtils.getRDFService(this); - setAttribute("unfilteredRDFService", rdfService); - return rdfService; - } - } - - public void setRDFService(RDFService rdfService) { - setAttribute("rdfService", rdfService); - } - - public void setUnfilteredRDFService(RDFService rdfService) { - setAttribute("unfilteredRDFService", rdfService); + return ModelAccess.on(this).getRDFService(CONTENT, LANGUAGE_NEUTRAL); } /** Gets WebappDaoFactory with appropriate filtering for the request */ public WebappDaoFactory getWebappDaoFactory(){ - return ModelAccess.on(this).getWebappDaoFactory(FactoryID.UNION); + return ModelAccess.on(this).getWebappDaoFactory(); } /** gets assertions+inference WebappDaoFactory with no policy filtering */ public WebappDaoFactory getUnfilteredWebappDaoFactory() { - return ModelAccess.on(this).getWebappDaoFactory(FactoryID.UNFILTERED_UNION); + return ModelAccess.on(this).getWebappDaoFactory(POLICY_NEUTRAL); } /** gets assertions-only WebappDaoFactory with no policy filtering */ public WebappDaoFactory getUnfilteredAssertionsWebappDaoFactory() { - return ModelAccess.on(this).getWebappDaoFactory(FactoryID.UNFILTERED_BASE); + return ModelAccess.on(this).getWebappDaoFactory(POLICY_NEUTRAL, ASSERTIONS_ONLY); } public Dataset getDataset() { - return (Dataset) getAttribute("dataset"); - } - - public void setDataset(Dataset dataset) { - setAttribute("dataset", dataset); + return ModelAccess.on(this).getDataset(CONTENT); } public Dataset getUnfilteredDataset() { - return (Dataset) getAttribute("unfilteredDataset"); - } - - public void setUnfilteredDataset(Dataset dataset) { - setAttribute("unfilteredDataset", dataset); + return ModelAccess.on(this).getDataset(CONTENT, LANGUAGE_NEUTRAL); } //Method that retrieves write model, returns special model in case of write model @@ -127,21 +102,15 @@ public class VitroRequest extends HttpServletRequestWrapper { } public OntModel getJenaOntModel() { - return ModelAccess.on(this).getJenaOntModel(); + return ModelAccess.on(this).getOntModel(ModelNames.FULL_UNION); } - /** JB - surprising that this comes from session. */ public OntModel getAssertionsOntModel() { - return ModelAccess.on(this.getSession()).getBaseOntModel(); + return ModelAccess.on(this).getOntModel(FULL_ASSERTIONS); } - /** JB - surprising that this comes from session. */ - public OntModel getInferenceOntModel() { - return ModelAccess.on(this.getSession()).getInferenceOntModel(); - } - public OntModel getDisplayModel(){ - return ModelAccess.on(this).getDisplayModel(); + return ModelAccess.on(this).getOntModel(DISPLAY); } /** @@ -216,12 +185,8 @@ public class VitroRequest extends HttpServletRequestWrapper { return _req.getParameterValues(name); } - public void setLanguageNeutralUnionFullModel(OntModel model) { - setAttribute("languageNeutralUnionFullModel", model); - } - public OntModel getLanguageNeutralUnionFullModel() { - return (OntModel) getAttribute("languageNeutralUnionFullModel"); + return ModelAccess.on(this).getOntModel(ModelNames.FULL_UNION, LANGUAGE_NEUTRAL); } public void setCollator(Collator collator) { @@ -232,12 +197,8 @@ public class VitroRequest extends HttpServletRequestWrapper { return (Collator) getAttribute("collator"); } - public void setLanguageNeutralWebappDaoFactory(WebappDaoFactory wadf) { - setAttribute("languageNeutralWebappDaoFactory", wadf); - } - public WebappDaoFactory getLanguageNeutralWebappDaoFactory() { - return (WebappDaoFactory) getAttribute("languageNeutralWebappDaoFactory"); + return edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.on(this).getWebappDaoFactory(LANGUAGE_NEUTRAL); } // ---------------------------------------------------------------------- diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/BasicProxiesGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/BasicProxiesGetter.java index 724c4e828..60e3df457 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/BasicProxiesGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/BasicProxiesGetter.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ajax; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS; + import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -20,8 +22,8 @@ import com.hp.hpl.jena.query.QuerySolution; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.ajax.AbstractAjaxResponder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils; import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil; @@ -58,7 +60,7 @@ public class BasicProxiesGetter extends AbstractAjaxResponder { super(servlet, vreq, resp); term = getStringParameter(PARAMETER_SEARCH_TERM, ""); - userAccountsModel = ModelAccess.on(vreq).getUserAccountsModel(); + userAccountsModel = ModelAccess.on(vreq).getOntModel(USER_ACCOUNTS); placeholderImageUrl = UrlBuilder.getUrl(PlaceholderUtil .getPlaceholderImagePathForType(vreq, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowSourcesController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowSourcesController.java new file mode 100644 index 000000000..20bd7fb69 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowSourcesController.java @@ -0,0 +1,252 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.admin; + +import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest.AUTHORIZED; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption.LANGUAGE_NEUTRAL; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.rdf.model.Model; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.RequestModelAccess; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ComplexStringFormatter; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * Show the details of where our RDF data is coming from. What are the + * structures that supply the triples? + * + *
+ * Display like this:
+ * 
+ * ModelAccess for Context
+ * blah-blah
+ * 
+ * ModelAccess for Request
+ * blah-blah 
+ * 
+ * RDFServices
+ *               CONTEXT    REQUEST
+ * CONTENT       blah-blah  argle-bargle
+ * CONFIGURATION balderdash obstreporous
+ * 
+ * Datasets  [same]
+ * 
+ * Models
+ * Name                     ContextOnly
+ * DISPLAY                  blah-blah
+ * filegraph:tbox/junk.owl  bork-bork-bork
+ * 
+ * OntModels
+ * Name                     Context        REQUEST
+ * DISPLAY                  blah-blah      song-and-dance
+ * filegraph:tbox/junk.owl  bork-bork-bork bogus-malarkey
+ * 
+ * For the request object, 
+ *     Get the LANGUAGE_NEUTRAL versions, since they have fewer decorators.
+ *     If the string is the same as the corresponding object in the context, show as "SAME AS CONTEXT"
+ * 
+ * Structure for freemarker:
+ * map:
+ *    modelAccess:
+ *       context: text
+ *       request: text
+ *    rdfServices:
+ *       content:
+ *          context: text
+ *          request: text
+ *       configuration:
+ *          context: text
+ *          request: text
+ *    datasets:
+ *       [same]
+ *    models:
+ *       content:
+ *          name1: 
+ *             context: text
+ *          name2: 
+ *             context: text
+ *          ...
+ *       configuration:
+ *          name3: 
+ *             context: text
+ *             request: text
+ *          ...
+ *    ontModels:
+ *       name1: 
+ *          context: text
+ *          request: text
+ *       ...
+ *       
+ * At the same time, write these to the log as INFO messages, without the fancy formatting.
+ * 
+ */ +public class ShowSourcesController extends FreemarkerHttpServlet { + private static final Log log = LogFactory + .getLog(ShowSourcesController.class); + + @Override + protected AuthorizationRequest requiredActions(VitroRequest vreq) { + return AUTHORIZED; + } + + @Override + protected ResponseValues processRequest(VitroRequest vreq) { + return new TemplateResponseValues("admin-showSources.ftl", + new SourcesMap(vreq)); + } + + private static class SourcesMap extends HashMap { + private static final Object SAME_AS_CONTEXT = "Same as Context"; + + private final RequestModelAccess reqModels; + private final ContextModelAccess ctxModels; + + private final SortedSet contentModelNames; + private final SortedSet configurationModelNames; + private final SortedSet allModelNames; + + public SourcesMap(VitroRequest vreq) { + this.reqModels = ModelAccess.on(vreq); + this.ctxModels = ModelAccess.on(vreq.getSession() + .getServletContext()); + + this.contentModelNames = new TreeSet<>(ctxModels + .getModelMaker(CONTENT).listModels().toList()); + this.configurationModelNames = new TreeSet<>(ctxModels + .getModelMaker(CONFIGURATION).listModels().toList()); + this.allModelNames = new TreeSet<>(contentModelNames); + this.allModelNames.addAll(configurationModelNames); + + addStructures(ctxModels, reqModels, "modelAccess"); + + addStructures(ctxModels.getRDFService(CONTENT), + reqModels.getRDFService(CONTENT, LANGUAGE_NEUTRAL), + "rdfServices", CONTENT); + addStructures(ctxModels.getRDFService(CONFIGURATION), + reqModels.getRDFService(CONFIGURATION, LANGUAGE_NEUTRAL), + "rdfServices", CONFIGURATION); + + addStructures(ctxModels.getDataset(CONTENT), + reqModels.getDataset(CONTENT, LANGUAGE_NEUTRAL), + "datasets", CONTENT); + addStructures(ctxModels.getDataset(CONFIGURATION), + reqModels.getDataset(CONFIGURATION, LANGUAGE_NEUTRAL), + "datasets", CONFIGURATION); + + for (String modelName : contentModelNames) { + addContextModel( + ctxModels.getModelMaker(CONTENT).getModel(modelName), + "models", CONTENT, ToString.modelName(modelName)); + } + for (String modelName : configurationModelNames) { + addContextModel(ctxModels.getModelMaker(CONFIGURATION) + .getModel(modelName), "models", CONFIGURATION, + ToString.modelName(modelName)); + } + + for (String modelName : allModelNames) { + addStructures(ctxModels.getOntModel(modelName), + reqModels.getOntModel(modelName, LANGUAGE_NEUTRAL), + "ontModels", ToString.modelName(modelName)); + } + } + + private void addStructures(Object contextDataStructure, + Object requestDataStructure, Object... keys) { + Map map = followPath(keys); + map.put("context", formatStructure(contextDataStructure)); + + if (String.valueOf(contextDataStructure).equals( + String.valueOf(requestDataStructure))) { + map.put("request", SAME_AS_CONTEXT); + } else { + map.put("request", formatStructure(requestDataStructure)); + } + + writeToLog(keys, "context", contextDataStructure); + writeToLog(keys, "request", requestDataStructure); + } + + private void addContextModel(Model model, Object... keys) { + Map map = followPath(keys); + map.put("context", formatStructure(model)); + writeToLog(keys, "context", model); + } + + /** + * Get the inner map that corresponds to this set of keys. If there is + * no such map, create one. + */ + @SuppressWarnings("unchecked") + private Map followPath(Object[] keys) { + Map m = this; + for (Object key : keys) { + String stringKey = String.valueOf(key); + if (!m.containsKey(stringKey)) { + m.put(stringKey, new TreeMap()); + } + m = (Map) m.get(stringKey); + } + return m; + } + + private void writeToLog(Object[] keys, String lastKey, + Object dataStructure) { + List allKeys = new ArrayList<>(); + allKeys.addAll(Arrays.asList(keys)); + allKeys.add(lastKey); + log.info("Data structure: " + allKeys + " " + + dsToString(dataStructure)); + } + + private String dsToString(Object dataStructure) { + if (dataStructure instanceof OntModel) { + return ToString.ontModelToString((OntModel) dataStructure); + } else if (dataStructure instanceof Model) { + return ToString.modelToString((Model) dataStructure); + } else if (dataStructure instanceof Graph) { + return ToString.graphToString((Graph) dataStructure); + } else if (dataStructure instanceof RequestModelAccess + || dataStructure instanceof ContextModelAccess) { + return ToString + .replaceModelNames(String.valueOf(dataStructure)); + } else { + return String.valueOf(dataStructure); + } + } + + private String formatStructure(Object dataStructure) { + String dsString = dsToString(dataStructure); + if (dataStructure instanceof RequestModelAccess + || dataStructure instanceof ContextModelAccess) { + return new ComplexStringFormatter(dsString, ". ").toString(); + } else { + return new ComplexStringFormatter(dsString).toString(); + } + } + + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/SparqlQueryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/SparqlQueryController.java index 86f36d874..64d828763 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/SparqlQueryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/SparqlQueryController.java @@ -33,9 +33,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils; import edu.cornell.mannlib.vitro.webapp.utils.http.AcceptHeaderParsingException; import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException; @@ -103,8 +103,8 @@ public class SparqlQueryController extends FreemarkerHttpServlet { private void respondToQuery(HttpServletRequest req, HttpServletResponse resp) throws IOException { - RDFService rdfService = RDFServiceUtils.getRDFServiceFactory( - getServletContext()).getRDFService(); + RDFService rdfService = ModelAccess.on(getServletContext()) + .getRDFService(); String queryString = req.getParameter("query"); try { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java index 61ee72a20..d93a8dcf5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java @@ -2,6 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.controller.ajax; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS; import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; import java.io.IOException; @@ -20,7 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.ajax.SparqlUtils.AjaxControllerException; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * Handle an AJAX request for a SPARQL query. On entry, the "query" parameter @@ -78,9 +79,9 @@ public class SparqlQueryAjaxController extends VitroAjaxController { private Model locateModel(VitroRequest vreq, String modelParam) { if (OPTION_MODEL_USER_ACCOUNTS.equals(modelParam)) { - return ModelAccess.on(vreq).getUserAccountsModel(); + return ModelAccess.on(vreq).getOntModel(USER_ACCOUNTS); } else { - return ModelAccess.on(vreq).getJenaOntModel(); + return ModelAccess.on(vreq).getOntModel(); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/api/SparqlQueryApiController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/api/SparqlQueryApiController.java index 8945b7cd4..e1d938c92 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/api/SparqlQueryApiController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/api/SparqlQueryApiController.java @@ -19,9 +19,9 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.InvalidQueryTypeException; import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.SparqlQueryApiExecutor; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.utils.http.AcceptHeaderParsingException; import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException; @@ -53,8 +53,8 @@ public class SparqlQueryApiController extends VitroApiServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - RDFService rdfService = RDFServiceUtils.getRDFServiceFactory( - getServletContext()).getRDFService(); + RDFService rdfService = ModelAccess.on(getServletContext()) + .getRDFService(); String acceptHeader = req.getHeader("Accept"); String queryString = req.getParameter("query"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java index 2737dacf0..99a3fbcfd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java @@ -7,7 +7,6 @@ import java.util.Date; import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @@ -19,18 +18,17 @@ import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; import edu.cornell.mannlib.vitro.webapp.controller.edit.Authenticate; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.FactoryID; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.LogoutEvent; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder; /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/AbstractDumpRestoreAction.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/AbstractDumpRestoreAction.java index aa471b41d..061a075ba 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/AbstractDumpRestoreAction.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/AbstractDumpRestoreAction.java @@ -8,9 +8,9 @@ import javax.servlet.http.HttpServletRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.datatools.dumprestore.DumpRestoreController.BadRequestException; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; /** * Some utility methods that are common to the Action classes. diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/DumpModelsAction.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/DumpModelsAction.java index 5752805b2..dca5e5ee7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/DumpModelsAction.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/DumpModelsAction.java @@ -16,10 +16,10 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.controller.datatools.dumprestore.DumpRestoreController.BadRequestException; import edu.cornell.mannlib.vitro.webapp.controller.datatools.dumprestore.DumpRestoreController.DumpFormat; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; /** * The user has requested a dump. diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/RestoreModelsAction.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/RestoreModelsAction.java index ffb31fb70..22e4995b8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/RestoreModelsAction.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/RestoreModelsAction.java @@ -34,11 +34,11 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.datatools.dumprestore.DumpRestoreController.BadRequestException; import edu.cornell.mannlib.vitro.webapp.controller.datatools.dumprestore.DumpRestoreController.RestoreFormat; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; /** * Load from a dump file of NQuads, or something equivalent. diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Authenticate.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Authenticate.java index 142d9b4d4..3e2cd801f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Authenticate.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Authenticate.java @@ -39,7 +39,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginInProcessFl import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginRedirector; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginLogoutEvent; public class Authenticate extends VitroHttpServlet { @@ -559,7 +559,7 @@ public class Authenticate extends VitroHttpServlet { return; } - OntModel jenaOntModel = ModelAccess.on(session).getJenaOntModel(); + OntModel jenaOntModel = ModelAccess.on(context).getOntModel(); jenaOntModel.getBaseModel().notifyEvent(event); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java index 436dbec80..7a4b8a0d0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java @@ -19,7 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; public class Classes2ClassesRetryController extends BaseEditController { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/ClassgroupRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/ClassgroupRetryController.java index 75272e45e..f19b47e21 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/ClassgroupRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/ClassgroupRetryController.java @@ -25,7 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java index 77c923212..ec3759041 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java @@ -34,7 +34,7 @@ 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.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/NamespacePrefixOperationController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/NamespacePrefixOperationController.java index c55c9f0cf..7e8fd1647 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/NamespacePrefixOperationController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/NamespacePrefixOperationController.java @@ -24,7 +24,7 @@ import edu.cornell.mannlib.vedit.beans.EditProcessObject; import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; public class NamespacePrefixOperationController extends BaseEditController { @@ -69,7 +69,7 @@ public class NamespacePrefixOperationController extends BaseEditController { if (request.getParameter("_cancel") == null) { - OntModel ontModel = ModelAccess.on(getServletContext()).getJenaOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(); String namespaceStr = request.getParameter("namespace"); String prefixStr = request.getParameter("prefix"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyGroupRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyGroupRetryController.java index 2066cbc8e..a66883510 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyGroupRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyGroupRetryController.java @@ -25,7 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; 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.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; public class PropertyGroupRetryController extends BaseEditController { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java index 739f50be6..2b2ed1a77 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java @@ -33,7 +33,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; 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.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RefactorOperationController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RefactorOperationController.java index a812811e3..a708a02c1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RefactorOperationController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RefactorOperationController.java @@ -2,6 +2,11 @@ package edu.cornell.mannlib.vitro.webapp.controller.edit; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS; + import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -48,9 +53,8 @@ import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.servlet.setup.FileGraphSetup; public class RefactorOperationController extends BaseEditController { @@ -72,7 +76,7 @@ public class RefactorOperationController extends BaseEditController { request.setAttribute("title","Check Datatype Properties"); request.setAttribute("css", ""); - OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(FULL_ASSERTIONS); ontModel.enterCriticalSection(Lock.WRITE); ArrayList results = new ArrayList(); @@ -233,11 +237,11 @@ public class RefactorOperationController extends BaseEditController { boolean doNotify = false; Model model = null; - if (ModelNames.TBOX_ASSERTIONS.equals(graphURI)) { - model = ModelAccess.on(getServletContext()).getOntModel(ModelNames.TBOX_ASSERTIONS); + if (TBOX_ASSERTIONS.equals(graphURI)) { + model = ModelAccess.on(getServletContext()).getOntModel(TBOX_ASSERTIONS); doNotify = true; - } else if (ModelNames.ABOX_ASSERTIONS.equals(graphURI)) { - model = ModelAccess.on(getServletContext()).getOntModel(ModelNames.ABOX_ASSERTIONS); + } else if (ABOX_ASSERTIONS.equals(graphURI)) { + model = ModelAccess.on(getServletContext()).getOntModel(ABOX_ASSERTIONS); doNotify = true; } else { model = dataset.getNamedModel(graphURI); @@ -250,7 +254,7 @@ public class RefactorOperationController extends BaseEditController { dataset.getLock().leaveCriticalSection(); } - renameResourceInModel(ModelAccess.on(getServletContext()).getUserAccountsModel(), + renameResourceInModel(ModelAccess.on(getServletContext()).getOntModel(USER_ACCOUNTS), userURI, oldURIStr, newURIStr, !NOTIFY); // there are no statements to delete, but we want indexes updated appropriately @@ -327,7 +331,7 @@ public class RefactorOperationController extends BaseEditController { private void doMovePropertyStatements(VitroRequest request, HttpServletResponse response, EditProcessObject epo) { String userURI = LoginStatusBean.getBean(request).getUserURI(); - OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(FULL_ASSERTIONS); Model tempRetractModel = ModelFactory.createDefaultModel(); Model tempAddModel = ModelFactory.createDefaultModel(); @@ -411,7 +415,7 @@ public class RefactorOperationController extends BaseEditController { private void doMoveInstances(VitroRequest request, HttpServletResponse response, EditProcessObject epo) { String userURI = LoginStatusBean.getBean(request).getUserURI(); - OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(FULL_ASSERTIONS); String oldClassURIStr = (String) epo.getAttribute("VClassURI"); String newClassURIStr = (String) request.getParameter("NewVClassURI"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RestrictionOperationController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RestrictionOperationController.java index 2b23220a4..f4a6d98a3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RestrictionOperationController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RestrictionOperationController.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.controller.edit; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS; + import java.util.HashMap; import java.util.Iterator; @@ -28,9 +30,8 @@ import edu.cornell.mannlib.vedit.beans.EditProcessObject; import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class RestrictionOperationController extends BaseEditController { @@ -45,9 +46,8 @@ public class RestrictionOperationController extends BaseEditController { String defaultLandingPage = getDefaultLandingPage(request); try { - - OntModel ontModel = ModelAccess.on( - getServletContext()).getOntModel(ModelNames.TBOX_ASSERTIONS); + OntModel ontModel = ModelAccess.on(getServletContext()) + .getOntModel(TBOX_ASSERTIONS); HashMap epoHash = null; EditProcessObject epo = null; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassEditController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassEditController.java index 394bd527b..97381b513 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassEditController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassEditController.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.controller.edit; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.ASSERTIONS_ONLY; + import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -25,10 +27,10 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class VclassEditController extends BaseEditController { @@ -45,7 +47,7 @@ public class VclassEditController extends BaseEditController { EditProcessObject epo = super.createEpo(request, FORCE_NEW); request.setAttribute("epoKey", epo.getKey()); - VClassDao vcwDao = ModelAccess.on(getServletContext()).getBaseWebappDaoFactory().getVClassDao(); + VClassDao vcwDao = ModelAccess.on(getServletContext()).getWebappDaoFactory(ASSERTIONS_ONLY).getVClassDao(); VClass vcl = (VClass)vcwDao.getVClassByURI(request.getParameter("uri")); if (vcl == null) { @@ -149,7 +151,7 @@ public class VclassEditController extends BaseEditController { request.setAttribute("formSelect",formSelect); // if supported, we want to show only the asserted superclasses and subclasses. - VClassDao vcDao = ModelAccess.on(getServletContext()).getBaseWebappDaoFactory().getVClassDao(); + VClassDao vcDao = ModelAccess.on(getServletContext()).getWebappDaoFactory(ASSERTIONS_ONLY).getVClassDao(); VClassDao displayVcDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getVClassDao(); List superVClasses = getVClassesForURIList( diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassRetryController.java index 1e15f39c6..dcbd4a5ab 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassRetryController.java @@ -31,11 +31,11 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; 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.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class VclassRetryController extends BaseEditController { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/NamespacesListingController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/NamespacesListingController.java index 87977762b..afdedab53 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/NamespacesListingController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/NamespacesListingController.java @@ -22,8 +22,8 @@ import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class NamespacesListingController extends BaseEditController { @@ -35,7 +35,7 @@ public class NamespacesListingController extends BaseEditController { VitroRequest vrequest = new VitroRequest(request); - OntModel ontModel = ModelAccess.on(getServletContext()).getJenaOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(); ArrayList results = new ArrayList(); request.setAttribute("results",results); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/RestrictionsListingController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/RestrictionsListingController.java index d04c07618..e6b851b4f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/RestrictionsListingController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/RestrictionsListingController.java @@ -33,9 +33,9 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class RestrictionsListingController extends BaseEditController { @@ -52,7 +52,7 @@ public class RestrictionsListingController extends BaseEditController { epo = super.createEpo(request); - OntModel ontModel = ModelAccess.on(getServletContext()).getJenaOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(); ObjectPropertyDao opDao = vrequest.getUnfilteredWebappDaoFactory().getObjectPropertyDao(); VClassDao vcDao = vrequest.getUnfilteredWebappDaoFactory().getVClassDao(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeletePropertyController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeletePropertyController.java index b7ab19121..5563bef94 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeletePropertyController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeletePropertyController.java @@ -19,10 +19,10 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.N3EditUtils; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.web.URLEncoder; /* * Custom deletion controller to which deletion requests from default property form are sent. May be replaced diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaAdminActions.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaAdminActions.java index f26c3b5e3..08b007fef 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaAdminActions.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaAdminActions.java @@ -2,6 +2,9 @@ package edu.cornell.mannlib.vitro.webapp.controller.jena; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_INFERENCES; + import java.io.IOException; import java.io.OutputStream; import java.io.StringWriter; @@ -43,8 +46,8 @@ import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class JenaAdminActions extends BaseEditController { @@ -88,7 +91,7 @@ public class JenaAdminActions extends BaseEditController { * This doesn't really print just the TBox. It takes a copy of the model, removes all the individuals, and writes the result. */ private void outputTbox(HttpServletResponse response) { - OntModel memoryModel = ModelAccess.on(getServletContext()).getBaseOntModel(); + OntModel memoryModel = ModelAccess.on(getServletContext()).getOntModel(FULL_ASSERTIONS); try { OntModel tempOntModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM); memoryModel.enterCriticalSection(Lock.READ); @@ -158,7 +161,7 @@ public class JenaAdminActions extends BaseEditController { private String testWriteXML() { StringBuffer output = new StringBuffer(); output.append("Test Write XML
\n");
-		OntModel model = ModelAccess.on(getServletContext()).getJenaOntModel();
+		OntModel model = ModelAccess.on(getServletContext()).getOntModel();
 		Model tmp = ModelFactory.createDefaultModel();
 		boolean valid = true;
 		for (Statement stmt : model.listStatements().toList() ) {
@@ -214,7 +217,7 @@ public class JenaAdminActions extends BaseEditController {
     }
     
     private void removeLongLiterals() {
-		OntModel memoryModel = ModelAccess.on(getServletContext()).getJenaOntModel();
+		OntModel memoryModel = ModelAccess.on(getServletContext()).getOntModel();
     	memoryModel.enterCriticalSection(Lock.WRITE);
     	try {
     		List statementsToRemove = new LinkedList();
@@ -257,7 +260,7 @@ public class JenaAdminActions extends BaseEditController {
 		}
         
         if (actionStr.equals("checkURIs")) { 
-    		OntModel memoryModel = ModelAccess.on(getServletContext()).getJenaOntModel();
+    		OntModel memoryModel = ModelAccess.on(getServletContext()).getOntModel();
         	StmtIterator stmtIt = memoryModel.listStatements();
         	try {
         		for (Statement stmt : stmtIt.toList() ) {
@@ -288,16 +291,16 @@ public class JenaAdminActions extends BaseEditController {
         if (actionStr.equals("output")) {
             OntModel memoryModel = null;
 	    if (request.getParameter("assertionsOnly") != null) {
-	        memoryModel = ModelAccess.on(getServletContext()).getBaseOntModel();
+	        memoryModel = ModelAccess.on(getServletContext()).getOntModel(FULL_ASSERTIONS);
 	    	System.out.println("baseOntModel");
 	    } else if (request.getParameter("inferences") != null) {
-	    	memoryModel = ModelAccess.on(getServletContext()).getInferenceOntModel();
+	    	memoryModel = ModelAccess.on(getServletContext()).getOntModel(FULL_INFERENCES);
 	    	System.out.println("inferenceOntModel");
 	    } else if (request.getParameter("pellet") != null) {
 	    	memoryModel = (OntModel) getServletContext().getAttribute("pelletOntModel");
 	    	System.out.println("pelletOntModel");
 	    } else {
-			memoryModel = ModelAccess.on(getServletContext()).getJenaOntModel();
+			memoryModel = ModelAccess.on(getServletContext()).getOntModel();
 	    	System.out.println("jenaOntModel");
 	    }  
 	    int subModelCount = memoryModel.listSubModels().toList().size();
@@ -319,7 +322,7 @@ public class JenaAdminActions extends BaseEditController {
         }
         
         if (actionStr.equals("outputTaxonomy")) {
-            OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel();
+            OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(FULL_ASSERTIONS);
         	Model taxonomyModel = extractTaxonomy(ontModel);
         	try {
         		taxonomyModel.write(response.getOutputStream());
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaExportController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaExportController.java
index 880c05b5c..9a5f8ca18 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaExportController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaExportController.java
@@ -2,6 +2,12 @@
 
 package edu.cornell.mannlib.vitro.webapp.controller.jena;
 
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_INFERENCES;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.APPLICATION_METADATA;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_INFERENCES;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_UNION;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -28,9 +34,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
 import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
 import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
 import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
-import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaModelUtils;
-import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
+import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
@@ -118,7 +123,7 @@ public class JenaExportController extends BaseEditController {
 		if( "abox".equals(subgraphParam)){
 			model = ModelFactory.createDefaultModel();
 			if("inferred".equals(assertedOrInferredParam)){
-				model = ModelAccess.on(getServletContext()).getOntModel(ModelNames.ABOX_INFERENCES);
+				model = ModelAccess.on(getServletContext()).getOntModel(ABOX_INFERENCES);
 			}
 			else if("full".equals(assertedOrInferredParam)){
 			    outputSparqlConstruct(ABOX_FULL_CONSTRUCT, formatParam, response);
@@ -133,9 +138,9 @@ public class JenaExportController extends BaseEditController {
 		        // so we'll extract the whole ontology and then include
 		        // only those statements that are in the inferred graph
 		        Model tempModel = xutil.extractTBox(
-		        		ModelAccess.on(getServletContext()).getOntModel(ModelNames.TBOX_UNION),
+		        		ModelAccess.on(getServletContext()).getOntModel(TBOX_UNION),
 		                ontologyURI);
-		        Model inferenceModel = ModelAccess.on(getServletContext()).getOntModel(ModelNames.TBOX_INFERENCES);
+		        Model inferenceModel = ModelAccess.on(getServletContext()).getOntModel(TBOX_INFERENCES);
 		        inferenceModel.enterCriticalSection(Lock.READ);
 		        try {
     		        model = tempModel.intersection(inferenceModel);
@@ -144,20 +149,20 @@ public class JenaExportController extends BaseEditController {
 		        }
 		    } else if ("full".equals(assertedOrInferredParam)) {
                 model = xutil.extractTBox(
-                		ModelAccess.on(getServletContext()).getOntModel(ModelNames.TBOX_UNION),
+                		ModelAccess.on(getServletContext()).getOntModel(TBOX_UNION),
                         ontologyURI);		        
 		    } else {
                 model = xutil.extractTBox(
-                        ModelAccess.on(getServletContext()).getOntModel(ModelNames.TBOX_ASSERTIONS), ontologyURI);              		        
+                        ModelAccess.on(getServletContext()).getOntModel(TBOX_ASSERTIONS), ontologyURI);              		        
 		    }
 			
 		}
 		else if("full".equals(subgraphParam)){
 			if("inferred".equals(assertedOrInferredParam)){
 				ontModel = xutil.extractTBox(
-						dataset, ontologyURI, ModelNames.ABOX_INFERENCES);
-				ontModel.addSubModel(ModelAccess.on(getServletContext()).getOntModel(ModelNames.ABOX_INFERENCES));
-				ontModel.addSubModel(ModelAccess.on(getServletContext()).getOntModel(ModelNames.TBOX_INFERENCES));
+						dataset, ontologyURI, ABOX_INFERENCES);
+				ontModel.addSubModel(ModelAccess.on(getServletContext()).getOntModel(ABOX_INFERENCES));
+				ontModel.addSubModel(ModelAccess.on(getServletContext()).getOntModel(TBOX_INFERENCES));
 			}
 			else if("full".equals(assertedOrInferredParam)){
 			    outputSparqlConstruct(FULL_FULL_CONSTRUCT, formatParam, response);
@@ -228,7 +233,7 @@ public class JenaExportController extends BaseEditController {
 	
 	private void outputSparqlConstruct(String queryStr, String formatParam, 
 	        HttpServletResponse response) {
-	    RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(getServletContext()).getRDFService();
+	    RDFService rdfService = ModelAccess.on(getServletContext()).getRDFService();
 	    try {
 	        setHeaders(response, formatParam);
 	        OutputStream out = response.getOutputStream();
@@ -284,19 +289,19 @@ public class JenaExportController extends BaseEditController {
 	
 	private static final String ABOX_FULL_CONSTRUCT = "CONSTRUCT { ?s ?p ?o } " +
 	        "WHERE { GRAPH ?g { ?s ?p ?o } FILTER (!regex(str(?g), \"tbox\")) " +
-            "FILTER (?g != <" + ModelNames.APPLICATION_METADATA + ">) }";
+            "FILTER (?g != <" + APPLICATION_METADATA + ">) }";
 	
 	private static final String ABOX_ASSERTED_CONSTRUCT = "CONSTRUCT { ?s ?p ?o } " +
             "WHERE { GRAPH ?g { ?s ?p ?o } FILTER (!regex(str(?g), \"tbox\")) " + 
-	        "FILTER (?g != <" + ModelNames.ABOX_INFERENCES + ">) " +
-	        "FILTER (?g != <" + ModelNames.APPLICATION_METADATA + ">) }";
+	        "FILTER (?g != <" + ABOX_INFERENCES + ">) " +
+	        "FILTER (?g != <" + APPLICATION_METADATA + ">) }";
 	
 	private static final String FULL_FULL_CONSTRUCT = "CONSTRUCT { ?s ?p ?o } " +
             "WHERE { ?s ?p ?o }";
 
     private static final String FULL_ASSERTED_CONSTRUCT = "CONSTRUCT { ?s ?p ?o } " +
             "WHERE { GRAPH ?g { ?s ?p ?o } " + 
-            "FILTER (?g != <" + ModelNames.ABOX_INFERENCES + ">) " +
-            "FILTER (?g != <" + ModelNames.TBOX_INFERENCES + ">) }";
+            "FILTER (?g != <" + ABOX_INFERENCES + ">) " +
+            "FILTER (?g != <" + TBOX_INFERENCES + ">) }";
     
 }
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java
index d4f115fd0..6a2dba03e 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java
@@ -2,8 +2,12 @@
 
 package edu.cornell.mannlib.vitro.webapp.controller.jena;
 
-import static edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelMakerID.CONFIGURATION;
-import static edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelMakerID.CONTENT;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_ASSERTIONS;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_UNION;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -63,18 +67,15 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
 import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
 import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
 import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
-import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
-import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelMakerID;
 import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.BlankNodeFilteringModelMaker;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
-import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
+import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
+import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
-import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
-import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService;
 import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
 import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils;
 import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult;
@@ -122,7 +123,7 @@ public class JenaIngestController extends BaseEditController {
         
         VitroRequest vreq = new VitroRequest(request);   
         ModelMaker maker = getModelMaker(vreq);
-        ModelMakerID modelType = getModelType(vreq);
+        WhichService modelType = getModelType(vreq);
         
         String actionStr = vreq.getParameter("action");
         actionStr = (actionStr != null) ? actionStr : "";
@@ -203,7 +204,7 @@ public class JenaIngestController extends BaseEditController {
         
     }
     
-    private void processListModelsRequest(VitroRequest vreq, ModelMaker maker, ModelMakerID modelType) {
+    private void processListModelsRequest(VitroRequest vreq, ModelMaker maker, WhichService modelType) {
         showModelList(vreq, maker, modelType);
     }
     
@@ -223,7 +224,7 @@ public class JenaIngestController extends BaseEditController {
         showModelList(vreq, vsmm, CONTENT);
     }
     
-    private void processCreateModelRequest(VitroRequest vreq, ModelMaker maker, ModelMakerID modelType) {
+    private void processCreateModelRequest(VitroRequest vreq, ModelMaker maker, WhichService modelType) {
         String modelName = vreq.getParameter("modelName");
     	
         if (modelName != null) {
@@ -248,7 +249,7 @@ public class JenaIngestController extends BaseEditController {
         }
     }
     
-    private void processRemoveModelRequest(VitroRequest vreq, ModelMaker maker, ModelMakerID modelType) {
+    private void processRemoveModelRequest(VitroRequest vreq, ModelMaker maker, WhichService modelType) {
         String modelName = vreq.getParameter("modelName");
         if (modelName!=null) {
             doRemoveModel(modelName, maker);
@@ -256,7 +257,7 @@ public class JenaIngestController extends BaseEditController {
         showModelList(vreq, maker, modelType);
     }
     
-    private void processClearModelRequest(VitroRequest vreq, ModelMaker maker, ModelMakerID modelType) {
+    private void processClearModelRequest(VitroRequest vreq, ModelMaker maker, WhichService modelType) {
         String modelName = vreq.getParameter("modelName");
         if (modelName != null) {
             doClearModel(modelName,maker);
@@ -316,7 +317,7 @@ public class JenaIngestController extends BaseEditController {
         vreq.setAttribute("bodyJsp",INGEST_MENU_JSP);
     }
     
-    private void processAttachModelRequest(VitroRequest vreq, ModelMaker maker, ModelMakerID modelType) {
+    private void processAttachModelRequest(VitroRequest vreq, ModelMaker maker, WhichService modelType) {
         String modelName = vreq.getParameter("modelName");
         if (modelName != null) {
             doAttachModel(modelName,maker);
@@ -324,7 +325,7 @@ public class JenaIngestController extends BaseEditController {
         showModelList(vreq, maker, modelType);
     }
     
-    private void processDetachModelRequest(VitroRequest vreq, ModelMaker maker, ModelMakerID modelType) {
+    private void processDetachModelRequest(VitroRequest vreq, ModelMaker maker, WhichService modelType) {
         String modelName = vreq.getParameter("modelName");
         if (modelName != null) {
             doDetachModel(modelName);
@@ -464,7 +465,7 @@ public class JenaIngestController extends BaseEditController {
             vreq.setAttribute("title", "Choose Workflow Step");
             vreq.setAttribute("bodyJsp", WORKFLOW_STEP_JSP);
         } else {
-    		OntModel jenaOntModel = ModelAccess.on(getServletContext()).getJenaOntModel();
+    		OntModel jenaOntModel = ModelAccess.on(getServletContext()).getOntModel();
             jenaOntModel.enterCriticalSection(Lock.READ);
             List savedQueryList = new LinkedList();
             try {
@@ -481,7 +482,7 @@ public class JenaIngestController extends BaseEditController {
     
     private void processExecuteSparqlRequest(VitroRequest vreq) {
         String sparqlQueryStr = vreq.getParameter("sparqlQueryStr");
-		OntModel jenaOntModel = ModelAccess.on(getServletContext()).getJenaOntModel();
+		OntModel jenaOntModel = ModelAccess.on(getServletContext()).getOntModel();
         jenaOntModel.enterCriticalSection(Lock.READ);
         List savedQueryList = new LinkedList();
         try {
@@ -607,8 +608,8 @@ public class JenaIngestController extends BaseEditController {
               /*
                * get baseOnt and infOnt models
                */
-              OntModel baseOntModel = ModelAccess.on(getServletContext()).getBaseOntModel();
-              OntModel tboxOntModel = ModelAccess.on(getServletContext()).getOntModel(ModelNames.TBOX_UNION);
+              OntModel baseOntModel = ModelAccess.on(getServletContext()).getOntModel(FULL_ASSERTIONS);
+              OntModel tboxOntModel = ModelAccess.on(getServletContext()).getOntModel(TBOX_UNION);
               
               /*
                * calling method that does the merge operation.
@@ -679,7 +680,7 @@ public class JenaIngestController extends BaseEditController {
     /**
      * Get the model type from the request, or from the session.
      */
-    protected ModelMakerID getModelType(VitroRequest vreq) {
+    protected WhichService getModelType(VitroRequest vreq) {
         String modelType = vreq.getParameter("modelType");
 		if (modelType != null) {
 			if (modelType.equals(CONFIGURATION.toString())) {
@@ -757,7 +758,7 @@ public class JenaIngestController extends BaseEditController {
         }
         Model m = ModelFactory.createDefaultModel();
         m.add(modelMaker.getModel(modelName));        
-        ModelAccess.on(getServletContext()).getOntModel(ModelNames.TBOX_ASSERTIONS).addSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(TBOX_ASSERTIONS).addSubModel(m);
         attachedModels.put(modelName, m);
         log.info("Attached " + modelName + " (" + m.hashCode() + ") to webapp");
     }
@@ -767,7 +768,7 @@ public class JenaIngestController extends BaseEditController {
         if (m == null) {
             return;
         }
-        ModelAccess.on(getServletContext()).getOntModel(ModelNames.TBOX_ASSERTIONS).removeSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(TBOX_ASSERTIONS).removeSubModel(m);
         attachedModels.remove(modelName);
         log.info("Detached " + modelName + " (" + m.hashCode() + ") from webapp");
     }
@@ -835,7 +836,7 @@ public class JenaIngestController extends BaseEditController {
     }
     
     private long doExecuteSparql(VitroRequest vreq) {
-		OntModel jenaOntModel = ModelAccess.on(getServletContext()).getJenaOntModel();
+		OntModel jenaOntModel = ModelAccess.on(getServletContext()).getOntModel();
         OntModel source = null;
         if ("pellet".equals(vreq.getParameter("reasoning"))) {
             source = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
@@ -1073,13 +1074,13 @@ public class JenaIngestController extends BaseEditController {
         String result = null;
         Integer counter = 0;
         Boolean namespacePresent = false;
-        RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(
-                getServletContext()).getRDFService();
+		RDFService rdfService = ModelAccess.on(getServletContext())
+				.getRDFService();
         try {
             Model baseOntModel = RDFServiceGraph.createRDFServiceModel
                     (new RDFServiceGraph(
-                            rdfService, ModelNames.ABOX_ASSERTIONS));
-    		OntModel ontModel = ModelAccess.on(getServletContext()).getJenaOntModel();
+                            rdfService, ABOX_ASSERTIONS));
+    		OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel();
             List urisToChange = new LinkedList();        
             ontModel.enterCriticalSection(Lock.READ);
             try {
@@ -1117,7 +1118,7 @@ public class JenaIngestController extends BaseEditController {
                 log.debug("Renaming "+ oldURIStr + " to " + newURIStr);
          
                 String whereClause = "} WHERE { \n" +
-                        "  GRAPH <" + ModelNames.ABOX_ASSERTIONS + "> { \n" +  
+                        "  GRAPH <" + ABOX_ASSERTIONS + "> { \n" +  
                         "   { <" + oldURIStr + "> ?p <" + oldURIStr + "> } \n " +
                         "     UNION \n" +  
                         "   { <" + oldURIStr + "> ?q ?o } \n " +
@@ -1140,11 +1141,11 @@ public class JenaIngestController extends BaseEditController {
                     cs.addAddition(rdfService.sparqlConstructQuery(
                             addQuery, RDFService.ModelSerializationFormat.N3), 
                                     RDFService.ModelSerializationFormat.N3, 
-                                            ModelNames.ABOX_ASSERTIONS);
+                                            ABOX_ASSERTIONS);
                     cs.addRemoval(rdfService.sparqlConstructQuery(
                             removeQuery, RDFService.ModelSerializationFormat.N3), 
                                     RDFService.ModelSerializationFormat.N3, 
-                                            ModelNames.ABOX_ASSERTIONS); 
+                                            ABOX_ASSERTIONS); 
                     rdfService.changeSetUpdate(cs);
                 } catch (RDFServiceException e) {
                     throw new RuntimeException(e);
@@ -1165,7 +1166,7 @@ public class JenaIngestController extends BaseEditController {
         }
     }
     
-    protected void showModelList(VitroRequest vreq, ModelMaker maker, ModelMakerID modelType) {
+    protected void showModelList(VitroRequest vreq, ModelMaker maker, WhichService modelType) {
     	vreq.setAttribute("modelType", modelType.toString());
         if(modelType == CONTENT){
         	vreq.setAttribute("infoLine", "Main Store models");            
@@ -1205,19 +1206,14 @@ public class JenaIngestController extends BaseEditController {
     protected static ModelMaker getModelMaker(HttpServletRequest req){
         ServletContext ctx = req.getSession().getServletContext();
 		if (isUsingMainStoreForIngest(req)) {
-			RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx,
-					WhichService.CONTENT).getRDFService();
+			RDFService rdfService = ModelAccess.on(ctx).getRDFService(CONTENT);
 			return new BlankNodeFilteringModelMaker(rdfService, ModelAccess.on(
 					ctx).getModelMaker(CONTENT));
 		} else {
-			RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx,
-					WhichService.CONFIGURATION).getRDFService();
+			RDFService rdfService = ModelAccess.on(ctx).getRDFService(CONFIGURATION);
 			return new BlankNodeFilteringModelMaker(rdfService, ModelAccess.on(
 					ctx).getModelMaker(CONFIGURATION));
 		}
     }
-    
-
-    
 
 }
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java
index e8916dbf0..2d305c5c5 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java
@@ -2,6 +2,9 @@
 
 package edu.cornell.mannlib.vitro.webapp.controller.jena;
 
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_ASSERTIONS;
+import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -16,7 +19,6 @@ import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.logging.Log;
@@ -34,15 +36,14 @@ import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
 import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
 import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
 import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
-import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
-import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelMakerID;
 import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaModelUtils;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
-import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
+import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
+import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
@@ -112,7 +113,7 @@ public class RDFUploadController extends JenaIngestController {
         String uploadDesc ="";        
                 
         OntModel uploadModel = (directRead) 
-            ? getABoxModel(request.getSession(), getServletContext())
+            ? getABoxModel(getServletContext())
             : ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
             
         /* ********************* GET RDF by URL ********************** */
@@ -184,9 +185,9 @@ public class RDFUploadController extends JenaIngestController {
 
             JenaModelUtils xutil = new JenaModelUtils();
             
-            OntModel tboxModel = getTBoxModel(request.getSession());
+            OntModel tboxModel = getTBoxModel();
             OntModel aboxModel = getABoxModel(
-                    request.getSession(), getServletContext());
+                    getServletContext());
             OntModel tboxChangeModel = null;
             Model aboxChangeModel = null;
             OntModelSelector ontModelSelector = ModelAccess.on(getServletContext()).getOntModelSelector();
@@ -233,7 +234,7 @@ public class RDFUploadController extends JenaIngestController {
                                 ? RDFService.ModelSerializationFormat.RDFXML
                                 : RDFService.ModelSerializationFormat.N3;
         changeSet.addAddition(in, format, 
-                ModelNames.ABOX_ASSERTIONS);
+                ABOX_ASSERTIONS);
         try {
             rdfService.changeSetUpdate(changeSet);
         } catch (RDFServiceException rdfse) {
@@ -262,7 +263,7 @@ public class RDFUploadController extends JenaIngestController {
             } finally {
                 rdfService.close();
             }
-            ModelMakerID modelType = getModelType(request);
+            WhichService modelType = getModelType(request);
             showModelList(request, maker, modelType);
         } 
         
@@ -282,8 +283,7 @@ public class RDFUploadController extends JenaIngestController {
     private RDFService getRDFService(VitroRequest vreq, ModelMaker maker, String modelName) {
         if (isUsingMainStoreForIngest(vreq)) {
             log.debug("Using main RDFService");
-            return RDFServiceUtils.getRDFServiceFactory(
-                    getServletContext()).getRDFService();
+			return ModelAccess.on(getServletContext()).getRDFService();
         } else {
             log.debug("Making RDFService for single model from ModelMaker");
             Model m = maker.getModel(modelName);
@@ -431,15 +431,15 @@ public class RDFUploadController extends JenaIngestController {
          return;
      }
      
-     private OntModel getABoxModel(HttpSession session, ServletContext ctx) {   
-         RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService();
+     private OntModel getABoxModel(ServletContext ctx) {   
+         RDFService rdfService = ModelAccess.on(ctx).getRDFService();
          Model abox = RDFServiceGraph.createRDFServiceModel(
-                 new RDFServiceGraph(rdfService, ModelNames.ABOX_ASSERTIONS));
+                 new RDFServiceGraph(rdfService, ABOX_ASSERTIONS));
          return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, abox);
      }    
 
-     private OntModel getTBoxModel(HttpSession session) { 
-    	 return ModelAccess.on(session).getOntModel(ModelNames.TBOX_ASSERTIONS);
+     private OntModel getTBoxModel() { 
+    	 return ModelAccess.on(getServletContext()).getOntModel(TBOX_ASSERTIONS);
      }    
      
     private static final Log log = LogFactory.getLog(
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ModelAccess.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ModelAccess.java
deleted file mode 100644
index d9ef31dac..000000000
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ModelAccess.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/* $This file is distributed under the terms of the license in /doc/license.txt$ */
-
-package edu.cornell.mannlib.vitro.webapp.dao;
-
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.hp.hpl.jena.ontology.OntModel;
-import com.hp.hpl.jena.rdf.model.ModelMaker;
-
-import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
-import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl;
-import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
-import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory;
-
-/**
- * Hierarchical storage for models. TODO
- * 
- * Could this be extended? Could it be used to replace or implement these
- * methods?
- * 
- * 
- * VitroRequest.getAssertionsWebappDaoFactory()
- * VitroRequest.getFullWebappDaoFactory()
- * VitroRequest.getRDFService()
- * VitroRequest.getUnfilteredRDFService()
- * VitroRequest.getWebappDaoFactory()
- * VitroRequest.getWriteModel()
- * 
- * OntModelSelector.getABoxModel
- * OntModelSelector.getFullModel()
- * OntModelSelector.getTBoxModel()
- * VitroModelSource.getModel(URL)
- * VitroModelSource.getModel(URL, loadIfAbsent)
- * VitroModelSource.openModel(name)
- * VitroModelSource.openModelIfPresent(string)
- * ServletContext.getAttribute("pelletOntModel")
- * JenaDataSourceSetupBase.getStartupDataset()
- * HttpSession.getAttribute("jenaAuditModel")
- * 
- */ - -public class ModelAccess { - private static final Log log = LogFactory.getLog(ModelAccess.class); - - /** These attributes should only be accessed through this class. */ - private static final String ATTRIBUTE_NAME = ModelAccess.class.getName(); - - public enum FactoryID { - BASE, UNION, UNFILTERED_BASE, UNFILTERED_UNION - } - - public enum ModelMakerID { - CONTENT, CONFIGURATION - } - - private enum Scope { - CONTEXT, SESSION, REQUEST - } - - // ---------------------------------------------------------------------- - // Factory methods - // ---------------------------------------------------------------------- - - public static ModelAccess on(HttpServletRequest req) { - Object o = req.getAttribute(ATTRIBUTE_NAME); - if (o instanceof ModelAccess) { - return (ModelAccess) o; - } else { - ModelAccess parent = on(req.getSession()); - ModelAccess ma = new ModelAccess(Scope.REQUEST, parent); - req.setAttribute(ATTRIBUTE_NAME, ma); - return ma; - } - } - - public static ModelAccess on(HttpSession session) { - Object o = session.getAttribute(ATTRIBUTE_NAME); - if (o instanceof ModelAccess) { - return (ModelAccess) o; - } else { - ModelAccess parent = on(session.getServletContext()); - ModelAccess ma = new ModelAccess(Scope.SESSION, parent); - session.setAttribute(ATTRIBUTE_NAME, ma); - return ma; - } - } - - public static ModelAccess on(ServletContext ctx) { - Object o = ctx.getAttribute(ATTRIBUTE_NAME); - if (o instanceof ModelAccess) { - return (ModelAccess) o; - } else { - ModelAccess ma = new ModelAccess(Scope.CONTEXT, null); - ctx.setAttribute(ATTRIBUTE_NAME, ma); - return ma; - } - } - - // ---------------------------------------------------------------------- - // The instance - // ---------------------------------------------------------------------- - - private final Scope scope; - private final ModelAccess parent; - private final Map modelMap = new HashMap<>(); - private final Map factoryMap = new EnumMap<>( - FactoryID.class); - private final Map modelMakerMap = new EnumMap<>( - ModelMakerID.class); - - public ModelAccess(Scope scope, ModelAccess parent) { - this.scope = scope; - this.parent = parent; - } - - // ---------------------------------------------------------------------- - // Accessing the models - // ---------------------------------------------------------------------- - - public OntModel getApplicationMetadataModel() { - return getOntModel(ModelNames.APPLICATION_METADATA); - } - - public OntModel getUserAccountsModel() { - return getOntModel(ModelNames.USER_ACCOUNTS); - } - - public OntModel getDisplayModel() { - return getOntModel(ModelNames.DISPLAY); - } - - public OntModel getJenaOntModel() { - return getOntModel(ModelNames.FULL_UNION); - } - - public OntModel getBaseOntModel() { - return getOntModel(ModelNames.FULL_ASSERTIONS); - } - - public OntModel getInferenceOntModel() { - return getOntModel(ModelNames.FULL_INFERENCES); - } - - public void setOntModel(String id, OntModel ontModel) { - if (ontModel == null) { - modelMap.remove(id); - } else { - modelMap.put(id, ontModel); - } - } - - public OntModel getOntModel(String id) { - if (modelMap.containsKey(id)) { - log.debug("Using " + id + " model from " + scope); - return modelMap.get(id); - } else if (parent != null) { - return parent.getOntModel(id); - } else { - log.warn("No model found for " + id); - return null; - } - } - - // ---------------------------------------------------------------------- - // Accessing the Webapp DAO factories. - // ---------------------------------------------------------------------- - - public void setWebappDaoFactory(WebappDaoFactory wadf) { - setWebappDaoFactory(FactoryID.UNION, wadf); - } - - public WebappDaoFactory getWebappDaoFactory() { - return getWebappDaoFactory(FactoryID.UNION); - } - - public void setBaseWebappDaoFactory(WebappDaoFactory wadf) { - setWebappDaoFactory(FactoryID.BASE, wadf); - } - - public WebappDaoFactory getBaseWebappDaoFactory() { - return getWebappDaoFactory(FactoryID.BASE); - } - - public void setWebappDaoFactory(FactoryID id, WebappDaoFactory wadf) { - if (wadf == null) { - factoryMap.remove(id); - } else { - factoryMap.put(id, wadf); - } - } - - public void removeWebappDaoFactory(FactoryID id) { - setWebappDaoFactory(id, null); - } - - public WebappDaoFactory getWebappDaoFactory(FactoryID id) { - if (factoryMap.containsKey(id)) { - log.debug("Using " + id + " DAO factory from " + scope); - return factoryMap.get(id); - } else if (parent != null) { - return parent.getWebappDaoFactory(id); - } else { - log.warn("No DAO factory found for " + id); - return null; - } - } - - // ---------------------------------------------------------------------- - // Accessing the OntModelSelectors - // ---------------------------------------------------------------------- - - public OntModelSelector getOntModelSelector() { - return getUnionOntModelSelector(); - } - - public OntModelSelector getBaseOntModelSelector() { - return createOntModelSelector(ModelNames.ABOX_ASSERTIONS, - ModelNames.TBOX_ASSERTIONS, ModelNames.FULL_ASSERTIONS); - } - - public OntModelSelector getInferenceOntModelSelector() { - return createOntModelSelector(ModelNames.ABOX_INFERENCES, - ModelNames.TBOX_INFERENCES, ModelNames.FULL_INFERENCES); - } - - public OntModelSelector getUnionOntModelSelector() { - return createOntModelSelector(ModelNames.ABOX_UNION, - ModelNames.TBOX_UNION, ModelNames.FULL_UNION); - } - - // ---------------------------------------------------------------------- - // Accessing the ModelMakers - // ---------------------------------------------------------------------- - - public ModelMaker getModelMaker(ModelMakerID id) { - if (modelMakerMap.containsKey(id)) { - log.debug("Using " + id + " modelMaker from " + scope); - return modelMakerMap.get(id); - } else if (parent != null) { - return parent.getModelMaker(id); - } else { - log.warn("No modelMaker found for " + id); - return null; - } - } - - public void setModelMaker(ModelMakerID id, ModelMaker modelMaker) { - modelMakerMap.put(id, modelMaker); - if (id == ModelMakerID.CONFIGURATION) { - setOntModel(modelMaker, ModelNames.USER_ACCOUNTS); - setOntModel(modelMaker, ModelNames.DISPLAY); - setOntModel(modelMaker, ModelNames.DISPLAY_DISPLAY); - setOntModel(modelMaker, ModelNames.DISPLAY_TBOX); - } else { - setOntModel(modelMaker, ModelNames.APPLICATION_METADATA); - setOntModel(modelMaker, ModelNames.TBOX_ASSERTIONS); - setOntModel(modelMaker, ModelNames.TBOX_INFERENCES); - setOntModel(modelMaker, ModelNames.TBOX_UNION); - setOntModel(modelMaker, ModelNames.ABOX_ASSERTIONS); - setOntModel(modelMaker, ModelNames.ABOX_INFERENCES); - setOntModel(modelMaker, ModelNames.ABOX_UNION); - setOntModel(modelMaker, ModelNames.FULL_ASSERTIONS); - setOntModel(modelMaker, ModelNames.FULL_INFERENCES); - setOntModel(modelMaker, ModelNames.FULL_UNION); - - /* - * KLUGE - * - * For some reason, the union of two OntModels (like this) works - * fine as the TBOX_UNION, but an OntModel wrapped around the union - * of two Models (from ModelMakers) does not work. - * - * See also the Kluge in RequestModelsPrep. - */ - setOntModel(ModelNames.TBOX_UNION, VitroModelFactory.createUnion( - getOntModel(ModelNames.TBOX_ASSERTIONS), - getOntModel(ModelNames.TBOX_INFERENCES))); - } - } - - private void setOntModel(ModelMaker mm, String name) { - setOntModel(name, - VitroModelFactory.createOntologyModel(mm.getModel(name))); - } - - private OntModelSelector createOntModelSelector(String aboxName, - String tboxName, String fullName) { - OntModelSelectorImpl oms = new OntModelSelectorImpl(); - - oms.setApplicationMetadataModel(getOntModel(ModelNames.APPLICATION_METADATA)); - oms.setDisplayModel(getOntModel(ModelNames.DISPLAY)); - oms.setUserAccountsModel(getOntModel(ModelNames.USER_ACCOUNTS)); - - oms.setABoxModel(getOntModel(aboxName)); - oms.setTBoxModel(getOntModel(tboxName)); - oms.setFullModel(getOntModel(fullName)); - - return oms; - } - - // ---------------------------------------------------------------------- - // Close all locally stored models, WADFs, etc. - // ---------------------------------------------------------------------- - - public void close() { - if (this.scope == Scope.REQUEST) { - for (WebappDaoFactory wadf : factoryMap.values()) { - wadf.close(); - } - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupsForRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupsForRequest.java index 20484b00b..b775e08b5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupsForRequest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupsForRequest.java @@ -16,6 +16,7 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * A request-based image of the VClassGroupCache. That means that the names of diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java index 828757a2d..b362daca8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java @@ -3,7 +3,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.filtering; import java.util.List; -import java.util.Map; import java.util.Set; import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao; @@ -73,9 +72,15 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory { this.innerWebappDaoFactory = innerDao; } + @Override + public String toString() { + return "WebappDaoFactoryFiltering[inner=" + innerWebappDaoFactory + "]"; + } + /* ******************* filtering *********************** */ - public String checkURI(String uriStr) { + + public String checkURI(String uriStr) { return innerWebappDaoFactory.checkURI(uriStr); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/BlankNodeFilteringGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/BlankNodeFilteringGraph.java index 5e28f248e..a1c663ba5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/BlankNodeFilteringGraph.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/BlankNodeFilteringGraph.java @@ -20,7 +20,7 @@ import com.hp.hpl.jena.shared.PrefixMapping; import com.hp.hpl.jena.util.iterator.ExtendedIterator; import com.hp.hpl.jena.util.iterator.WrappedIterator; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class BlankNodeFilteringGraph implements Graph { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DifferenceGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DifferenceGraph.java index b393c60a0..ee5c8e55b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DifferenceGraph.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DifferenceGraph.java @@ -19,7 +19,7 @@ import com.hp.hpl.jena.shared.PrefixMapping; import com.hp.hpl.jena.util.iterator.ExtendedIterator; import com.hp.hpl.jena.util.iterator.WrappedIterator; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class DifferenceGraph implements Graph { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/MemToDBModelSynchronizer.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/MemToDBModelSynchronizer.java deleted file mode 100644 index de575b5be..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/MemToDBModelSynchronizer.java +++ /dev/null @@ -1,115 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import java.sql.SQLException; - -import com.hp.hpl.jena.graph.Graph; -import com.hp.hpl.jena.rdf.listeners.StatementListener; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Statement; - -/** - * This listener will open and close DB models as it performs edits to avoid - * wasting DB connections - * @author bjl23 - * - */ -public class MemToDBModelSynchronizer extends StatementListener { - - private static long IDLE_MILLIS = 2000; // how long to let a model site idle - // after an edit has been performed - - SQLGraphGenerator generator; - Model model; - boolean editInProgress; - boolean cleanupThreadActive; - long lastEditTimeMillis; - - public MemToDBModelSynchronizer(SQLGraphGenerator generator) { - this.generator = generator; - } - - private Model getModel() { - if ( model != null && !model.isClosed() ) { - return model; - } else { - Graph g = generator.generateGraph(); - model = ModelFactory.createModelForGraph(g); - return model; - } - } - - @Override - public void addedStatement(Statement stmt) { - this.editInProgress = true; - try { - getModel().add(stmt); - } finally { - lastEditTimeMillis = System.currentTimeMillis(); - this.editInProgress = false; - if (!cleanupThreadActive) { - (new Thread( - new Cleanup(this), "MemToDBModelSynchronizer")).start(); - } - } - } - - @Override - public void removedStatement(Statement stmt) { - this.editInProgress = true; - try { - getModel().remove(stmt); - } finally { - lastEditTimeMillis = System.currentTimeMillis(); - this.editInProgress = false; - if (!cleanupThreadActive) { - (new Thread( - new Cleanup(this), "MemToDBModelSynchronizer")).start(); - } - } - } - - private class Cleanup implements Runnable { - - private MemToDBModelSynchronizer s; - - public Cleanup(MemToDBModelSynchronizer s) { - this.s = s; - } - - public void run() { - s.cleanupThreadActive = true; - while( (s.editInProgress) - || (System.currentTimeMillis() - - s.lastEditTimeMillis < IDLE_MILLIS ) ) { - try { - Thread.currentThread().sleep(1000); - } catch (InterruptedException e) { - throw new RuntimeException( - "Interrupted cleanup thread in " - + this.getClass().getName(), e); - } - } - if (s.model != null) { - s.model.close(); - s.model = null; - } else { - throw new RuntimeException( - this.getClass().getName() + "Model already null"); - } - java.sql.Connection c = generator.getConnection(); - try { - if ( (c != null) && (!c.isClosed()) ) { - c.close(); - } - } catch (SQLException e) { - throw new RuntimeException(e); - } - s.cleanupThreadActive = false; - } - - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelSynchronizer.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelSynchronizer.java deleted file mode 100644 index 4c3077656..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelSynchronizer.java +++ /dev/null @@ -1,117 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelChangedListener; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.rdf.model.impl.StmtIteratorImpl; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.event.CloseEvent; - -/** - * Simple change listener to keep a model (the 'synchronizee') in synch with the - * model with which it is registered. - * - * @author bjl23 - * - */ -public class ModelSynchronizer implements ModelChangedListener { - private static final Log log = LogFactory.getLog(ModelSynchronizer.class); - - private Model m; - private String hash; - - public ModelSynchronizer(Model synchronizee, String name) { - this.m = synchronizee; - this.hash = Integer.toHexString(this.hashCode()); - log.debug(String.format("create: %s, wraps %s(%s) as %s", hash, this.m - .getClass().getName(), Integer.toHexString(this.m.hashCode()), - name)); - } - - @Override - public void addedStatement(Statement s) { - log.debug(hash + " addedStatement" + s); - m.add(s); - } - - @Override - public void addedStatements(Statement[] statements) { - log.debug(hash + " addedStatements: " + statements.length); - m.add(statements); - } - - @Override - public void addedStatements(List statements) { - log.debug(hash + " addedStatements: " + statements.size()); - m.add(statements); - } - - @Override - public void addedStatements(StmtIterator statements) { - if (log.isDebugEnabled()) { - Set set = statements.toSet(); - log.debug(hash + " addedStatements: " + set.size()); - m.add(new StmtIteratorImpl(set.iterator())); - } else { - m.add(new StmtIteratorImpl(statements)); - } - } - - @Override - public void addedStatements(Model model) { - log.debug(hash + " addedStatements: " + model.size()); - m.add(model); - } - - @Override - public void notifyEvent(Model model, Object event) { - if (event instanceof CloseEvent) { - m.close(); - } - } - - @Override - public void removedStatement(Statement s) { - log.debug(hash + " removedStatement" + s); - m.remove(s); - } - - @Override - public void removedStatements(Statement[] statements) { - log.debug(hash + " removedStatements: " + statements.length); - m.remove(statements); - } - - @Override - public void removedStatements(List statements) { - log.debug(hash + " removedStatements: " + statements.size()); - m.remove(statements); - } - - @Override - public void removedStatements(StmtIterator statements) { - if (log.isDebugEnabled()) { - Set set = statements.toSet(); - log.debug(hash + " removedStatements: " + set.size()); - m.remove(new StmtIteratorImpl(set.iterator())); - } else { - m.remove(new StmtIteratorImpl(statements)); - } - } - - @Override - public void removedStatements(Model model) { - log.debug(hash + " removedStatements: " + model.size()); - m.remove(model); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelectorImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelectorImpl.java index a80d064f2..bd7dcc73a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelectorImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelectorImpl.java @@ -12,7 +12,7 @@ public class OntModelSelectorImpl implements OntModelSelector { private OntModel fullModel; private OntModel tboxModel; private OntModel userAccountsModel; - + @Override public OntModel getABoxModel() { return this.aboxModel; @@ -42,11 +42,11 @@ public class OntModelSelectorImpl implements OntModelSelector { public OntModel getUserAccountsModel() { return this.userAccountsModel; } - + public void setABoxModel(OntModel m) { this.aboxModel = m; } - + public void setApplicationMetadataModel(OntModel m) { this.applicationMetadataModel = m; } @@ -54,17 +54,26 @@ public class OntModelSelectorImpl implements OntModelSelector { public void setDisplayModel(OntModel m) { this.displayModel = m; } - + public void setTBoxModel(OntModel m) { this.tboxModel = m; } - + public void setUserAccountsModel(OntModel m) { this.userAccountsModel = m; } - + public void setFullModel(OntModel m) { this.fullModel = m; } - + + @Override + public String toString() { + return "OntModelSelectorImpl[abox=" + hashHex(aboxModel) + ", tbox=" + + hashHex(tboxModel) + ", full=" + hashHex(fullModel) + "]"; + } + + private String hashHex(Object o) { + return (o == null) ? "00000000" : Integer.toString(o.hashCode(), 16); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java index 9e2d85e53..ae2bbfc34 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java @@ -16,7 +16,7 @@ import com.hp.hpl.jena.sparql.core.DatasetGraph; import com.hp.hpl.jena.sparql.util.Context; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class RDFServiceDataset implements Dataset { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java index 736860e59..b2f010b5d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java @@ -24,6 +24,7 @@ import com.hp.hpl.jena.util.iterator.WrappedIterator; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class RDFServiceDatasetGraph implements DatasetGraph { @@ -224,4 +225,9 @@ public class RDFServiceDatasetGraph implements DatasetGraph { return (node == null || node.isVariable() || node == Node.ANY); } + @Override + public String toString() { + return "RDFServiceDatasetGraph[" + ToString.hashHex(this) + + ", " + rdfService + "]"; + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java index bba1d4b97..61afe6091 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java @@ -39,7 +39,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class RDFServiceGraph implements GraphWithPerform { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java index 3325605d6..2ae6886c0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java @@ -160,4 +160,9 @@ public class RDFServiceModelMaker implements ModelMaker { return dataset.getNamedModel(name); } + @Override + public String toString() { + return "RDFServiceModelMaker[service=" + service + "]"; + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RegeneratingGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RegeneratingGraph.java index 392839081..da205d408 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RegeneratingGraph.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RegeneratingGraph.java @@ -21,7 +21,7 @@ import com.hp.hpl.jena.util.iterator.ExtendedIterator; import com.hp.hpl.jena.vocabulary.DCTerms; import com.hp.hpl.jena.vocabulary.RDF; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class RegeneratingGraph implements Graph, Regenerable { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java index 5ff4a009f..c64b5c444 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java @@ -43,7 +43,7 @@ import com.hp.hpl.jena.util.iterator.ExtendedIterator; import com.hp.hpl.jena.util.iterator.SingletonIterator; import com.hp.hpl.jena.util.iterator.WrappedIterator; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class SparqlGraph implements GraphWithPerform { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java index a743c5bef..74a93d7a2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java @@ -21,7 +21,7 @@ import com.hp.hpl.jena.shared.AddDeniedException; import com.hp.hpl.jena.util.iterator.ExtendedIterator; import com.hp.hpl.jena.util.iterator.WrappedIterator; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class SparqlGraphMultilingual extends SparqlGraph implements GraphWithPerform { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java index 6853d8cf6..fdc102166 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java @@ -27,7 +27,6 @@ import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; @@ -35,6 +34,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilterUtils; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchFacetField; @@ -498,7 +498,7 @@ public class VClassGroupCache implements IndexingEventListener { } else if(VitroVocabulary.DISPLAY_RANK.equals(stmt.getPredicate().getURI())){ requestCacheUpdate(); } else { - OntModel jenaOntModel = ModelAccess.on(context).getJenaOntModel(); + OntModel jenaOntModel = ModelAccess.on(context).getOntModel(); if( isClassNameChange(stmt, jenaOntModel) ) { requestCacheUpdate(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroModelSource.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroModelSource.java index 906141a00..bddf240db 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroModelSource.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroModelSource.java @@ -9,7 +9,7 @@ import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelReader; import com.hp.hpl.jena.rdf.model.ModelSource; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; /** @@ -107,11 +107,11 @@ public class VitroModelSource implements ModelSource { private Model getNamedModel( ModelName pmn ){ switch( pmn ){ case ABOX: - return ModelAccess.on(context).getJenaOntModel(); + return ModelAccess.on(context).getOntModel(); case TBOX: return (Model) context.getAttribute("tboxmodel???"); case DISPLAY: - return ModelAccess.on(context).getDisplayModel(); + return ModelAccess.on(context).getOntModel(ModelNames.DISPLAY); case DISPLAY_TBOX: return ModelAccess.on(context).getOntModel(ModelNames.DISPLAY_TBOX); case DISPLAY_DISPLAY: diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java index f613018f1..c7d6197ee 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java @@ -49,8 +49,14 @@ public class WebappDaoFactorySDB extends WebappDaoFactoryJena { this.datasetMode = datasetMode; } } - - public WebappDaoFactorySDB(WebappDaoFactorySDB base, String userURI) { + + @Override + public String toString() { + return "WebappDaoFactorySDB[" + Integer.toString(hashCode(), 16) + ", " + + datasetMode + "]"; + } + + public WebappDaoFactorySDB(WebappDaoFactorySDB base, String userURI) { super(base.ontModelSelector); this.ontModelSelector = base.ontModelSelector; this.config = base.config; @@ -94,6 +100,7 @@ public class WebappDaoFactorySDB extends WebappDaoFactoryJena { return vClassDao = new VClassDaoSDB(dwf, datasetMode, this, config.isUnderlyingStoreReasoned()); } + @Override public WebappDaoFactory getUserAwareDaoFactory(String userURI) { return new WebappDaoFactorySDB(this, userURI); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dwr/EntityDWR.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dwr/EntityDWR.java index c3872f70f..289cf0f45 100755 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dwr/EntityDWR.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dwr/EntityDWR.java @@ -15,7 +15,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.dao.InsertException; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** This is a class to support Direct Web Remoting(DWR) in diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java index a53e3f65e..a445b091c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java @@ -23,11 +23,11 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import freemarker.template.Configuration; public class EditConfigurationUtils { @@ -215,7 +215,7 @@ public class EditConfigurationUtils { public static DataPropertyStatement getDataPropertyStatement(VitroRequest vreq, HttpSession session, Integer dataHash, String predicateUri) { DataPropertyStatement dps = null; if( dataHash != 0) { - OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); + OntModel model = ModelAccess.on(session.getServletContext()).getOntModel(); dps = RdfLiteralHash.getPropertyStmtByHash(EditConfigurationUtils.getSubjectUri(vreq), predicateUri, dataHash, model); } return dps; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/N3EditUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/N3EditUtils.java index 726adcb3b..df0189e31 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/N3EditUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/N3EditUtils.java @@ -1,7 +1,8 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; -import java.lang.reflect.Constructor; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; + import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; @@ -17,12 +18,10 @@ import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; -import com.hp.hpl.jena.query.QuerySolutionMap; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Literal; 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 edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; @@ -32,10 +31,9 @@ import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.ModelChangePreprocessor; -import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetterUtils; public class N3EditUtils { @@ -52,7 +50,7 @@ public class N3EditUtils { List modelChangePreprocessors = editConfiguration.getModelChangePreprocessors(); //Check if there is a default set of preprocessors for the whole application - List defaultPreprocessors = getDefaultModelChangePreprocessors(request, ModelAccess.on(request).getDisplayModel()); + List defaultPreprocessors = getDefaultModelChangePreprocessors(request, ModelAccess.on(request).getOntModel(DISPLAY)); if(modelChangePreprocessors != null) { //if preprocessors exist for the configuration, add default preprocessors to the end modelChangePreprocessors.addAll(defaultPreprocessors); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/IdModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/IdModelSelector.java index e25833c7f..7051e61d9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/IdModelSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/IdModelSelector.java @@ -1,7 +1,7 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration; -import static edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelMakerID.CONTENT; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -9,8 +9,8 @@ import javax.servlet.http.HttpServletRequest; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelMaker; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class IdModelSelector implements ModelSelector { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java index 6fb134cff..ce6a4f7da 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_UNION; + import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -10,15 +12,14 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class StandardModelSelector implements ModelSelector { - private static final Log log = LogFactory.getLog(StandardModelSelector.class); - public OntModel getModel(HttpServletRequest request, ServletContext context) { - return ModelAccess.on(request.getSession()).getOntModel(ModelNames.ABOX_UNION); + @Override + public OntModel getModel(HttpServletRequest request, ServletContext context) { + return ModelAccess.on(context).getOntModel(ABOX_UNION); } public static final ModelSelector selector = new StandardModelSelector(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java index 0599081bd..dac6eb3df 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java @@ -11,11 +11,11 @@ import org.apache.commons.lang.StringUtils; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.IdModelSelector; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.StandardModelSelector; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public abstract class BaseEditConfigurationGenerator implements EditConfigurationGenerator { @@ -62,7 +62,7 @@ public abstract class BaseEditConfigurationGenerator implements EditConfiguratio //setup the model selectors for query, write and display models on editConfig setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = ModelAccess.on(vreq).getJenaOntModel(); + OntModel queryModel = ModelAccess.on(vreq).getOntModel(); if( editConfig.getSubjectUri() == null) editConfig.setSubjectUri( EditConfigurationUtils.getSubjectUri(vreq)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java index 0a8a866a3..dc9ef5acf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java @@ -16,19 +16,18 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.DefaultAddMissingIndividualFormModelPreprocessor; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * Generates the edit configuration for a default property form. @@ -355,7 +354,7 @@ public class DefaultAddMissingIndividualFormGenerator implements EditConfigurati private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) { //Here, retrieve model from - OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); + OntModel model = ModelAccess.on(session.getServletContext()).getOntModel(); //if object property if(EditConfigurationUtils.isObjectProperty(EditConfigurationUtils.getPredicateUri(vreq), vreq)){ Individual objectIndividual = EditConfigurationUtils.getObjectIndividual(vreq); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java index cd35a9f03..7812ed09d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; + import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -22,7 +24,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; @@ -31,6 +32,7 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.IndividualsViaObjectPropetyOptions; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation; import edu.cornell.mannlib.vitro.webapp.i18n.I18n; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery; @@ -468,7 +470,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) { //Here, retrieve model from - OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); + OntModel model = ModelAccess.on(session.getServletContext()).getOntModel(); //if object property if(EditConfigurationUtils.isObjectProperty(EditConfigurationUtils.getPredicateUri(vreq), vreq)){ Individual objectIndividual = EditConfigurationUtils.getObjectIndividual(vreq); @@ -499,7 +501,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene if(isSelectFromExisting(vreq)) { // set ProhibitedFromSearch object so picklist doesn't show // individuals from classes that should be hidden from list views - OntModel displayOntModel = ModelAccess.on(session.getServletContext()).getDisplayModel(); + OntModel displayOntModel = ModelAccess.on(session.getServletContext()).getOntModel(DISPLAY); ProhibitedFromSearch pfs = new ProhibitedFromSearch( DisplayVocabulary.SEARCH_INDEX_URI, displayOntModel); if( editConfig != null ) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java index caed9de4d..10caf6d02 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java @@ -36,7 +36,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; @@ -46,6 +45,7 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocesso import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessDataGetterN3; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessDataGetterN3Utils; import edu.cornell.mannlib.vitro.webapp.i18n.I18n; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetterUtils; import edu.cornell.mannlib.vitro.webapp.utils.menuManagement.MenuManagementDataUtils; @@ -219,7 +219,7 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen void prepare(VitroRequest vreq, EditConfigurationVTwo editConfig) { //setup the model selectors for query, write and display models on editConfig setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = ModelAccess.on(vreq).getJenaOntModel(); + OntModel queryModel = ModelAccess.on(vreq).getOntModel(); if (editConfig.isParamUpdate()) { editConfig.prepareForParamUpdate(queryModel); @@ -236,7 +236,7 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen if (editConfig.isParamUpdate()) { //setup the model selectors for query, write and display models on editConfig setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = ModelAccess.on(vreq).getJenaOntModel(); + OntModel queryModel = ModelAccess.on(vreq).getOntModel(); retrieveExistingDataGetterInfo(context, editConfig, queryModel); } @@ -639,7 +639,7 @@ private String getExistingIsSelfContainedTemplateQuery() { int maxMenuPosition = 0; Literal menuPosition = null; setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = ModelAccess.on(vreq).getJenaOntModel(); + OntModel queryModel = ModelAccess.on(vreq).getOntModel(); String maxMenuPositionQuery = getMaxMenuPositionQueryString(); QueryExecution qe = null; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java index 54c189705..f46d60022 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java @@ -17,12 +17,12 @@ import com.hp.hpl.jena.vocabulary.XSD; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * Generates the edit configuration for a default property form. @@ -240,7 +240,7 @@ public class NewIndividualFormGenerator implements EditConfigurationGenerator { private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) { //Here, retrieve model from - OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); + OntModel model = ModelAccess.on(session.getServletContext()).getOntModel(); //This form is always doing a non-update editConfiguration.prepareForNonUpdate( model ); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java index 648e1d768..9953a85c1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java @@ -15,19 +15,18 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.vocabulary.XSD; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * Generates the edit configuration for RDFS Label form. * @@ -299,7 +298,7 @@ public class RDFSLabelGenerator implements EditConfigurationGenerator { private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) { //Here, retrieve model from - OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); + OntModel model = ModelAccess.on(session.getServletContext()).getOntModel(); if( editConfiguration.isDataPropertyUpdate() ){ editConfiguration.prepareForDataPropUpdate(model, vreq.getWebappDaoFactory().getDataPropertyDao()); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/ModelSwitcher.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/ModelSwitcher.java index a334e7b1c..4240e8e96 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/ModelSwitcher.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/ModelSwitcher.java @@ -7,8 +7,10 @@ import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.SWITCH_TO_D import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_DISPLAY_MODEL_PARAM; import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_MODEL_PARAM; import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_TBOX_MODEL_PARAM; -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONFIGURATION; -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONTENT; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_TBOX; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -25,15 +27,15 @@ import com.hp.hpl.jena.rdf.model.ModelFactory; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.RequestModelAccessImpl; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; /** * Handle model switching, if requested for the editing framework. @@ -86,8 +88,8 @@ public class ModelSwitcher { // If they asked for the display model, give it to them. if (isParameterPresent(vreq, SWITCH_TO_DISPLAY_MODEL)) { - OntModel mainOntModel = ModelAccess.on(_context).getDisplayModel(); - OntModel tboxOntModel = ModelAccess.on(_context).getOntModel(ModelNames.DISPLAY_TBOX); + OntModel mainOntModel = ModelAccess.on(_context).getOntModel(DISPLAY); + OntModel tboxOntModel = ModelAccess.on(_context).getOntModel(DISPLAY_TBOX); setSpecialWriteModel(vreq, mainOntModel); vreq.setAttribute(VitroRequest.ID_FOR_ABOX_MODEL, VitroModelSource.ModelName.DISPLAY.toString()); @@ -120,8 +122,8 @@ public class ModelSwitcher { } private void setSpecialWriteModel(VitroRequest vreq, OntModel mainOntModel) { - if (mainOntModel != null) { - ModelAccess.on(vreq).setOntModel(ModelNames.FULL_UNION, mainOntModel); + if (mainOntModel != null) { + ((RequestModelAccessImpl) ModelAccess.on(vreq)).setSpecialWriteModel(mainOntModel); vreq.setAttribute(SPECIAL_WRITE_MODEL, mainOntModel); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java index daa09d735..9c4972da4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java @@ -22,8 +22,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.PageController; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.PageDao; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * This filter is intended to route requests to pages defined in the display model. * diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/RequestModelsPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/RequestModelsPrep.java index ce9d043a9..a4b5b0403 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/RequestModelsPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/RequestModelsPrep.java @@ -2,21 +2,14 @@ package edu.cornell.mannlib.vitro.webapp.filters; -import static edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelMakerID.CONTENT; - import java.io.IOException; import java.text.Collator; import java.util.Enumeration; -import java.util.List; import java.util.Locale; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Pattern; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -25,67 +18,24 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.jena.atlas.lib.Pair; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.query.Dataset; -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.FactoryID; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; -import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; -import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.HideFromDisplayByPolicyFilter; -import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; -import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl; -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerUtils; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringRDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringUtils; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** - * This sets up several objects in the Request scope for each incoming HTTP - * request. This is done in a Filter so that controllers and JSPs get the same - * setup. + * This used to set up a lot of request-based objects. Now, most of them are + * obtained through ModelAccess, which does not require setup here. However, it + * does require teardown. * - * This code configures the WebappDaoFactory for each request. + * This is done in a filter, so it applies to both Servlets and JSPs. */ public class RequestModelsPrep implements Filter { private final static Log log = LogFactory.getLog(RequestModelsPrep.class); - /** - * The filter will be applied to all incoming urls, this is a list of URI - * patterns to skip. These are matched against the requestURI sans query - * parameters, e.g. "/vitro/index.jsp" "/vitro/themes/enhanced/css/edit.css" - */ - private final static Pattern[] skipPatterns = { - Pattern.compile(".*\\.(gif|GIF|jpg|jpeg|png|PNG)$"), - Pattern.compile(".*\\.css$"), Pattern.compile(".*\\.js$"), - Pattern.compile("/.*/themes/.*/site_icons/.*"), - Pattern.compile("/.*/images/.*") }; - - private ServletContext ctx; - private ConfigurationProperties props; - private String defaultNamespace; - @Override public void init(FilterConfig fc) throws ServletException { - ctx = fc.getServletContext(); - props = ConfigurationProperties.getBean(ctx); - defaultNamespace = props.getProperty("Vitro.defaultNamespace"); + // Nothing to do } @Override @@ -101,251 +51,19 @@ public class RequestModelsPrep implements Filter { return; } - if (!thisRequestNeedsModels(req) || modelsAreAlreadySetUp(req)) { + try { + setCollator(new VitroRequest(req)); filterChain.doFilter(req, resp); - } else { - RDFService contentRdfService = RDFServiceUtils - .getRDFServiceFactory(ctx, WhichService.CONTENT) - .getShortTermRDFService(); - RDFService configurationRdfService = RDFServiceUtils - .getRDFServiceFactory(ctx, WhichService.CONFIGURATION) - .getShortTermRDFService(); - try { - setUpTheRequestModels(contentRdfService, configurationRdfService, req); - filterChain.doFilter(req, resp); - tearDownTheRequestModels(req); - } finally { - contentRdfService.close(); - configurationRdfService.close(); + } finally { + if (ModelAccess.isPresent(req)) { + ModelAccess.on(req).close(); } } } - private boolean thisRequestNeedsModels(HttpServletRequest req) { - String requestURI = req.getRequestURI(); - for (Pattern skipPattern : skipPatterns) { - if (skipPattern.matcher(requestURI).matches()) { - log.debug("request matched skipPattern '" + skipPattern - + "', skipping RequestModelsPrep"); - return false; - } - } - return true; - } - - private boolean modelsAreAlreadySetUp(HttpServletRequest req) { - String attributeName = RequestModelsPrep.class.getName() + "-setup"; - if (req.getAttribute(attributeName) != null) { - return true; - } else { - req.setAttribute(attributeName, Boolean.TRUE); - return false; - } - } - - private void setUpTheRequestModels(RDFService contentRdfService, RDFService configurationRdfService, - HttpServletRequest req) { - VitroRequest vreq = new VitroRequest(req); - - setRdfServicesAndDatasets(contentRdfService, vreq); - - setRawModels(contentRdfService, configurationRdfService, vreq); - - RDFService rdfService = vreq.getRDFService(); - - // We need access to some language-neutral items - either because we - // need to see all contents regardless of language, or because we need - // to see the blank nodes that are removed during language filtering. - vreq.setLanguageNeutralUnionFullModel(ModelAccess.on(vreq).getOntModel( - ModelNames.FULL_UNION)); - vreq.setLanguageNeutralWebappDaoFactory(new WebappDaoFactorySDB( - rdfService, createLanguageNeutralOntModelSelector(vreq), - createWadfConfig(vreq))); - - wrapModelsWithLanguageAwareness(vreq); - - setCollator(vreq); - - setWebappDaoFactories(vreq, rdfService); - } - - /** - * Set language-neutral and language-aware versions of the RdfService and - * Dataset. - */ - private void setRdfServicesAndDatasets(RDFService rawRdfService, - VitroRequest vreq) { - vreq.setUnfilteredRDFService(rawRdfService); - vreq.setUnfilteredDataset(new RDFServiceDataset(rawRdfService)); - - RDFService rdfService = addLanguageAwareness(vreq, rawRdfService); - vreq.setRDFService(rdfService); - - Dataset dataset = new RDFServiceDataset(rdfService); - vreq.setDataset(dataset); - } - - private void setRawModels(RDFService contentRdfService, RDFService configurationRdfService, VitroRequest vreq) { - ModelAccess models = ModelAccess.on(vreq); - - /** - * KLUGE -- VIVO-843 - * - * We happen to know that the short-term configuration models are the - * same as the long-term ones. But if we wrap them in OntModels again, - * we will lose the everytime sub-models. So for now, just skip that. - */ -// ModelMaker configMM = ModelMakerUtils.getShortTermModelMaker(ctx, -// configurationRdfService, WhichService.CONFIGURATION); -// models.setModelMaker(CONFIGURATION, configMM); - - ModelMaker contentMM = ModelMakerUtils.getShortTermModelMaker(ctx, - contentRdfService, WhichService.CONTENT); - models.setModelMaker(CONTENT, contentMM); - - /* - * KLUGE - * - * The TBOX_ASSERTIONS in the context is wrapped by an OntModel with - * sub-models (file-graph models). If we wrap a new OntModel around it, - * we will lose those sub-models, so use the OntModel from the context. - * - * Do we need to do the same with TBOX_INFERENCES and TBOX_UNION? Maybe - * not. - * - * See also the Kluge in ModelAccess. - */ - useModelFromContext(vreq, ModelNames.TBOX_ASSERTIONS); - useModelFromContext(vreq, ModelNames.TBOX_INFERENCES); - useModelFromContext(vreq, ModelNames.TBOX_UNION); - } - - private void useModelFromContext(VitroRequest vreq, String modelId) { - OntModel contextModel = ModelAccess.on(ctx).getOntModel(modelId); - ModelAccess.on(vreq).setOntModel(modelId, contextModel); - } - - /** - * Create an OntModelSelector that will hold the un-language-filtered - * models. - */ - private OntModelSelector createLanguageNeutralOntModelSelector( - VitroRequest vreq) { - OntModelSelectorImpl oms = new OntModelSelectorImpl(); - oms.setABoxModel(ModelAccess.on(vreq).getOntModel(ModelNames.ABOX_UNION)); - oms.setTBoxModel(ModelAccess.on(vreq).getOntModel(ModelNames.TBOX_UNION)); - oms.setFullModel(ModelAccess.on(vreq).getOntModel(ModelNames.FULL_UNION)); - oms.setApplicationMetadataModel(ModelAccess.on(vreq).getOntModel( - ModelNames.APPLICATION_METADATA)); - oms.setDisplayModel(ModelAccess.on(vreq).getOntModel(ModelNames.DISPLAY)); - oms.setUserAccountsModel(ModelAccess.on(vreq).getOntModel( - ModelNames.USER_ACCOUNTS)); - return oms; - } - - private void wrapModelsWithLanguageAwareness(VitroRequest vreq) { - wrapModelWithLanguageAwareness(vreq, ModelNames.DISPLAY); - wrapModelWithLanguageAwareness(vreq, ModelNames.APPLICATION_METADATA); - wrapModelWithLanguageAwareness(vreq, ModelNames.TBOX_ASSERTIONS); - wrapModelWithLanguageAwareness(vreq, ModelNames.TBOX_UNION); - wrapModelWithLanguageAwareness(vreq, ModelNames.FULL_UNION); - wrapModelWithLanguageAwareness(vreq, ModelNames.FULL_ASSERTIONS); - } - - private void wrapModelWithLanguageAwareness(HttpServletRequest req, - String name) { - if (isLanguageAwarenessEnabled()) { - OntModel unaware = ModelAccess.on(req).getOntModel(name); - OntModel aware = LanguageFilteringUtils - .wrapOntModelInALanguageFilter(unaware, req); - ModelAccess.on(req).setOntModel(name, aware); - } - } - - private void setWebappDaoFactories(VitroRequest vreq, RDFService rdfService) { - WebappDaoFactoryConfig config = createWadfConfig(vreq); - - WebappDaoFactory unfilteredWadf = new WebappDaoFactorySDB(rdfService, - ModelAccess.on(vreq).getUnionOntModelSelector(), config); - ModelAccess.on(vreq).setWebappDaoFactory(FactoryID.UNFILTERED_UNION, - unfilteredWadf); - - WebappDaoFactory unfilteredAssertionsWadf = new WebappDaoFactorySDB( - rdfService, ModelAccess.on(vreq).getBaseOntModelSelector(), - config, SDBDatasetMode.ASSERTIONS_ONLY); - ModelAccess.on(vreq).setWebappDaoFactory(FactoryID.BASE, - unfilteredAssertionsWadf); - ModelAccess.on(vreq).setWebappDaoFactory(FactoryID.UNFILTERED_BASE, - unfilteredAssertionsWadf); - - WebappDaoFactory wadf = new WebappDaoFactorySDB(rdfService, ModelAccess - .on(vreq).getUnionOntModelSelector(), config); - - // Do model switching and replace the WebappDaoFactory with - // a different version if requested by parameters - WebappDaoFactory switchedWadf = new ModelSwitcher() - .checkForModelSwitching(vreq, wadf); - // Switch the language-neutral one also. - vreq.setLanguageNeutralWebappDaoFactory(new ModelSwitcher() - .checkForModelSwitching(vreq, - vreq.getLanguageNeutralWebappDaoFactory())); - - HideFromDisplayByPolicyFilter filter = new HideFromDisplayByPolicyFilter( - RequestIdentifiers.getIdBundleForRequest(vreq), - ServletPolicyList.getPolicies(ctx)); - WebappDaoFactoryFiltering filteredWadf = new WebappDaoFactoryFiltering( - switchedWadf, filter); - ModelAccess.on(vreq).setWebappDaoFactory(FactoryID.UNION, filteredWadf); - } - - private WebappDaoFactoryConfig createWadfConfig(HttpServletRequest req) { - List langs = getPreferredLanguages(req); - WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); - config.setDefaultNamespace(defaultNamespace); - config.setPreferredLanguages(langs); - config.setUnderlyingStoreReasoned(isStoreReasoned(req)); - config.setCustomListViewConfigFileMap(getCustomListViewConfigFileMap(req - .getSession().getServletContext())); - return config; - } - - /** - * This method is also used by VitroHttpServlet to retrieve the right - * Collator instance for picklist sorting - * - * @param req - * @return - */ - public static Enumeration getPreferredLocales(HttpServletRequest req) { - return req.getLocales(); - } - - private List getPreferredLanguages(HttpServletRequest req) { - log.debug("Accept-Language: " + req.getHeader("Accept-Language")); - return LanguageFilteringUtils - .localesToLanguages(getPreferredLocales(req)); - } - - /** - * Language awareness is disabled unless they explicitly enable it. - */ - private Boolean isLanguageAwarenessEnabled() { - return Boolean.valueOf(props.getProperty("RDFService.languageFilter", - "false")); - } - - private RDFService addLanguageAwareness(HttpServletRequest req, - RDFService rawRDFService) { - List langs = getPreferredLanguages(req); - if (isLanguageAwarenessEnabled()) { - return new LanguageFilteringRDFService(rawRDFService, langs); - } else { - return rawRDFService; - } - } - private void setCollator(VitroRequest vreq) { - Enumeration locales = getPreferredLocales(vreq); + @SuppressWarnings("unchecked") + Enumeration locales = vreq.getLocales(); while (locales.hasMoreElements()) { Locale locale = locales.nextElement(); Collator collator = Collator.getInstance(locale); @@ -357,28 +75,6 @@ public class RequestModelsPrep implements Filter { vreq.setCollator(Collator.getInstance()); } - private boolean isStoreReasoned(ServletRequest req) { - String isStoreReasoned = ConfigurationProperties.getBean(req) - .getProperty("VitroConnection.DataSource.isStoreReasoned", - "true"); - return ("true".equals(isStoreReasoned)); - } - - private Map>, String> getCustomListViewConfigFileMap( - ServletContext ctx) { - Map>, String> map = (Map>, String>) ctx - .getAttribute("customListViewConfigFileMap"); - if (map == null) { - map = new ConcurrentHashMap>, String>(); - ctx.setAttribute("customListViewConfigFileMap", map); - } - return map; - } - - private void tearDownTheRequestModels(HttpServletRequest req) { - ModelAccess.on(req).close(); - } - @Override public void destroy() { // Nothing to destroy diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java index c20b6ff3b..f618c9e24 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java @@ -21,8 +21,8 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import freemarker.cache.WebappTemplateLoader; import freemarker.template.Configuration; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/URLRewritingHttpServletResponse.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/URLRewritingHttpServletResponse.java index ab8dccffd..0f0d6ea61 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/URLRewritingHttpServletResponse.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/URLRewritingHttpServletResponse.java @@ -16,8 +16,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ContentModelMakerFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ContentModelMakerFactory.java deleted file mode 100644 index 3cbe0344f..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ContentModelMakerFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.modelaccess; - -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_ASSERTIONS; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_INFERENCES; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_UNION; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.APPLICATION_METADATA; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_INFERENCES; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_INFERENCES; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_UNION; -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONTENT; - -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.NamedDefaultModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.UnionModelsModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.UnionModelsModelMaker.UnionSpec; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; - -/** - * Common functionality among the Content-based ModelMakerFactorys - */ -public abstract class ContentModelMakerFactory implements ModelMakerFactory { - - /** - * These are the small content models that we want to keep in memory. - */ - protected static final String[] SMALL_CONTENT_MODELS = { - APPLICATION_METADATA, TBOX_ASSERTIONS, TBOX_INFERENCES }; - - - private static final UnionSpec[] CONTENT_UNIONS = new UnionSpec[] { - UnionSpec.base(ABOX_ASSERTIONS).plus(ABOX_INFERENCES) - .yields(ABOX_UNION), - UnionSpec.base(TBOX_ASSERTIONS).plus(TBOX_INFERENCES) - .yields(TBOX_UNION), - UnionSpec.base(ABOX_ASSERTIONS).plus(TBOX_ASSERTIONS) - .yields(FULL_ASSERTIONS), - UnionSpec.base(ABOX_INFERENCES).plus(TBOX_INFERENCES) - .yields(FULL_INFERENCES) }; - - private static final String CONTENT_DEFAULT_MODEL_NAME = FULL_UNION; - - /** - * These decorations are added to a Content ModelMaker, regardless of the - * source. - * - * Create the union models and full models. Use the default model as the - * full union. - */ - protected ModelMaker addContentDecorators(ModelMaker sourceMM) { - ModelMaker unions = new UnionModelsModelMaker(sourceMM, CONTENT_UNIONS); - return new NamedDefaultModelMaker(unions, CONTENT_DEFAULT_MODEL_NAME); - } - - @Override - public WhichService whichModelMaker() { - return CONTENT; - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ContextModelAccess.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ContextModelAccess.java new file mode 100644 index 000000000..b4525ea03 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ContextModelAccess.java @@ -0,0 +1,57 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; + +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +/** + * Data structures on the context have fewer options than those on a request. + * + * There is no Preferred Language or Policy restrictions if there is no + * "current user". + */ +public interface ContextModelAccess { + /** Get the RDFService for the CONTENT. */ + public RDFService getRDFService(); + + /** Get the RDFService for either CONTENT or CONFIGURATION models. */ + public RDFService getRDFService(WhichService which); + + /** Get the Dataset for the CONTENT models. */ + public Dataset getDataset(); + + /** Get the Dataset for either CONTENT or CONFIGURATION models. */ + public Dataset getDataset(WhichService which); + + /** Get the ModelMaker for the CONTENT models. */ + public ModelMaker getModelMaker(); + + /** Get the ModelMaker for either CONTENT or CONFIGURATION models. */ + public ModelMaker getModelMaker(WhichService which); + + /** Get the FULL_UNION OntModel. */ + public OntModel getOntModel(); + + /** Get an OntModel by name. */ + public OntModel getOntModel(String name); + + /** Get the ASSERTIONS_AND_INFERENCES OntModelSelector. */ + public OntModelSelector getOntModelSelector(); + + /** Get an OntModelSelector based on ASSERTIONS, INFERENCES, or both. */ + public OntModelSelector getOntModelSelector(ReasoningOption option); + + /** Get the ASSERTIONS_AND_INFERENCES WebappDaoFactory. */ + public WebappDaoFactory getWebappDaoFactory(); + + /** Get a WebappDaoFactory, based on ASSERTIONS, INFERENCES, or both. */ + public WebappDaoFactory getWebappDaoFactory(ReasoningOption option); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelAccess.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelAccess.java new file mode 100644 index 000000000..cb2697390 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelAccess.java @@ -0,0 +1,198 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.ContextModelAccessImpl; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.RequestModelAccessImpl; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.DataStructuresProvider; + +/** + * The root access point for the RDF data structures: RDFServices, Datasets, + * ModelMakers, OntModels, OntModelSelectors and WebappDaoFactories. + * + * Get a long-term data structure by accessing from the context. Get a + * short-term data structure by accessing from the request. + * + *
+ * ModelAccess.on(ctx).getRDFService(CONFIGURATION);
+ * ModelAccess.on(req).getOntModel(ModelNames.DISPLAY);
+ * 
+ * + * ------------------------------------ + * + * The elaborate structure of options enums allows us to specify method + * signatures like this on RequestModelAccess: + * + *
+ * getOntModelSelector(OntModelSelectorOption... options);
+ * 
+ * + * Which can be invoked in any of these ways: + * + *
+ * ModelAccess.on(req).getOntModelSelector();
+ * ModelAccess.on(req).getOntModelSelector(LANGUAGE_NEUTRAL);
+ * ModelAccess.on(req).getOntModelSelector(INFERENCES_ONLY);
+ * ModelAccess.on(req).getOntModelSelector(ASSERTIONS_ONLY, LANGUAGE_NEUTRAL);
+ * 
+ * + * The compiler insures that only appropriate options are specified. However, if + * conflicting options are supplied, it will only be caught at runtime. + */ +public class ModelAccess { + private static final Log log = LogFactory.getLog(ModelAccess.class); + + // ---------------------------------------------------------------------- + // The options enums. + // ---------------------------------------------------------------------- + + /* + * It may seem complicated, but it allows us to verify options at compile + * time, and to provide or omit them in any order in a method call. + */ + + public interface ModelAccessOption { + boolean isDefault(); + } + + public interface RdfServiceOption extends ModelAccessOption { + // Just a marker interface + } + + public interface DatasetOption extends ModelAccessOption { + // Just a marker interface + } + + public interface OntModelSelectorOption extends ModelAccessOption { + // Just a marker interface + } + + public interface WebappDaoFactoryOption extends ModelAccessOption { + // Just a marker interface + } + + @SuppressWarnings("hiding") + public enum LanguageOption implements RdfServiceOption, DatasetOption, + OntModelSelectorOption, WebappDaoFactoryOption { + LANGUAGE_NEUTRAL, LANGUAGE_AWARE; + @Override + public boolean isDefault() { + return this == LANGUAGE_AWARE; + } + } + + @SuppressWarnings("hiding") + public enum ReasoningOption implements OntModelSelectorOption, + WebappDaoFactoryOption { + ASSERTIONS_ONLY, INFERENCES_ONLY, ASSERTIONS_AND_INFERENCES; + @Override + public boolean isDefault() { + return this == ASSERTIONS_AND_INFERENCES; + } + } + + @SuppressWarnings("hiding") + public enum PolicyOption implements WebappDaoFactoryOption { + POLICY_NEUTRAL, POLICY_AWARE; + @Override + public boolean isDefault() { + return this == POLICY_AWARE; + } + + } + + @SuppressWarnings("hiding") + public enum WhichService implements RdfServiceOption, DatasetOption { + CONTENT, CONFIGURATION; + @Override + public boolean isDefault() { + return this == CONTENT; + } + + } + + /* + * This is the easiest way to specify an option: + * ModelAccess.LANGUAGE_NEUTRAL, instead of + * ModelAccess.LanguageOption.LANGUAGE_NEUTRAL + */ + public static final LanguageOption LANGUAGE_NEUTRAL = LanguageOption.LANGUAGE_NEUTRAL; + public static final LanguageOption LANGUAGE_AWARE = LanguageOption.LANGUAGE_AWARE; + public static final ReasoningOption ASSERTIONS_ONLY = ReasoningOption.ASSERTIONS_ONLY; + public static final ReasoningOption INFERENCES_ONLY = ReasoningOption.INFERENCES_ONLY; + public static final ReasoningOption ASSERTIONS_AND_INFERENCES = ReasoningOption.ASSERTIONS_AND_INFERENCES; + public static final PolicyOption POLICY_NEUTRAL = PolicyOption.POLICY_NEUTRAL; + public static final PolicyOption POLICY_AWARE = PolicyOption.POLICY_AWARE; + public static final WhichService CONTENT = WhichService.CONTENT; + public static final WhichService CONFIGURATION = WhichService.CONFIGURATION; + + // ---------------------------------------------------------------------- + // The factory + // ---------------------------------------------------------------------- + + private static volatile DataStructuresProvider dataStructuresProvider; + private static volatile ModelAccessFactory factory = new ModelAccessFactory(); + + /** These attributes should only be accessed through this class. */ + private static final String ATTRIBUTE_NAME = ModelAccess.class.getName(); + + public static void setDataStructuresProvider(DataStructuresProvider provider) { + if (dataStructuresProvider != null) { + log.warn("Assigning DataStructuresProvider " + provider + + ", but was already set to " + dataStructuresProvider); + } + dataStructuresProvider = provider; + } + + public static RequestModelAccess on(HttpServletRequest req) { + Object o = req.getAttribute(ATTRIBUTE_NAME); + if (o instanceof RequestModelAccess) { + return (RequestModelAccess) o; + } else { + RequestModelAccess access = factory.buildRequestModelAccess(req); + req.setAttribute(ATTRIBUTE_NAME, access); + return access; + } + } + + public static boolean isPresent(HttpServletRequest req) { + return (req.getAttribute(ATTRIBUTE_NAME) instanceof RequestModelAccess); + } + + public static ContextModelAccess on(ServletContext ctx) { + Object o = ctx.getAttribute(ATTRIBUTE_NAME); + if (o instanceof ContextModelAccess) { + return (ContextModelAccess) o; + } else { + ContextModelAccess access = factory.buildContextModelAccess(ctx); + ctx.setAttribute(ATTRIBUTE_NAME, access); + return access; + } + } + + // ---------------------------------------------------------------------- + // A factory to create the instances, so we can override in unit tests. + // ---------------------------------------------------------------------- + + public static class ModelAccessFactory { + public ContextModelAccess buildContextModelAccess(ServletContext ctx) { + return new ContextModelAccessImpl(ctx, dataStructuresProvider); + } + + /** + * Note that the RequestModelAccess must be closed when the request + * closes. + */ + public RequestModelAccess buildRequestModelAccess(HttpServletRequest req) { + return new RequestModelAccessImpl(req, + dataStructuresProvider + .getShortTermDataStructuresProvider(req)); + } + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelMakerFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelMakerFactory.java deleted file mode 100644 index 1156e23b6..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelMakerFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.modelaccess; - -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; - -/** - * Get model makers for long and short-term use. - */ -public interface ModelMakerFactory { - - /** - * Get a model maker that is suitable for long-term use. - */ - ModelMaker getModelMaker(RDFService longTermRdfService); - - /** - * Get a model maker that should not be left idle for long periods of time. - * - * Because it is based (at least in part) on a short-term RDFService, it - * should not be stored in the context or the session, but should be deleted - * at the end of the request. - */ - ModelMaker getShortTermModelMaker(RDFService shortTermRdfService); - - /** - * Is this factory configured to provide CONTENT models or CONFIGURATION models? - */ - WhichService whichModelMaker(); - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelMakerUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelMakerUtils.java deleted file mode 100644 index 4e5d7716c..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelMakerUtils.java +++ /dev/null @@ -1,104 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.modelaccess; - -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONFIGURATION; -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONTENT; - -import javax.servlet.ServletContext; - -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; - -/** - * Convenience methods for obtaining the ModelMakerFactories. - */ -public class ModelMakerUtils { - public static final String ATTRIBUTE_BASE = ModelMakerUtils.class.getName(); - - public static void setContentModelMakerFactory(ServletContext ctx, - ModelMakerFactory mmFactory) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } - if (mmFactory == null) { - throw new NullPointerException("mmFactory may not be null."); - } - if (mmFactory.whichModelMaker() != CONTENT) { - throw new IllegalArgumentException( - "mmFactory must be a CONTENT ModelMakerFactory"); - } - ctx.setAttribute(attributeName(CONTENT), mmFactory); - } - - public static void setConfigurationModelMakerFactory(ServletContext ctx, - ModelMakerFactory mmFactory) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } - if (mmFactory == null) { - throw new NullPointerException("mmFactory may not be null."); - } - if (mmFactory.whichModelMaker() != CONFIGURATION) { - throw new IllegalArgumentException( - "mmFactory must be a CONFIGURATION ModelMakerFactory"); - } - ctx.setAttribute(attributeName(CONFIGURATION), mmFactory); - } - - public static ModelMaker getModelMaker(ServletContext ctx, - WhichService which) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } - if (which == null) { - throw new NullPointerException("which may not be null."); - } - return getFactory(ctx, which).getModelMaker( - RDFServiceUtils.getRDFServiceFactory(ctx) - .getShortTermRDFService()); - } - - public static ModelMaker getShortTermModelMaker(ServletContext ctx, - RDFService shortTermRdfService, WhichService which) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } - if (shortTermRdfService == null) { - throw new NullPointerException( - "shortTermRdfService may not be null."); - } - if (which == null) { - throw new NullPointerException("which may not be null."); - } - - return getFactory(ctx, which).getShortTermModelMaker( - shortTermRdfService); - } - - private static ModelMakerFactory getFactory(ServletContext ctx, - WhichService which) { - Object attribute = ctx.getAttribute(attributeName(which)); - if (attribute instanceof ModelMakerFactory) { - return (ModelMakerFactory) attribute; - } else { - throw new IllegalStateException("Expected a ModelMakerFactory at '" - + attributeName(which) + "', but found " + attribute); - } - } - - private static String attributeName(WhichService which) { - return ATTRIBUTE_BASE + "-" + which; - } - - /** - * No need for an instance - all methods are static. - */ - private ModelMakerUtils() { - // Nothing to instantiate. - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelNames.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelNames.java index 677ac815a..2dbcb6459 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelNames.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelNames.java @@ -2,6 +2,10 @@ package edu.cornell.mannlib.vitro.webapp.modelaccess; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + /** * A central place to record the URIs of the models that we rely on. */ @@ -9,18 +13,44 @@ public class ModelNames { public static final String ABOX_ASSERTIONS = "http://vitro.mannlib.cornell.edu/default/vitro-kb-2"; public static final String ABOX_INFERENCES = "http://vitro.mannlib.cornell.edu/default/vitro-kb-inf"; public static final String ABOX_UNION = "vitro:aboxOntModel"; - + public static final String TBOX_ASSERTIONS = "http://vitro.mannlib.cornell.edu/default/asserted-tbox"; public static final String TBOX_INFERENCES = "http://vitro.mannlib.cornell.edu/default/inferred-tbox"; public static final String TBOX_UNION = "vitro:tboxOntModel"; - + public static final String FULL_ASSERTIONS = "vitro:baseOntModel"; public static final String FULL_INFERENCES = "vitro:inferenceOntModel"; public static final String FULL_UNION = "vitro:jenaOntModel"; - + public static final String APPLICATION_METADATA = "http://vitro.mannlib.cornell.edu/default/vitro-kb-applicationMetadata"; public static final String USER_ACCOUNTS = "http://vitro.mannlib.cornell.edu/default/vitro-kb-userAccounts"; public static final String DISPLAY = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata"; public static final String DISPLAY_TBOX = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadataTBOX"; public static final String DISPLAY_DISPLAY = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata-displayModel"; + + /** + * A map of the URIS, keyed by their short names, intended only for display + * purposes. + */ + public static final Map namesMap = populateNamesMap(); + + private static Map populateNamesMap() { + Map map = new HashMap<>(); + map.put("ABOX_ASSERTIONS", ABOX_ASSERTIONS); + map.put("ABOX_INFERENCES", ABOX_INFERENCES); + map.put("ABOX_UNION", ABOX_UNION); + map.put("TBOX_ASSERTIONS", TBOX_ASSERTIONS); + map.put("TBOX_INFERENCES", TBOX_INFERENCES); + map.put("TBOX_UNION", TBOX_UNION); + map.put("FULL_ASSERTIONS", FULL_ASSERTIONS); + map.put("FULL_INFERENCES", FULL_INFERENCES); + map.put("FULL_UNION", FULL_UNION); + map.put("APPLICATION_METADATA", APPLICATION_METADATA); + map.put("USER_ACCOUNTS", USER_ACCOUNTS); + map.put("DISPLAY", DISPLAY); + map.put("DISPLAY_TBOX", DISPLAY_TBOX); + map.put("DISPLAY_DISPLAY", DISPLAY_DISPLAY); + return Collections.unmodifiableMap(map); + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/RequestModelAccess.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/RequestModelAccess.java new file mode 100644 index 000000000..14e3eff3c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/RequestModelAccess.java @@ -0,0 +1,57 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Dataset; + +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.DatasetOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.OntModelSelectorOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.RdfServiceOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WebappDaoFactoryOption; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +/** + * Data structure on a request have additional options, depending on the + * identity and preferences of the user. + */ +public interface RequestModelAccess { + /** + * Get an RDFService: CONTENT or CONFIGURATION, Language-aware or not. + */ + RDFService getRDFService(RdfServiceOption... options); + + /** + * Get a Dataset: CONTENT or CONFIGURATION, Language-aware or not. + */ + Dataset getDataset(DatasetOption... options); + + /** + * Get the FULL_UNION OntModel: Language-aware or not. + */ + OntModel getOntModel(LanguageOption... options); + + /** + * Get an OntModel: Language-aware or not. + */ + OntModel getOntModel(String name, LanguageOption... options); + + /** + * Get an OntModelSelector: Language-aware or not, ASSERTIONS or INFERENCES or both. + */ + OntModelSelector getOntModelSelector(OntModelSelectorOption... options); + + /** + * Get a WebappDaoFactory: Filtered or not, Language-aware or not, + * ASSERTIONS or INFERENCES or both. + */ + WebappDaoFactory getWebappDaoFactory(WebappDaoFactoryOption... options); + + /** + * When finished, release any resources. + */ + void close(); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/AbstractModelMakerDecorator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/AbstractModelMakerDecorator.java index 8df8905ea..092ca328b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/AbstractModelMakerDecorator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/AbstractModelMakerDecorator.java @@ -21,6 +21,11 @@ public class AbstractModelMakerDecorator implements ModelMaker { } this.inner = inner; } + + @Override public String toString() { + return this.getClass().getSimpleName() + "[inner=" + + String.valueOf(inner) + "]"; + } @Override public Model createDefaultModel() { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/MemoryMappingModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/MemoryMappingModelMaker.java index 9f9da1907..359e7b276 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/MemoryMappingModelMaker.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/MemoryMappingModelMaker.java @@ -10,8 +10,7 @@ import com.hp.hpl.jena.rdf.model.ModelMaker; import com.hp.hpl.jena.rdf.model.ModelReader; import com.hp.hpl.jena.shared.AlreadyExistsException; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; -import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory; +import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.MemoryMappedModel; /** * Provides fast read access to small models, by creating a "mapped" model in @@ -34,11 +33,7 @@ public class MemoryMappingModelMaker extends AbstractModelMakerDecorator { } private Model createMemoryMapping(String name) { - Model externalModel = super.openModel(name); - Model memoryModel = VitroModelFactory.createModel(); - memoryModel.add(externalModel); - memoryModel.register(new ModelSynchronizer(externalModel, name)); - return memoryModel; + return new MemoryMappedModel(super.openModel(name), name); } private boolean isMapped(String name) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/ShadowingModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/ShadowingModelMaker.java deleted file mode 100644 index a755fb79a..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/ShadowingModelMaker.java +++ /dev/null @@ -1,140 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import com.hp.hpl.jena.graph.GraphMaker; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelMaker; -import com.hp.hpl.jena.rdf.model.ModelReader; -import com.hp.hpl.jena.util.iterator.ExtendedIterator; -import com.hp.hpl.jena.util.iterator.WrappedIterator; - -/** - * Allow some models in the "shadowing" ModelMaker to hide the corresponding - * models in the "shadowed" ModelMaker. - * - * Specify both ModelMakers, and the list of URIs for the shadowing models. - */ -public class ShadowingModelMaker extends AbstractModelMakerDecorator { - private final ModelMaker shadowing; - private final Set shadowUris; - - public ShadowingModelMaker(ModelMaker shadowed, ModelMaker shadowing, - String... shadowUris) { - super(shadowed); - this.shadowing = shadowing; - this.shadowUris = new HashSet<>(Arrays.asList(shadowUris)); - } - - private boolean isShadow(String name) { - return shadowUris.contains(name); - } - - @Override - public Model createDefaultModel() { - return super.createDefaultModel(); - } - - @Override - public Model createFreshModel() { - return super.createFreshModel(); - } - - @Override - public Model openModel(String name) { - if (isShadow(name)) { - return shadowing.openModel(name); - } else { - return super.openModel(name); - } - } - - @Override - public Model openModelIfPresent(String name) { - if (isShadow(name)) { - return shadowing.openModelIfPresent(name); - } else { - return super.openModelIfPresent(name); - } - } - - @Override - public Model getModel(String name) { - if (isShadow(name)) { - return shadowing.getModel(name); - } else { - return super.getModel(name); - } - } - - @Override - public Model getModel(String name, ModelReader loadIfAbsent) { - if (isShadow(name)) { - return shadowing.getModel(name, loadIfAbsent); - } else { - return super.getModel(name, loadIfAbsent); - } - } - - @Override - public Model createModel(String name, boolean strict) { - if (isShadow(name)) { - return shadowing.createModel(name, strict); - } else { - return super.createModel(name, strict); - } - } - - @Override - public Model createModel(String name) { - if (isShadow(name)) { - return shadowing.createModel(name); - } else { - return super.createModel(name); - } - } - - @Override - public Model openModel(String name, boolean strict) { - if (isShadow(name)) { - return shadowing.openModel(name, strict); - } else { - return super.openModel(name, strict); - } - } - - @Override - public void removeModel(String name) { - if (isShadow(name)) { - shadowing.removeModel(name); - } else { - super.removeModel(name); - } - } - - @Override - public boolean hasModel(String name) { - if (isShadow(name)) { - return shadowing.hasModel(name); - } else { - return super.hasModel(name); - } - } - - @Override - public void close() { - shadowing.close(); - super.close(); - } - - @Override - public ExtendedIterator listModels() { - Set allNames = super.listModels().toSet(); - allNames.addAll(shadowUris); - return WrappedIterator.create(allNames.iterator()); - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/UnionModelsModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/UnionModelsModelMaker.java deleted file mode 100644 index 0ad156a54..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/UnionModelsModelMaker.java +++ /dev/null @@ -1,249 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters; - -import java.util.HashMap; -import java.util.Map; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelMaker; -import com.hp.hpl.jena.rdf.model.ModelReader; -import com.hp.hpl.jena.shared.AlreadyExistsException; -import com.hp.hpl.jena.util.iterator.ExtendedIterator; - -import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory; - -/** - * This ModelMaker decorator creates one or more "union models" over the models - * provided to it by the inner ModelMaker. - * - * Each union model contains all of the triples of both its base model and its - * "plus" model. Any changes to the union model are delegated to the base model. - * If changes are desired in the "plus" model, it must be accessed directly. - * - * This can create surprises, since the union model will claim to have a given - * statement that is part of the plus model, but an attempt to delete that - * statement from the union model has no effect. - */ -public class UnionModelsModelMaker extends AbstractModelMakerDecorator { - private final Map unionModelsMap; - - /** - * Create it like this: - * - *
-	 * new UnionModelsModelMaker(inner,
-	 *     UnionSpec.base("baseUri").plus("plusUri").yields("unionUri"),
-	 *     ...);
-	 * 
- */ - public UnionModelsModelMaker(ModelMaker inner, UnionSpec... unionModelSpecs) { - super(inner); - - this.unionModelsMap = new HashMap<>(); - - for (UnionSpec spec : unionModelSpecs) { - String unionUri = spec.getUnionUri(); - if (unionModelsMap.containsKey(unionUri)) { - throw new IllegalArgumentException( - "Two UnionSpecs may not have the same union URI: " - + spec + ", " + unionModelsMap.get(unionUri)); - } - this.unionModelsMap.put(unionUri, spec); - } - - for (UnionSpec spec1 : unionModelsMap.values()) { - if (unionModelsMap.containsKey(spec1.getBaseUri()) - || unionModelsMap.containsKey(spec1.getPlusUri())) { - throw new IllegalArgumentException( - "A UnionSpec may not build on another UnionSpec: " - + spec1); - } - } - } - - private boolean hasUnionModel(String name) { - return unionModelsMap.containsKey(name); - } - - /** - * The union models use lazy initialization, so there is no overhead if the - * model is never requested. - */ - private Model getUnionModel(String name) { - UnionSpec spec = unionModelsMap.get(name); - synchronized (spec) { - if (spec.getUnionModel() == null) { - Model baseModel = super.openModel(spec.getBaseUri()); - Model plusModel = super.openModel(spec.getPlusUri()); - spec.setUnionModel(VitroModelFactory.createUnion(baseModel, - plusModel)); - } - } - return spec.getUnionModel(); - } - - // ---------------------------------------------------------------------- - // Overridden methods. - // ---------------------------------------------------------------------- - - @Override - public Model createModel(String name) { - return createModel(name, false); - } - - @Override - public Model createModel(String name, boolean strict) { - if (hasUnionModel(name)) { - if (strict) { - throw new AlreadyExistsException(name); - } else { - return getUnionModel(name); - } - } else { - return super.createModel(name, strict); - } - } - - @Override - public Model openModel(String name, boolean strict) { - if (hasUnionModel(name)) { - return getUnionModel(name); - } else { - return super.openModel(name, strict); - } - } - - @Override - public Model openModel(String name) { - if (hasUnionModel(name)) { - return getUnionModel(name); - } else { - return super.openModel(name); - } - } - - @Override - public Model openModelIfPresent(String name) { - if (hasUnionModel(name)) { - return getUnionModel(name); - } else { - return super.openModelIfPresent(name); - } - } - - @Override - public boolean hasModel(String name) { - if (hasUnionModel(name)) { - return true; - } else { - return super.hasModel(name); - } - } - - @Override - public ExtendedIterator listModels() { - return super.listModels().andThen(unionModelsMap - .keySet().iterator()); - } - - @Override - public void removeModel(String name) { - if (hasUnionModel(name)) { - unionModelsMap.remove(name); - } else { - super.removeModel(name); - } - } - - @Override - public Model getModel(String URL) { - if (hasUnionModel(URL)) { - return getUnionModel(URL); - } else { - return super.getModel(URL); - } - } - - @Override - public Model getModel(String URL, ModelReader loadIfAbsent) { - if (hasUnionModel(URL)) { - return getUnionModel(URL); - } else { - return super.getModel(URL, loadIfAbsent); - } - } - - // ---------------------------------------------------------------------- - // UnionSpec and builder classes. - // ---------------------------------------------------------------------- - - public static class UnionSpec { - public static UnionSpecBase base(String baseUri) { - return new UnionSpecBase(baseUri); - } - - private final String baseUri; - private final String plusUri; - private final String unionUri; - private Model unionModel; - - public UnionSpec(String baseUri, String plusUri, String unionUri) { - this.baseUri = baseUri; - this.plusUri = plusUri; - this.unionUri = unionUri; - } - - public Model getUnionModel() { - return unionModel; - } - - public void setUnionModel(Model unionModel) { - this.unionModel = unionModel; - } - - public String getBaseUri() { - return baseUri; - } - - public String getPlusUri() { - return plusUri; - } - - public String getUnionUri() { - return unionUri; - } - - @Override - public String toString() { - return "UnionSpec[baseUri=" + baseUri + ", plusUri=" + plusUri - + ", unionUri=" + unionUri + "]"; - } - } - - public static class UnionSpecBase { - private final String baseUri; - - UnionSpecBase(String baseUri) { - this.baseUri = baseUri; - } - - public UnionSpecPair plus(String plusUri) { - return new UnionSpecPair(baseUri, plusUri); - } - } - - public static class UnionSpecPair { - private final String baseUri; - private final String plusUri; - - public UnionSpecPair(String baseUri, String plusUri) { - this.baseUri = baseUri; - this.plusUri = plusUri; - } - - public UnionSpec yields(String unionUri) { - return new UnionSpec(baseUri, plusUri, unionUri); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/ContextModelAccessImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/ContextModelAccessImpl.java new file mode 100644 index 000000000..85b71fc53 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/ContextModelAccessImpl.java @@ -0,0 +1,279 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.impl; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.ASSERTIONS_AND_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.ASSERTIONS_ONLY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.INFERENCES_ONLY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_UNION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.APPLICATION_METADATA; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_UNION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.Map; + +import javax.servlet.ServletContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; + +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.DataStructuresProvider; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * The context-based model access is simpler than the request-based model + * access. + * + * There is no "current user", so there can be no preferred language or + * policy-based filtering. + * + * We are confident that each of these structures will be used at some point, so + * there is no need for lazy initialization. + */ +public class ContextModelAccessImpl implements ContextModelAccess { + private static final Log log = LogFactory + .getLog(ContextModelAccessImpl.class); + + private static final String VITRO_DEFAULT_NAMESPACE = "Vitro.defaultNamespace"; + + private final ConfigurationProperties props; + + private final DataStructuresProvider factory; + + private final Map rdfServiceMap; + private final Map datasetMap; + private final Map modelMakerMap; + private final OntModelCache ontModelCache; + private final Map omsMap; + private final Map wadfMap; + + /** + * Pull all of the items into maps, instead of fetching them from the + * factory on demand. We don't know that the factory wouldn't create fresh + * ones. + * + * The exception is the OntModels, for two reasons: first, because the + * OntModelCache assures us that it won't create fresh copies, and second + * because we may not know the names of all of the models that will be + * requested. + */ + public ContextModelAccessImpl(ServletContext ctx, + DataStructuresProvider factory) { + this.props = ConfigurationProperties.getBean(ctx); + this.factory = factory; + + this.ontModelCache = factory.getOntModelCache(); + this.rdfServiceMap = populateRdfServiceMap(); + this.datasetMap = populateDatasetMap(); + this.modelMakerMap = populateModelMakerMap(); + this.omsMap = populateOmsMap(); + this.wadfMap = populateWadfMap(); + } + + @Override + public String toString() { + return "ContextModelAccessImpl[" + ToString.hashHex(this) + + ", factory=" + factory + "]"; + } + + // ---------------------------------------------------------------------- + // RDFServices + // ---------------------------------------------------------------------- + + private Map populateRdfServiceMap() { + Map map = new EnumMap<>(WhichService.class); + map.put(CONTENT, factory.getRDFService(CONTENT)); + map.put(CONFIGURATION, factory.getRDFService(CONFIGURATION)); + log.debug("RdfServiceMap: " + map); + return Collections.unmodifiableMap(map); + } + + @Override + public RDFService getRDFService() { + return getRDFService(CONTENT); + } + + @Override + public RDFService getRDFService(WhichService which) { + RDFService rdfService = rdfServiceMap.get(which); + log.debug("getRDFService " + which + ": " + rdfService); + return rdfService; + } + + // ---------------------------------------------------------------------- + // Datasets + // ---------------------------------------------------------------------- + + private Map populateDatasetMap() { + Map map = new EnumMap<>(WhichService.class); + map.put(CONTENT, factory.getDataset(CONTENT)); + map.put(CONFIGURATION, factory.getDataset(CONFIGURATION)); + log.debug("DatasetMap: " + map); + return Collections.unmodifiableMap(map); + } + + @Override + public Dataset getDataset() { + return getDataset(CONTENT); + } + + @Override + public Dataset getDataset(WhichService which) { + Dataset dataset = datasetMap.get(which); + log.debug("getDataset " + which + ": " + dataset); + return dataset; + } + + // ---------------------------------------------------------------------- + // ModelMakers + // ---------------------------------------------------------------------- + + private Map populateModelMakerMap() { + Map map = new EnumMap<>(WhichService.class); + map.put(CONTENT, factory.getModelMaker(CONTENT)); + map.put(CONFIGURATION, factory.getModelMaker(CONFIGURATION)); + log.debug("ModelMakerMap: " + map); + return Collections.unmodifiableMap(map); + } + + @Override + public ModelMaker getModelMaker() { + return getModelMaker(CONTENT); + } + + @Override + public ModelMaker getModelMaker(WhichService which) { + ModelMaker modelMaker = modelMakerMap.get(which); + log.debug("getModelMaker " + which + ": " + modelMaker); + return modelMaker; + } + + // ---------------------------------------------------------------------- + // OntModels + // ---------------------------------------------------------------------- + + @Override + public OntModel getOntModel() { + return getOntModel(FULL_UNION); + } + + @Override + public OntModel getOntModel(String name) { + OntModel ontModel = ontModelCache.getOntModel(name); + log.debug("getOntModel: " + ontModel); + return ontModel; + } + + // ---------------------------------------------------------------------- + // OntModelSelectors + // ---------------------------------------------------------------------- + + private Map populateOmsMap() { + Map map = new EnumMap<>( + ReasoningOption.class); + map.put(ASSERTIONS_ONLY, + createOntModelSelector(ABOX_ASSERTIONS, TBOX_ASSERTIONS, + FULL_ASSERTIONS)); + map.put(INFERENCES_ONLY, + createOntModelSelector(ABOX_INFERENCES, TBOX_INFERENCES, + FULL_INFERENCES)); + map.put(ASSERTIONS_AND_INFERENCES, + createOntModelSelector(ABOX_UNION, TBOX_UNION, FULL_UNION)); + log.debug("OntModelSelectorMap: " + map); + return Collections.unmodifiableMap(map); + } + + private OntModelSelector createOntModelSelector(String aboxName, + String tboxName, String fullName) { + OntModelSelectorImpl oms = new OntModelSelectorImpl(); + oms.setABoxModel(getOntModel(aboxName)); + oms.setTBoxModel(getOntModel(tboxName)); + oms.setFullModel(getOntModel(fullName)); + oms.setApplicationMetadataModel(getOntModel(APPLICATION_METADATA)); + oms.setDisplayModel(getOntModel(DISPLAY)); + oms.setUserAccountsModel(getOntModel(USER_ACCOUNTS)); + return oms; + } + + @Override + public OntModelSelector getOntModelSelector() { + return getOntModelSelector(ASSERTIONS_AND_INFERENCES); + } + + @Override + public OntModelSelector getOntModelSelector(ReasoningOption option) { + OntModelSelector ontModelSelector = omsMap.get(option); + log.debug("getOntModelSelector: " + ontModelSelector); + return ontModelSelector; + } + + // ---------------------------------------------------------------------- + // WebappDaoFactories + // ---------------------------------------------------------------------- + + private Map populateWadfMap() { + WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); + config.setDefaultNamespace(getDefaultNamespace()); + + RDFService rdfService = getRDFService(CONTENT); + + Map map = new EnumMap<>( + ReasoningOption.class); + map.put(ASSERTIONS_ONLY, new WebappDaoFactorySDB(rdfService, + getOntModelSelector(ASSERTIONS_ONLY), config, + SDBDatasetMode.ASSERTIONS_ONLY)); + map.put(INFERENCES_ONLY, new WebappDaoFactorySDB(rdfService, + getOntModelSelector(INFERENCES_ONLY), config, + SDBDatasetMode.INFERENCES_ONLY)); + map.put(ASSERTIONS_AND_INFERENCES, new WebappDaoFactorySDB(rdfService, + getOntModelSelector(ASSERTIONS_AND_INFERENCES), config, + SDBDatasetMode.ASSERTIONS_AND_INFERENCES)); + log.debug("WebappdaoFactoryMap: " + map); + return Collections.unmodifiableMap(map); + } + + private String getDefaultNamespace() { + return props.getProperty(VITRO_DEFAULT_NAMESPACE); + } + + @Override + public WebappDaoFactory getWebappDaoFactory() { + return getWebappDaoFactory(ASSERTIONS_AND_INFERENCES); + } + + @Override + public WebappDaoFactory getWebappDaoFactory(ReasoningOption option) { + WebappDaoFactory wadf = wadfMap.get(option); + log.debug("getWebappDaoFactory: " + wadf); + return wadf; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/RequestModelAccessImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/RequestModelAccessImpl.java new file mode 100644 index 000000000..c6b9277bd --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/RequestModelAccessImpl.java @@ -0,0 +1,342 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.impl; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption.LANGUAGE_AWARE; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption.LANGUAGE_NEUTRAL; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.PolicyOption.POLICY_AWARE; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.APPLICATION_METADATA; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Dataset; + +import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; +import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.HideFromDisplayByPolicyFilter; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; +import edu.cornell.mannlib.vitro.webapp.filters.ModelSwitcher; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.DatasetOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.OntModelSelectorOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.RdfServiceOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WebappDaoFactoryOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.modelaccess.RequestModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys.DatasetKey; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys.OntModelKey; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys.OntModelSelectorKey; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys.RDFServiceKey; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys.WebappDaoFactoryKey; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringRDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringUtils; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.ShortTermDataStructuresProvider; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * For each category of data structure, the pattern is the same: + * + * Build a key from the supplied options. If the cache contains a structure with + * that key, return it. + * + * Otherwise, create the requested structure, often from a simplified version. + * For example, if the request was for a LANGUAGE_AWARE RDFService, get the + * LANGUAGE_NEUTRAL RDFService and wrap it with langauge awareness. + * + * This second step is a recursive call, so we check again to see if the cache + * contains the new requested structure based on a modified key. If it does + * contain the structure, use it. Otherwise, create it. Eventually, we reach a + * request for the simplest structure, which we fetch from the + * ShortTermDataStructuresFactory. + * + * If the request includes language-awareness, the structure can be created from + * the language-neutral version. If language-awareness is disabled, the + * language-neutral structure will be cached under two different keys. + * + * ---------------------------------------- + * + * There are two hacks here to support model switching: one in the OntModels and + * one in the WebappDaoFactories. These are hacks for several reasons, not the + * least of which is that the model switching will not be available on + * WebappDaoFactories based on ASSERTIONS_ONLY or INFERENCES_ONLY, and similarly + * for the OntModel. + */ +public class RequestModelAccessImpl implements RequestModelAccess { + private static final Log log = LogFactory + .getLog(RequestModelAccessImpl.class); + + private final HttpServletRequest req; + private final ServletContext ctx; + private final ConfigurationProperties props; + private final ShortTermDataStructuresProvider provider; + + public RequestModelAccessImpl(HttpServletRequest req, + ShortTermDataStructuresProvider provider) { + this.req = req; + this.ctx = req.getSession().getServletContext(); + this.props = ConfigurationProperties.getBean(req); + this.provider = provider; + } + + /** + * Language awareness is disabled unless they explicitly enable it. + */ + private Boolean isLanguageAwarenessEnabled() { + return Boolean.valueOf(props.getProperty("RDFService.languageFilter", + "false")); + } + + private List getPreferredLanguages() { + return LanguageFilteringUtils.localesToLanguages(req.getLocales()); + } + + @Override + public void close() { + this.provider.close(); + } + + @Override + public String toString() { + return "RequestModelAccessImpl[" + ToString.hashHex(this) + ", req=" + + ToString.hashHex(req) + ", provider=" + provider + "]"; + } + + // ---------------------------------------------------------------------- + // RDFServices + // ---------------------------------------------------------------------- + + private final Map rdfServiceMap = new HashMap<>(); + + @Override + public RDFService getRDFService(RdfServiceOption... options) { + return getRDFService(new RDFServiceKey(options)); + } + + private RDFService getRDFService(RDFServiceKey key) { + if (!rdfServiceMap.containsKey(key)) { + RDFService rdfService = createRDFService(key); + log.debug("Creating: " + key + ", request=" + req.hashCode() + + ", " + rdfService); + rdfServiceMap.put(key, rdfService); + } + RDFService rdfService = rdfServiceMap.get(key); + log.debug("getRDFService, " + key + ": " + rdfService); + return rdfService; + } + + private RDFService createRDFService(RDFServiceKey key) { + if (key.getLanguageOption() == LANGUAGE_AWARE) { + return addLanguageAwareness(getRDFService(LANGUAGE_NEUTRAL)); + } else { + return provider.getRDFService(key.getWhichService()); + } + } + + private RDFService addLanguageAwareness(RDFService unaware) { + if (isLanguageAwarenessEnabled()) { + return new LanguageFilteringRDFService(unaware, + getPreferredLanguages()); + } else { + return unaware; + } + } + + // ---------------------------------------------------------------------- + // Datasets + // ---------------------------------------------------------------------- + + private final Map datasetMap = new HashMap<>(); + + @Override + public Dataset getDataset(DatasetOption... options) { + return getDataset(new DatasetKey(options)); + } + + private Dataset getDataset(DatasetKey key) { + if (!datasetMap.containsKey(key)) { + Dataset dataset = createDataset(key); + log.debug("Creating: " + key + ", request=" + req.hashCode() + + ", " + dataset); + datasetMap.put(key, dataset); + } + Dataset dataset = datasetMap.get(key); + log.debug("getDataset, " + key + ": " + dataset); + return dataset; + } + + private Dataset createDataset(DatasetKey key) { + return new RDFServiceDataset(getRDFService(key.rdfServiceKey())); + } + + // ---------------------------------------------------------------------- + // OntModels + // ---------------------------------------------------------------------- + + private final Map ontModelMap = new HashMap<>(); + + @Override + public OntModel getOntModel(LanguageOption... options) { + return getOntModel(ModelNames.FULL_UNION, options); + } + + @Override + public OntModel getOntModel(String name, LanguageOption... options) { + return getOntModel(new OntModelKey(name, options)); + } + + private OntModel getOntModel(OntModelKey key) { + if (!ontModelMap.containsKey(key)) { + OntModel ontModel = createOntModel(key); + log.debug("Creating: " + key + ", request=" + req.hashCode() + + ", " + ontModel); + ontModelMap.put(key, ontModel); + } + OntModel ontModel = ontModelMap.get(key); + log.debug("getOntModel, " + key + ": " + ontModel); + return ontModel; + } + + private OntModel createOntModel(OntModelKey key) { + if (key.getLanguageOption() == LANGUAGE_AWARE) { + return addLanguageAwareness(getOntModel(key.getName(), + LANGUAGE_NEUTRAL)); + } else { + return provider.getOntModelCache().getOntModel(key.getName()); + } + } + + private OntModel addLanguageAwareness(OntModel unaware) { + if (isLanguageAwarenessEnabled()) { + return LanguageFilteringUtils.wrapOntModelInALanguageFilter( + unaware, req); + } else { + return unaware; + } + } + + /** + * TODO Hack for model switching. + */ + public void setSpecialWriteModel(OntModel mainOntModel) { + ontModelMap.put(new OntModelKey(ModelNames.FULL_UNION), mainOntModel); + } + + // ---------------------------------------------------------------------- + // OntModelSelectors + // ---------------------------------------------------------------------- + + private final Map ontModelSelectorMap = new HashMap<>(); + + @Override + public OntModelSelector getOntModelSelector( + OntModelSelectorOption... options) { + return getOntModelSelector(new OntModelSelectorKey(options)); + } + + private OntModelSelector getOntModelSelector(OntModelSelectorKey key) { + if (!ontModelSelectorMap.containsKey(key)) { + OntModelSelector oms = createOntModelSelector(key); + log.debug("Creating: " + key + ", request=" + req.hashCode() + + ", " + oms); + ontModelSelectorMap.put(key, oms); + } + OntModelSelector ontModelSelector = ontModelSelectorMap.get(key); + log.debug("getOntModelSelector, " + key + ": " + ontModelSelector); + return ontModelSelector; + } + + private OntModelSelector createOntModelSelector(OntModelSelectorKey key) { + OntModelSelectorImpl oms = new OntModelSelectorImpl(); + + oms.setABoxModel(getOntModel(key.aboxKey())); + oms.setTBoxModel(getOntModel(key.tboxKey())); + oms.setFullModel(getOntModel(key.fullKey())); + + oms.setApplicationMetadataModel(getOntModel(key + .ontModelKey(APPLICATION_METADATA))); + oms.setDisplayModel(getOntModel(key.ontModelKey(DISPLAY))); + oms.setUserAccountsModel(getOntModel(key.ontModelKey(USER_ACCOUNTS))); + + return oms; + } + + // ---------------------------------------------------------------------- + // WebappDaoFactories + // ---------------------------------------------------------------------- + + private final Map wadfMap = new HashMap<>(); + + @Override + public WebappDaoFactory getWebappDaoFactory( + WebappDaoFactoryOption... options) { + return getWebappDaoFactory(new WebappDaoFactoryKey(options)); + } + + private WebappDaoFactory getWebappDaoFactory(WebappDaoFactoryKey key) { + if (!wadfMap.containsKey(key)) { + WebappDaoFactory wadf = createWebappDaoFactory(key); + log.debug("Creating: " + key + ", request=" + req.hashCode() + + ", " + wadf); + wadfMap.put(key, wadf); + } + WebappDaoFactory wadf = wadfMap.get(key); + log.debug("getWebappDaoFactory, " + key + ": " + wadf); + return wadf; + } + + private WebappDaoFactory createWebappDaoFactory(WebappDaoFactoryKey key) { + if (key.getPolicyOption() == POLICY_AWARE) { + return addPolicyAwareness(getWebappDaoFactory(key.policyNeutral())); + } + + RDFService rdfService = getRDFService(key.rdfServiceKey()); + OntModelSelector ontModelSelector = getOntModelSelector(key + .ontModelSelectorKey()); + WebappDaoFactoryConfig config = provider.getWebappDaoFactoryConfig(); + + switch (key.getReasoningOption()) { + case ASSERTIONS_ONLY: + return new WebappDaoFactorySDB(rdfService, ontModelSelector, + config, SDBDatasetMode.ASSERTIONS_ONLY); + case INFERENCES_ONLY: + return new WebappDaoFactorySDB(rdfService, ontModelSelector, + config, SDBDatasetMode.INFERENCES_ONLY); + default: // ASSERTIONS_AND_INFERENCES + // TODO Do model switching and replace the WebappDaoFactory with + // a different version if requested by parameters + WebappDaoFactory unswitched = new WebappDaoFactorySDB(rdfService, + ontModelSelector, config); + return new ModelSwitcher().checkForModelSwitching(new VitroRequest( + req), unswitched); + } + } + + private WebappDaoFactory addPolicyAwareness(WebappDaoFactory unaware) { + HideFromDisplayByPolicyFilter filter = new HideFromDisplayByPolicyFilter( + RequestIdentifiers.getIdBundleForRequest(req), + ServletPolicyList.getPolicies(ctx)); + return new WebappDaoFactoryFiltering(unaware, filter); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/DatasetKey.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/DatasetKey.java new file mode 100644 index 000000000..5609c38ff --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/DatasetKey.java @@ -0,0 +1,35 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.DatasetOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; + +/** + * An immutable key for storing Dataset objects in the ModelAccess maps. + */ +public final class DatasetKey extends ModelAccessKey { + public DatasetKey(DatasetOption... options) { + super(findWhichService(options), findLanguageOption(options)); + } + + @Override + public WhichService getWhichService() { + return super.getWhichService(); + } + + @Override + public LanguageOption getLanguageOption() { + return super.getLanguageOption(); + } + + /** + * How would we access an RDFService that is the basis for the Dataset + * accessed by this key? + */ + public RDFServiceKey rdfServiceKey() { + return new RDFServiceKey(getWhichService(), getLanguageOption()); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/LanguageOptionKey.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/LanguageOptionKey.java new file mode 100644 index 000000000..6cac9d902 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/LanguageOptionKey.java @@ -0,0 +1,21 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; + +/** + * An immutable key that distills a list of LanguageOptions into a single + * result. + */ +public final class LanguageOptionKey extends ModelAccessKey { + public LanguageOptionKey(LanguageOption... options) { + super(options); + } + + @Override + public LanguageOption getLanguageOption() { + return super.getLanguageOption(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/ModelAccessKey.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/ModelAccessKey.java new file mode 100644 index 000000000..42a5ae40d --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/ModelAccessKey.java @@ -0,0 +1,159 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ModelAccessOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.PolicyOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; + +/** + * An immutable collection of options that can be used as a key in a hashmap. + * + * The class of the key is part of the hash, so a OntModelKey and a + * RDFServiceKey can both be used in the same map without conflict. + */ +public abstract class ModelAccessKey { + + // ---------------------------------------------------------------------- + // Static methods + // ---------------------------------------------------------------------- + + protected static WhichService findWhichService(ModelAccessOption... options) { + return findWhichService(Arrays.asList(options)); + } + + protected static WhichService findWhichService( + Iterable options) { + return findOption(options, WhichService.CONTENT, WhichService.class); + } + + protected static ReasoningOption findReasoningOption( + ModelAccessOption... options) { + return findReasoningOption(Arrays.asList(options)); + } + + protected static ReasoningOption findReasoningOption( + Iterable options) { + return findOption(options, ReasoningOption.ASSERTIONS_AND_INFERENCES, + ReasoningOption.class); + } + + protected static LanguageOption findLanguageOption( + ModelAccessOption... options) { + return findLanguageOption(Arrays.asList(options)); + } + + protected static LanguageOption findLanguageOption( + Iterable options) { + return findOption(options, LanguageOption.LANGUAGE_AWARE, + LanguageOption.class); + } + + protected static PolicyOption findPolicyOption(ModelAccessOption[] options) { + return findPolicyOption(Arrays.asList(options)); + } + + protected static PolicyOption findPolicyOption( + Iterable options) { + return findOption(options, PolicyOption.POLICY_AWARE, + PolicyOption.class); + } + + /** + * Search through the options for values from the specified class. If none + * are found, use the default value. + * + * Redundant options are silently accepted, but conflicting options will + * throw an exception. + */ + private static T findOption(Iterable options, + T defaultValue, Class clazz) { + T found = null; + for (ModelAccessOption option : options) { + if (found == option) { + continue; + } + if (!clazz.isInstance(option)) { + continue; + } + if (found == null) { + found = clazz.cast(option); + continue; + } + throw new IllegalArgumentException("Conflicting options: " + found + + " and " + option); + } + + if (found == null) { + return defaultValue; + } else { + return found; + } + } + + // ---------------------------------------------------------------------- + // The instance + // ---------------------------------------------------------------------- + + protected final List keyComponents; + private final int hashCode; + + protected ModelAccessKey(ModelAccessOption... options) { + this.keyComponents = Collections.unmodifiableList(new ArrayList<>( + Arrays.asList(options))); + this.hashCode = keyComponents.hashCode() ^ this.getClass().hashCode(); + } + + protected ReasoningOption getReasoningOption() { + return findReasoningOption(keyComponents); + } + + protected LanguageOption getLanguageOption() { + return findLanguageOption(keyComponents); + } + + protected WhichService getWhichService() { + return findWhichService(keyComponents); + } + + protected PolicyOption getPolicyOption() { + return findPolicyOption(keyComponents); + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null) { + return false; + } else if (getClass() != obj.getClass()) { + return false; + } + ModelAccessKey that = (ModelAccessKey) obj; + return this.keyComponents.equals(that.keyComponents); + } + + @Override + public String toString() { + List notDefaults = new ArrayList<>(); + for (ModelAccessOption option : keyComponents) { + if (!option.isDefault()) { + notDefaults.add(option); + } + } + return this.getClass().getSimpleName() + notDefaults; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/OntModelKey.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/OntModelKey.java new file mode 100644 index 000000000..bbb3263ee --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/OntModelKey.java @@ -0,0 +1,48 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * An immutable key for storing and retrieving OntModels. + * + * In addition to the usual options, it has a name, which adds to the + * uniqueness. + */ +public final class OntModelKey extends ModelAccessKey { + private final String name; + private final int hashCode; + + public OntModelKey(String name, LanguageOption... options) { + super(findLanguageOption(options)); + this.name = name; + this.hashCode = super.hashCode() ^ name.hashCode(); + } + + public String getName() { + return name; + } + + @Override + public LanguageOption getLanguageOption() { + return super.getLanguageOption(); + } + + @Override + public boolean equals(Object obj) { + return super.equals(obj) && ((OntModelKey) obj).name.equals(this.name); + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public String toString() { + return super.toString() + " " + ToString.modelName(name); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/OntModelSelectorKey.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/OntModelSelectorKey.java new file mode 100644 index 000000000..a790f4ee3 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/OntModelSelectorKey.java @@ -0,0 +1,77 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_UNION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_UNION; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.OntModelSelectorOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption; + +/** + * An immutable key for storing OntModelSelectors in the ModelAccess maps. + */ +public final class OntModelSelectorKey extends ModelAccessKey { + public OntModelSelectorKey(OntModelSelectorOption... options) { + super(findLanguageOption(options), findReasoningOption(options)); + } + + @Override + public LanguageOption getLanguageOption() { + return super.getLanguageOption(); + } + + @Override + public ReasoningOption getReasoningOption() { + return super.getReasoningOption(); + } + + public OntModelKey aboxKey() { + switch (getReasoningOption()) { + case ASSERTIONS_ONLY: + return new OntModelKey(ABOX_ASSERTIONS, getLanguageOption()); + case INFERENCES_ONLY: + return new OntModelKey(ABOX_INFERENCES, getLanguageOption()); + default: // ASSERTIONS_AND_INFERENCES + return new OntModelKey(ABOX_UNION, getLanguageOption()); + } + } + + public OntModelKey tboxKey() { + switch (getReasoningOption()) { + case ASSERTIONS_ONLY: + return new OntModelKey(TBOX_ASSERTIONS, getLanguageOption()); + case INFERENCES_ONLY: + return new OntModelKey(TBOX_INFERENCES, getLanguageOption()); + default: // ASSERTIONS_AND_INFERENCES + return new OntModelKey(TBOX_UNION, getLanguageOption()); + } + } + + public OntModelKey fullKey() { + switch (getReasoningOption()) { + case ASSERTIONS_ONLY: + return new OntModelKey(FULL_ASSERTIONS, getLanguageOption()); + case INFERENCES_ONLY: + return new OntModelKey(FULL_INFERENCES, getLanguageOption()); + default: // ASSERTIONS_AND_INFERENCES + return new OntModelKey(FULL_UNION, getLanguageOption()); + } + } + + /** + * Get appropriate keys for the DISPLAY, USER_ACCOUNTS, and + * APPLICATION_METADATA models. + */ + public OntModelKey ontModelKey(String name) { + return new OntModelKey(name, getLanguageOption()); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/RDFServiceKey.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/RDFServiceKey.java new file mode 100644 index 000000000..4507272b4 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/RDFServiceKey.java @@ -0,0 +1,27 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.RdfServiceOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; + +/** + * An immutable key for storing RDFService objects in the ModelAccess maps. + */ +public final class RDFServiceKey extends ModelAccessKey { + public RDFServiceKey(RdfServiceOption... options) { + super(findWhichService(options), findLanguageOption(options)); + } + + @Override + public WhichService getWhichService() { + return super.getWhichService(); + } + + @Override + public LanguageOption getLanguageOption() { + return super.getLanguageOption(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/WebappDaoFactoryKey.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/WebappDaoFactoryKey.java new file mode 100644 index 000000000..9efddf61b --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/keys/WebappDaoFactoryKey.java @@ -0,0 +1,48 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.PolicyOption.POLICY_NEUTRAL; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.PolicyOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WebappDaoFactoryOption; + +/** + * An immutable key for storing RDFService objects in the ModelAccess maps. + */ +public final class WebappDaoFactoryKey extends ModelAccessKey { + public WebappDaoFactoryKey(WebappDaoFactoryOption... options) { + super(findLanguageOption(options), findReasoningOption(options), + findPolicyOption(options)); + } + + @Override + public LanguageOption getLanguageOption() { + return super.getLanguageOption(); + } + + @Override + public ReasoningOption getReasoningOption() { + return super.getReasoningOption(); + } + + @Override + public PolicyOption getPolicyOption() { + return super.getPolicyOption(); + } + + public WebappDaoFactoryKey policyNeutral() { + return new WebappDaoFactoryKey(getLanguageOption(), + getReasoningOption(), POLICY_NEUTRAL); + } + + public RDFServiceKey rdfServiceKey() { + return new RDFServiceKey(getWhichService(), getLanguageOption()); + } + + public OntModelSelectorKey ontModelSelectorKey() { + return new OntModelSelectorKey(getLanguageOption(), + getReasoningOption()); + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/JoinedOntModelCache.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/JoinedOntModelCache.java new file mode 100644 index 000000000..3207196bf --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/JoinedOntModelCache.java @@ -0,0 +1,67 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels; + +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; + +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * Use two OntModelCaches as one. + * + * If both caches contain models with the same name, a warning will be written + * to the log, and the model from the primary cache will be used. + * + * Any new models will be created on the primary cache. + */ +public class JoinedOntModelCache implements OntModelCache { + private static final Log log = LogFactory.getLog(JoinedOntModelCache.class); + + private final OntModelCache primary; + private final OntModelCache secondary; + + public JoinedOntModelCache(OntModelCache primary, OntModelCache secondary) { + this.primary = primary; + this.secondary = secondary; + + Set duplicateNames = new HashSet<>(primary.getModelNames()); + duplicateNames.retainAll(secondary.getModelNames()); + if (!duplicateNames.isEmpty()) { + log.warn("These model names appear in both caches: " + + duplicateNames); + } + } + + @Override + public OntModel getOntModel(String name) { + if (primary.getModelNames().contains(name)) { + return primary.getOntModel(name); + } + if (secondary.getModelNames().contains(name)) { + return secondary.getOntModel(name); + } + return primary.getOntModel(name); + } + + @Override + public SortedSet getModelNames() { + SortedSet allNames = new TreeSet<>(primary.getModelNames()); + allNames.addAll(secondary.getModelNames()); + return allNames; + } + + @Override + public String toString() { + return "JoinedOntModelCache[" + ToString.hashHex(this) + ", primary=" + + primary + ", secondary=" + secondary + "]"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/MaskingOntModelCache.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/MaskingOntModelCache.java new file mode 100644 index 000000000..9ae5a5d1b --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/MaskingOntModelCache.java @@ -0,0 +1,77 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; + +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * The named models in the masking cache will be used in preference to a model + * of the same name in the base cache. + * + * If a named model doesn't exist in the masking cache, a warning is written to + * the log and the name will be ignored. + * + * New models are created in the base cache only. + */ +public class MaskingOntModelCache implements OntModelCache { + private static final Log log = LogFactory + .getLog(MaskingOntModelCache.class); + + private final OntModelCache baseCache; + private final OntModelCache maskingCache; + private final Set maskingNames; + + public MaskingOntModelCache(OntModelCache baseCache, + OntModelCache maskingCache, Collection maskingNames) { + this.baseCache = baseCache; + this.maskingCache = maskingCache; + this.maskingNames = new HashSet<>(maskingNames); + checkForMissingNamedModels(); + } + + private void checkForMissingNamedModels() { + Set missingModelNames = new HashSet<>(this.maskingNames); + missingModelNames.removeAll(maskingCache.getModelNames()); + if (!missingModelNames.isEmpty()) { + log.warn("Specifed models do not exist in the masking cache: " + + missingModelNames); + maskingNames.removeAll(missingModelNames); + } + } + + @Override + public OntModel getOntModel(String name) { + if (maskingNames.contains(name)) { + return maskingCache.getOntModel(name); + } else { + return baseCache.getOntModel(name); + } + } + + /** The list of names in the baseCache may have changed. */ + @Override + public SortedSet getModelNames() { + SortedSet allNames = new TreeSet<>(baseCache.getModelNames()); + allNames.addAll(maskingNames); + return allNames; + } + + @Override + public String toString() { + return "MaskingOntModelCache[" + ToString.hashHex(this) + + ", baseCache=" + baseCache + ", maskingCache=" + maskingCache + + ", maskingNames=" + maskingNames + "]"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/ModelMakerOntModelCache.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/ModelMakerOntModelCache.java new file mode 100644 index 000000000..94106433c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/ModelMakerOntModelCache.java @@ -0,0 +1,57 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels; + +import java.util.HashMap; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelMaker; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * When an OntModel is requested for the first time, get a model from the + * ModelMaker, wrap it, and cache it for subsequent requests. + */ +public class ModelMakerOntModelCache implements OntModelCache { + private final Map cache = new HashMap<>(); + private final ModelMaker mm; + + public ModelMakerOntModelCache(ModelMaker mm) { + this.mm = mm; + } + + @Override + public OntModel getOntModel(String name) { + synchronized (cache) { + if (cache.containsKey(name)) { + return cache.get(name); + } + return wrapAndCache(name); + } + } + + private OntModel wrapAndCache(String name) { + Model m = mm.getModel(name); + OntModel om = VitroModelFactory.createOntologyModel(m); + cache.put(name, om); + return om; + } + + @Override + public SortedSet getModelNames() { + return new TreeSet<>(mm.listModels().toList()); + } + + @Override + public String toString() { + return "ModelMakerOntModelCache[" + ToString.hashHex(this) + ", mm=" + mm + + "]"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/OntModelCache.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/OntModelCache.java new file mode 100644 index 000000000..865f07fd6 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/OntModelCache.java @@ -0,0 +1,26 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels; + +import java.util.SortedSet; + +import com.hp.hpl.jena.ontology.OntModel; + +/** + * A source for OntModels from the triple-store. The contract is this: + * + * If you ask by a name that is not in use, an OntModel will be created. + * + * If you ask by the same name twice, you get the same OntModel. + */ +public interface OntModelCache { + /** + * Get the model with this name (URI). If such a model does not exist, it will be created. + */ + OntModel getOntModel(String name); + + /** + * Get the names of all existing models. + */ + SortedSet getModelNames(); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/UnionModelsOntModelsCache.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/UnionModelsOntModelsCache.java new file mode 100644 index 000000000..2ce5af5cc --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ontmodels/UnionModelsOntModelsCache.java @@ -0,0 +1,181 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels; + +import java.util.HashMap; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import com.hp.hpl.jena.ontology.OntModel; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * Decorates an OntModelCache with some "virtual" OntModels, each of which is a + * union of two actual OntModels. + * + * For example, we might create a model called FULL_ASSERTIONS, that is the + * union of two models called ABOX_ASSERTIONS and TBOX_ASSERTIONS. + * + * The inner class UnionSpec holds the model names, and allows us to lazily + * create the union models. + */ +public class UnionModelsOntModelsCache implements OntModelCache { + private final OntModelCache inner; + private final Map unionModelsMap; + + /** + * Create it like this: + * + *
+	 * new UnionModelsOntModelsCache(inner,
+	 *     UnionSpec.base("baseUri").plus("plusUri").yields("unionUri"),
+	 *     ...);
+	 * 
+ */ + public UnionModelsOntModelsCache(OntModelCache inner, + UnionSpec... unionModelSpecs) { + this.inner = inner; + + this.unionModelsMap = new HashMap<>(); + + for (UnionSpec spec : unionModelSpecs) { + String unionUri = spec.getUnionUri(); + if (unionModelsMap.containsKey(unionUri)) { + throw new IllegalArgumentException( + "Two UnionSpecs may not have the same union URI: " + + spec + ", " + unionModelsMap.get(unionUri)); + } + this.unionModelsMap.put(unionUri, spec); + } + + for (UnionSpec spec : unionModelsMap.values()) { + if (unionModelsMap.containsKey(spec.getBaseUri()) + || unionModelsMap.containsKey(spec.getPlusUri())) { + throw new IllegalArgumentException( + "A UnionSpec may not build on another UnionSpec: " + + spec); + } + } + } + + private boolean hasUnionModel(String name) { + return unionModelsMap.containsKey(name); + } + + /** + * The union models use lazy initialization, so there is no overhead if the + * model is never requested. + */ + private OntModel getUnionModel(String name) { + UnionSpec spec = unionModelsMap.get(name); + synchronized (spec) { + if (spec.getUnionModel() == null) { + OntModel baseModel = inner.getOntModel(spec.getBaseUri()); + OntModel plusModel = inner.getOntModel(spec.getPlusUri()); + spec.setUnionModel(VitroModelFactory.createUnion(baseModel, + plusModel)); + } + } + return spec.getUnionModel(); + } + + @Override + public OntModel getOntModel(String name) { + if (hasUnionModel(name)) { + return getUnionModel(name); + } else { + return inner.getOntModel(name); + } + } + + @Override + public SortedSet getModelNames() { + SortedSet names = new TreeSet<>(inner.getModelNames()); + names.addAll(unionModelsMap.keySet()); + return names; + } + + @Override + public String toString() { + return "UnionModelsOntModelsCache[" + ToString.hashHex(this) + + ", inner=" + inner + ", unionModelsMap=" + unionModelsMap + + "]"; + } + + // ---------------------------------------------------------------------- + // UnionSpec and builder classes. + // ---------------------------------------------------------------------- + + public static class UnionSpec { + public static UnionSpecBase base(String baseUri) { + return new UnionSpecBase(baseUri); + } + + private final String baseUri; + private final String plusUri; + private final String unionUri; + private OntModel unionModel; + + public UnionSpec(String baseUri, String plusUri, String unionUri) { + this.baseUri = baseUri; + this.plusUri = plusUri; + this.unionUri = unionUri; + } + + public OntModel getUnionModel() { + return unionModel; + } + + public void setUnionModel(OntModel unionModel) { + this.unionModel = unionModel; + } + + public String getBaseUri() { + return baseUri; + } + + public String getPlusUri() { + return plusUri; + } + + public String getUnionUri() { + return unionUri; + } + + @Override + public String toString() { + return "UnionSpec[baseUri=" + baseUri + ", plusUri=" + plusUri + + ", unionUri=" + unionUri + "]"; + } + } + + public static class UnionSpecBase { + private final String baseUri; + + UnionSpecBase(String baseUri) { + this.baseUri = baseUri; + } + + public UnionSpecPair plus(String plusUri) { + return new UnionSpecPair(baseUri, plusUri); + } + } + + public static class UnionSpecPair { + private final String baseUri; + private final String plusUri; + + public UnionSpecPair(String baseUri, String plusUri) { + this.baseUri = baseUri; + this.plusUri = plusUri; + } + + public UnionSpec yields(String unionUri) { + return new UnionSpec(baseUri, plusUri, unionUri); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index 0b4b72923..c5d2995be 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -31,6 +31,7 @@ import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; @@ -333,7 +334,7 @@ public class KnowledgeBaseUpdater { return required; } - RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(servletContext).getRDFService(); + RDFService rdfService = ModelAccess.on(servletContext).getRDFService(); // if the ASK query DOES have a solution (i.e. the assertions exist // showing that the update has already been performed), then the update @@ -381,7 +382,7 @@ public class KnowledgeBaseUpdater { private void assertSuccess(ServletContext servletContext) throws FileNotFoundException, IOException { try { - RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(servletContext).getRDFService(); + RDFService rdfService = ModelAccess.on(servletContext).getRDFService(); ChangeSet changeSet = rdfService.manufactureChangeSet(); File successAssertionsFile = new File(settings.getSuccessAssertionsFile()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/AbstractModelDecorator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/AbstractModelDecorator.java index 1cdbf2d2d..1c607398f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/AbstractModelDecorator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/AbstractModelDecorator.java @@ -40,6 +40,8 @@ import com.hp.hpl.jena.shared.Command; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.PrefixMapping; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + /** * The base class for a delegating model decorator. * @@ -56,6 +58,12 @@ public abstract class AbstractModelDecorator implements Model { this.inner = m; } + @Override + public String toString() { + return ToString.simpleName(this) + "[" + ToString.hashHex(this) + + ", inner=" + ToString.modelToString(inner) + "]"; + } + @Override @Deprecated public Resource getResource(String uri, com.hp.hpl.jena.rdf.model.ResourceF f) { @@ -464,13 +472,13 @@ public abstract class AbstractModelDecorator implements Model { @Override public Model remove(Model m) { - return m.remove(m); + return inner.remove(m); } @Override @Deprecated public Model remove(Model m, boolean suppressReifications) { - return m.remove(m, suppressReifications); + return inner.remove(m, suppressReifications); } @Override @@ -737,13 +745,13 @@ public abstract class AbstractModelDecorator implements Model { @Override public Model add(Model m) { - return m.add(m); + return inner.add(m); } @Override @Deprecated public Model add(Model m, boolean suppressReifications) { - return m.add(m, suppressReifications); + return inner.add(m, suppressReifications); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/AbstractOntModelDecorator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/AbstractOntModelDecorator.java index 2f9f6d8d4..dc6d2b7eb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/AbstractOntModelDecorator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/AbstractOntModelDecorator.java @@ -79,7 +79,7 @@ import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.PrefixMapping; import com.hp.hpl.jena.util.iterator.ExtendedIterator; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; /** * The base class for a delegating ontology model decorator. @@ -511,13 +511,13 @@ public abstract class AbstractOntModelDecorator implements OntModel { @Override public Model remove(Model m) { - return m.remove(m); + return inner.remove(m); } @Override @Deprecated public Model remove(Model m, boolean suppressReifications) { - return m.remove(m, suppressReifications); + return inner.remove(m, suppressReifications); } @Override @@ -784,13 +784,13 @@ public abstract class AbstractOntModelDecorator implements OntModel { @Override public Model add(Model m) { - return m.add(m); + return inner.add(m); } @Override @Deprecated public Model add(Model m, boolean suppressReifications) { - return m.add(m, suppressReifications); + return inner.add(m, suppressReifications); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkUpdatingModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkUpdatingModel.java index 59472183d..0ad31d3cb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkUpdatingModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkUpdatingModel.java @@ -182,11 +182,6 @@ public class BulkUpdatingModel extends AbstractModelDecorator { return this; } - @Override - public String toString() { - return "<" + this.getClass().getSimpleName() + " " + getGraph() + ">"; - } - private Iterator asTriples(StmtIterator it) { return it.mapWith(mapAsTriple); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/MemoryMappedModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/MemoryMappedModel.java new file mode 100644 index 000000000..8eff342d6 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/MemoryMappedModel.java @@ -0,0 +1,142 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.adapters; + +import java.util.List; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelChangedListener; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.rdf.model.impl.StmtIteratorImpl; + +import edu.cornell.mannlib.vitro.webapp.dao.jena.event.CloseEvent; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * Creates an in-memory model, with a listener that keeps the external model in + * sync with it. + */ +public class MemoryMappedModel extends AbstractModelDecorator { + private static final Log log = LogFactory.getLog(MemoryMappedModel.class); + + private final String toString; + + public MemoryMappedModel(Model externalModel, String name) { + super(VitroModelFactory.createModel()); + super.add(externalModel); + super.register(new ModelSynchronizer(externalModel, name)); + + this.toString = "MemoryMappedModel[wrapping " + + ToString.modelToString(externalModel) + "]"; + } + + @Override + public String toString() { + return this.toString; + } + + // ---------------------------------------------------------------------- + // The listener + // ---------------------------------------------------------------------- + + /** + * Simple change listener to keep a model (the 'synchronizee') in synch with + * the model with which it is registered. + */ + public class ModelSynchronizer implements ModelChangedListener { + private Model m; + private String hash; + + public ModelSynchronizer(Model synchronizee, String name) { + this.m = synchronizee; + this.hash = Integer.toHexString(this.hashCode()); + log.debug(String.format("create: %s, wraps %s(%s) as %s", hash, + this.m.getClass().getName(), + Integer.toHexString(this.m.hashCode()), name)); + } + + @Override + public void addedStatement(Statement s) { + log.debug(hash + " addedStatement" + s); + m.add(s); + } + + @Override + public void addedStatements(Statement[] statements) { + log.debug(hash + " addedStatements: " + statements.length); + m.add(statements); + } + + @Override + public void addedStatements(List statements) { + log.debug(hash + " addedStatements: " + statements.size()); + m.add(statements); + } + + @Override + public void addedStatements(StmtIterator statements) { + if (log.isDebugEnabled()) { + Set set = statements.toSet(); + log.debug(hash + " addedStatements: " + set.size()); + m.add(new StmtIteratorImpl(set.iterator())); + } else { + m.add(new StmtIteratorImpl(statements)); + } + } + + @Override + public void addedStatements(Model model) { + log.debug(hash + " addedStatements: " + model.size()); + m.add(model); + } + + @Override + public void notifyEvent(Model model, Object event) { + if (event instanceof CloseEvent) { + m.close(); + } + } + + @Override + public void removedStatement(Statement s) { + log.debug(hash + " removedStatement" + s); + m.remove(s); + } + + @Override + public void removedStatements(Statement[] statements) { + log.debug(hash + " removedStatements: " + statements.length); + m.remove(statements); + } + + @Override + public void removedStatements(List statements) { + log.debug(hash + " removedStatements: " + statements.size()); + m.remove(statements); + } + + @Override + public void removedStatements(StmtIterator statements) { + if (log.isDebugEnabled()) { + Set set = statements.toSet(); + log.debug(hash + " removedStatements: " + set.size()); + m.remove(new StmtIteratorImpl(set.iterator())); + } else { + m.remove(new StmtIteratorImpl(statements)); + } + } + + @Override + public void removedStatements(Model model) { + log.debug(hash + " removedStatements: " + model.size()); + m.remove(model); + } + + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/VitroModelFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/VitroModelFactory.java index 739bc9975..3de5327ce 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/VitroModelFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/VitroModelFactory.java @@ -17,7 +17,7 @@ import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.impl.ModelCom; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; /** * Make models that will do proper bulk updates. diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java index e970c8969..a1915a189 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java @@ -11,6 +11,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; /** * An RDFServiceFactory that always returns the same RDFService object @@ -140,7 +141,12 @@ public class RDFServiceFactorySingle implements RDFServiceFactory { // Don't close s. It's being used by everybody. } + @Override + public String toString() { + return ToString.simpleName(this) + "[" + ToString.hashHex(this) + + ", inner=" + s + "]"; + } + } - } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceUtils.java index 77e864436..15c67689a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceUtils.java @@ -18,6 +18,7 @@ import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.sparql.resultset.ResultsFormat; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat; @@ -31,8 +32,6 @@ public class RDFServiceUtils { private static final String RDFSERVICEFACTORY_ATTR = RDFServiceUtils.class.getName() + ".RDFServiceFactory"; - public enum WhichService {CONTENT, CONFIGURATION} - public static RDFServiceFactory getRDFServiceFactory(ServletContext context) { return getRDFServiceFactory(context, WhichService.CONTENT); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/ListeningGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/ListeningGraph.java index 6d8702ce0..690fcf02f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/ListeningGraph.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/ListeningGraph.java @@ -29,7 +29,7 @@ import com.hp.hpl.jena.util.iterator.WrappedIterator; import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceImpl; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class ListeningGraph implements GraphWithPerform { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java index cf7ced6e6..40fb8edda 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java @@ -27,7 +27,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.RDFServiceJena; -import edu.cornell.mannlib.vitro.webapp.utils.ToString; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; public class RDFServiceSDB extends RDFServiceJena implements RDFService { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/tdb/RDFServiceTDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/tdb/RDFServiceTDB.java index cff20f024..519bd9e02 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/tdb/RDFServiceTDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/tdb/RDFServiceTDB.java @@ -22,6 +22,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.RDFServiceJena; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; /** * An implementation that is based on Jena TDB. @@ -165,4 +166,8 @@ public class RDFServiceTDB extends RDFServiceJena { } } + @Override + public String toString() { + return "RDFServiceTDB[" + ToString.hashHex(this) + "]"; + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index f229aeadc..bce72e978 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -17,7 +17,6 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.AnnotationProperty; import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.ontology.OntProperty; import com.hp.hpl.jena.rdf.listeners.StatementListener; import com.hp.hpl.jena.rdf.model.Literal; @@ -66,9 +65,9 @@ public class SimpleReasoner extends StatementListener { private static final String mostSpecificTypePropertyURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#mostSpecificType"; - private static final AnnotationProperty mostSpecificType = - (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)) - .createAnnotationProperty(mostSpecificTypePropertyURI); + private static final AnnotationProperty mostSpecificType = ( + VitroModelFactory.createOntologyModel()) + .createAnnotationProperty(mostSpecificTypePropertyURI); // DeltaComputer private CumulativeDeltaModeler aBoxDeltaModeler1 = null; @@ -102,8 +101,8 @@ public class SimpleReasoner extends StatementListener { this.tboxModel = tboxModel; - this.fullModel = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, ModelFactory.createModelForGraph( + this.fullModel = VitroModelFactory.createOntologyModel( + VitroModelFactory.createModelForGraph( new RDFServiceGraph(rdfService))); this.aboxModel = VitroModelFactory.createOntologyModel( @@ -141,9 +140,8 @@ public class SimpleReasoner extends StatementListener { this.tboxModel = tboxModel; this.aboxModel = aboxModel; this.inferenceModel = inferenceModel; - this.fullModel = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, ModelFactory.createUnion( - aboxModel, inferenceModel)); + this.fullModel = VitroModelFactory.createUnion(aboxModel, + VitroModelFactory.createOntologyModel(inferenceModel)); aBoxDeltaModeler1 = new CumulativeDeltaModeler(); aBoxDeltaModeler2 = new CumulativeDeltaModeler(); this.batchMode = 0; @@ -550,7 +548,7 @@ public class SimpleReasoner extends StatementListener { */ protected void addedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) { //log.debug("subClass = " + subClass.getURI() + " superClass = " + superClass.getURI()); - OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + OntModel unionModel = VitroModelFactory.createOntologyModel(); unionModel.addSubModel(aboxModel); unionModel.addSubModel(inferenceModel); List subjectList = new ArrayList(); @@ -580,7 +578,7 @@ public class SimpleReasoner extends StatementListener { * of A (including A itself) */ protected void removedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) { - OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + OntModel unionModel = VitroModelFactory.createOntologyModel(); unionModel.addSubModel(aboxModel); unionModel.addSubModel(inferenceModel); List subjectList = new ArrayList(); @@ -862,7 +860,7 @@ public class SimpleReasoner extends StatementListener { protected void generateSameAsInferences(Resource ind1, Resource ind2, Model inferenceModel) { - OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + OntModel unionModel = VitroModelFactory.createOntologyModel(); unionModel.addSubModel(aboxModel); unionModel.addSubModel(inferenceModel); @@ -1310,7 +1308,7 @@ public class SimpleReasoner extends StatementListener { HashSet typeURIs = new HashSet(); try { - OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + OntModel unionModel = VitroModelFactory.createOntologyModel(); unionModel.addSubModel(aboxModel); unionModel.addSubModel(inferenceModel); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ContextNodeFields.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ContextNodeFields.java index 24e368c9e..636a61e91 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ContextNodeFields.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ContextNodeFields.java @@ -51,7 +51,7 @@ public class ContextNodeFields implements DocumentModifier{ } @Override - public void modifyDocument(Individual individual, SearchInputDocument doc, StringBuffer addUri) { + public void modifyDocument(Individual individual, SearchInputDocument doc) { if( individual == null ) return; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/DocumentModifier.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/DocumentModifier.java index 7b3b6194a..c6323b17d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/DocumentModifier.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/DocumentModifier.java @@ -4,13 +4,25 @@ package edu.cornell.mannlib.vitro.webapp.search.documentBuilding; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument; + /** - * This interface represents an object that can add to a SearchInputDocument. + * An object that can add to a SearchInputDocument. */ public interface DocumentModifier { - public void modifyDocument(Individual individual, SearchInputDocument doc, StringBuffer addUri) throws SkipIndividualException; - - //called to inform the DocumentModifier that the system is shutting down - public void shutdown(); - + /** + * Use the rules contained within this class to modify this search document, + * according to the characteristics of this individual. + * + * @param individual + * The individual that is being indexed. Will not be null. + * @param doc + * The document as it stands so far. Will not be null. + */ + public void modifyDocument(Individual individual, SearchInputDocument doc); + + /** + * Called to inform the DocumentModifier that the system is shutting down. + */ + public void shutdown(); + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/IndividualToSearchDocument.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/IndividualToSearchDocument.java index 6bb9986d9..78ce9c044 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/IndividualToSearchDocument.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/IndividualToSearchDocument.java @@ -97,7 +97,7 @@ public class IndividualToSearchDocument { log.debug(ind.getURI() + " pre mod boost: " + doc.getDocumentBoost()); - runAdditionalDocModifers(ind,doc,addUri); + runAdditionalDocModifers(ind,doc); log.debug(ind.getURI() + " post mod boost: " + doc.getDocumentBoost()); @@ -132,7 +132,7 @@ public class IndividualToSearchDocument { protected Map docModClassToTime = new HashMap(); protected long docModCount =0; - protected void runAdditionalDocModifers( Individual ind, SearchInputDocument doc, StringBuffer addUri ) + protected void runAdditionalDocModifers( Individual ind, SearchInputDocument doc ) throws SkipIndividualException{ //run the document modifiers if( documentModifiers != null && !documentModifiers.isEmpty()){ @@ -141,7 +141,7 @@ public class IndividualToSearchDocument { long start = System.currentTimeMillis(); - modifier.modifyDocument(ind, doc, addUri); + modifier.modifyDocument(ind, doc); if( log.isDebugEnabled()){ long delta = System.currentTimeMillis() - start; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameBoost.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameBoost.java index 5a0da964b..67eaf66c1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameBoost.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameBoost.java @@ -28,8 +28,7 @@ public class NameBoost implements DocumentModifier { } @Override - public void modifyDocument(Individual individual, SearchInputDocument doc, - StringBuffer addUri) { + public void modifyDocument(Individual individual, SearchInputDocument doc) { for( String fieldName : fieldsToBoost){ SearchInputField field = doc.getField(fieldName); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameFields.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameFields.java index 06b592d53..964a16e4a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameFields.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameFields.java @@ -18,7 +18,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames; /** - * Adds all labels to name fields, not just the one returned by Indivdiual.getName(). + * Adds all labels to name fields, not just the one returned by Individual.getName(). */ public class NameFields implements DocumentModifier { RDFServiceFactory rsf; @@ -31,8 +31,7 @@ public class NameFields implements DocumentModifier { } @Override - public void modifyDocument(Individual ind, SearchInputDocument doc, - StringBuffer addUri) throws SkipIndividualException { + public void modifyDocument(Individual ind, SearchInputDocument doc) { if( ind == null || ind.getURI() == null ){ return; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/SourceInstitution.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/SourceInstitution.java index ccd0c0ccc..85dfb40bd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/SourceInstitution.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/SourceInstitution.java @@ -7,26 +7,25 @@ import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames; public class SourceInstitution implements DocumentModifier { - + private String siteURL; private String siteName; - + static VitroSearchTermNames term = new VitroSearchTermNames(); private String fieldForSiteURL = term.SITE_URL; private String fieldForSiteName = term.SITE_NAME; - - public SourceInstitution(String siteURL, String siteName){ + + public SourceInstitution(String siteURL, String siteName) { this.siteURL = siteURL; this.siteName = siteName; } - + @Override - public void modifyDocument(Individual individual, SearchInputDocument doc, - StringBuffer addUri) throws SkipIndividualException { - + public void modifyDocument(Individual individual, SearchInputDocument doc) { + doc.addField(VitroSearchTermNames.SITE_URL, siteURL); doc.addField(VitroSearchTermNames.SITE_NAME, siteURL); - + doc.addField(fieldForSiteName, siteName); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ThumbnailImageURL.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ThumbnailImageURL.java index bafcd761d..a82b3a661 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ThumbnailImageURL.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ThumbnailImageURL.java @@ -45,10 +45,8 @@ public class ThumbnailImageURL implements DocumentModifier { } @Override - public void modifyDocument(Individual individual, SearchInputDocument doc, - StringBuffer addUri) throws SkipIndividualException { - - //add a field for storing the location of thumbnail for the individual. + public void modifyDocument(Individual individual, SearchInputDocument doc) { + // add a field for storing the location of thumbnail for the individual. doc.addField(THUMBNAIL_URL, runQueryForThumbnailLocation(individual)); addThumbnailExistence(individual, doc); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/SearchEngineWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/InstrumentedSearchEngineWrapper.java similarity index 93% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/SearchEngineWrapper.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/InstrumentedSearchEngineWrapper.java index 9b59f232f..137506630 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/SearchEngineWrapper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/InstrumentedSearchEngineWrapper.java @@ -20,16 +20,18 @@ import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse; /** - * TODO + * Manages the life-cycle of the SearchEngine. Adds logging, controlled by + * DeveloperSettings. */ -public class SearchEngineWrapper implements SearchEngine { - private static final Log log = LogFactory.getLog(SearchEngineWrapper.class); +public class InstrumentedSearchEngineWrapper implements SearchEngine { + private static final Log log = LogFactory + .getLog(InstrumentedSearchEngineWrapper.class); private final SearchEngine innerEngine; private volatile LifecycleState lifecycleState = NEW; - public SearchEngineWrapper(SearchEngine innerEngine) { + public InstrumentedSearchEngineWrapper(SearchEngine innerEngine) { if (innerEngine == null) { throw new NullPointerException("innerEngine may not be null."); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/SearchEngineLogger.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/SearchEngineLogger.java index 268f7bcfc..b46cb6314 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/SearchEngineLogger.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/SearchEngineLogger.java @@ -254,7 +254,7 @@ public abstract class SearchEngineLogger implements AutoCloseable { QueryLogger(SearchQuery query) { this.query = query; - this.stackTrace = new StackTraceUtility(SearchEngineWrapper.class, + this.stackTrace = new StackTraceUtility(InstrumentedSearchEngineWrapper.class, true); this.passesRestrictions = passesQueryRestriction() && passesStackRestriction(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputDocument.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputDocument.java index a41054ff3..51bfb596d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputDocument.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputDocument.java @@ -14,8 +14,28 @@ import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField; * A foundation class for implementing SearchInputDocument. */ public class BaseSearchInputDocument implements SearchInputDocument { - private final Map fieldMap = new HashMap<>(); - private float documentBoost = 1.0F; + private final Map fieldMap; + private float documentBoost; + + /** + * Default constructor. + */ + public BaseSearchInputDocument() { + this.fieldMap = new HashMap<>(); + this.documentBoost = 1.0F; + } + + /** + * Create a deep copy, down to the value objects. + */ + public BaseSearchInputDocument(BaseSearchInputDocument doc) { + this.documentBoost = doc.documentBoost; + this.fieldMap = new HashMap<>(); + for (String fieldName : doc.getFieldMap().keySet()) { + this.fieldMap.put(fieldName, + new BaseSearchInputField(doc.getField(fieldName))); + } + } @Override public void addField(SearchInputField field) { @@ -77,10 +97,33 @@ public class BaseSearchInputDocument implements SearchInputDocument { return new BaseSearchInputField(name); } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Float.floatToIntBits(documentBoost); + result = prime * result + fieldMap.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BaseSearchInputDocument other = (BaseSearchInputDocument) obj; + return (Float.floatToIntBits(documentBoost) == Float + .floatToIntBits(other.documentBoost)) + && fieldMap.equals(other.fieldMap); + } + @Override public String toString() { return "BaseSearchInputDocument[fieldMap=" + fieldMap + ", documentBoost=" + documentBoost + "]"; } - + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputField.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputField.java index b0ce82393..c83fa757c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputField.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputField.java @@ -14,12 +14,22 @@ import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField; */ public class BaseSearchInputField implements SearchInputField { private final String name; - private final List valueList = new ArrayList<>(); - - private float boost = 1.0F; + private final List valueList; + private float boost; public BaseSearchInputField(String name) { this.name = name; + this.valueList = new ArrayList<>(); + this.boost = 1.0F; + } + + /** + * Create a copy of the field. + */ + public BaseSearchInputField(SearchInputField field) { + this.name = field.getName(); + this.valueList = new ArrayList<>(field.getValues()); + this.boost = field.getBoost(); } @Override @@ -61,10 +71,58 @@ public class BaseSearchInputField implements SearchInputField { } } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Float.floatToIntBits(boost); + result = prime * result + name.hashCode(); + result = prime * result + valueList.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BaseSearchInputField other = (BaseSearchInputField) obj; + return (Float.floatToIntBits(boost) == Float + .floatToIntBits(other.boost)) + && name.equals(other.name) + && equalsIgnoreOrder(valueList, other.valueList); + } + + /** + * Can't just compare the value lists, because they are considered to be + * equivalent even if the order is differemt. + * + * Can't just convert them to Sets, because either list may contain the same + * object multiple times. + * + * Remove the members of list1 from list2, one at a time. If any member is + * not found, the lists are not equivalent. + */ + private boolean equalsIgnoreOrder(List list1, List list2) { + if (list1.size() != list2.size()) { + return false; + } + List remaining = new ArrayList<>(list2); + for (Object value : list1) { + if (!remaining.remove(value)) { + return false; + } + } + return true; + } + @Override public String toString() { - return "BaseSearchInputField[name=" + name + ", valueList=" - + valueList + ", boost=" + boost + "]"; + return "BaseSearchInputField[name=" + name + ", valueList=" + valueList + + ", boost=" + boost + "]"; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchindex/SearchIndexerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchindex/SearchIndexerSetup.java index bb42e07c4..6e742499b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/searchindex/SearchIndexerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/searchindex/SearchIndexerSetup.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.searchindex; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; + import java.util.ArrayList; import java.util.List; @@ -14,13 +16,13 @@ import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.vocabulary.OWL; import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilterUtils; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; @@ -80,8 +82,8 @@ public class SearchIndexerSetup implements ServletContextListener { try { /* set up the individual to search doc translation */ - OntModel jenaOntModel = ModelAccess.on(context).getJenaOntModel(); - OntModel displayModel = ModelAccess.on(context).getDisplayModel(); + OntModel jenaOntModel = ModelAccess.on(context).getOntModel(); + OntModel displayModel = ModelAccess.on(context).getOntModel(DISPLAY); /* * try to get context attribute DocumentModifiers and use that as diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ConfigurationModelsSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ConfigurationModelsSetup.java index aa35e7bd2..b195f65eb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ConfigurationModelsSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ConfigurationModelsSetup.java @@ -2,14 +2,18 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_DISPLAY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_TBOX; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS; + import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import com.hp.hpl.jena.ontology.OntModel; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** @@ -23,10 +27,10 @@ public class ConfigurationModelsSetup implements ServletContextListener { StartupStatus ss = StartupStatus.getBean(ctx); try { - setupModel(ctx, ModelNames.DISPLAY, "display"); - setupModel(ctx, ModelNames.DISPLAY_TBOX, "displayTbox"); - setupModel(ctx, ModelNames.DISPLAY_DISPLAY, "displayDisplay"); - setupModel(ctx, ModelNames.USER_ACCOUNTS, "auth"); + setupModel(ctx, DISPLAY, "display"); + setupModel(ctx, DISPLAY_TBOX, "displayTbox"); + setupModel(ctx, DISPLAY_DISPLAY, "displayDisplay"); + setupModel(ctx, USER_ACCOUNTS, "auth"); ss.info(this, "Set up the display models and the user accounts model."); } catch (Exception e) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ContentModelSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ContentModelSetup.java index df6d1164e..2f8eb399c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ContentModelSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ContentModelSetup.java @@ -2,7 +2,9 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; -import static edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode.ASSERTIONS_ONLY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.APPLICATION_METADATA; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS; import java.util.ArrayList; import java.util.List; @@ -14,7 +16,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ResIterator; import com.hp.hpl.jena.rdf.model.Resource; @@ -23,18 +24,10 @@ import com.hp.hpl.jena.util.ResourceUtils; import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.RDF; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.FactoryID; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; -import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** @@ -56,19 +49,16 @@ public class ContentModelSetup extends JenaDataSourceSetupBase } private void setUpJenaDataSource(ServletContext ctx) { - ModelAccess models = ModelAccess.on(ctx); + ContextModelAccess models = ModelAccess.on(ctx); - RDFService rdfService = createRdfService(ctx); - createStartupDataset(ctx, rdfService); - - Model applicationMetadataModel = models.getOntModel(ModelNames.APPLICATION_METADATA); + Model applicationMetadataModel = models.getOntModel(APPLICATION_METADATA); if (applicationMetadataModel.size()== 0) { thisIsFirstStartup(); } - OntModel baseABoxModel = models.getOntModel(ModelNames.ABOX_ASSERTIONS); - OntModel baseTBoxModel = models.getOntModel(ModelNames.TBOX_ASSERTIONS); + OntModel baseABoxModel = models.getOntModel(ABOX_ASSERTIONS); + OntModel baseTBoxModel = models.getOntModel(TBOX_ASSERTIONS); if (isFirstStartup()) { initializeApplicationMetadata(ctx, applicationMetadataModel); @@ -81,32 +71,8 @@ public class ContentModelSetup extends JenaDataSourceSetupBase RDFFilesLoader.loadEveryTimeFiles(ctx, "tbox", baseTBoxModel); log.info("Setting up DAO factories"); - - WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); - config.setDefaultNamespace(getDefaultNamespace(ctx)); - - OntModelSelector baseOms = models.getBaseOntModelSelector(); - WebappDaoFactory baseWadf = new WebappDaoFactorySDB(rdfService, baseOms, config, ASSERTIONS_ONLY); - ModelAccess.on(ctx).setWebappDaoFactory(FactoryID.BASE, baseWadf); - ModelAccess.on(ctx).setWebappDaoFactory(FactoryID.UNFILTERED_BASE, baseWadf); - - OntModelSelector unionOms = models.getUnionOntModelSelector(); - WebappDaoFactory wadf = new WebappDaoFactorySDB(rdfService, unionOms, config); - ModelAccess.on(ctx).setWebappDaoFactory(FactoryID.UNION, wadf); - ModelAccess.on(ctx).setWebappDaoFactory(FactoryID.UNFILTERED_UNION, wadf); - - ctx.setAttribute("defaultNamespace", getDefaultNamespace(ctx)); } - private RDFService createRdfService(ServletContext ctx) { - return RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService(); - } - - private void createStartupDataset(ServletContext ctx, RDFService rdfService) { - Dataset dataset = new RDFServiceDataset(rdfService); - setStartupDataset(dataset, ctx); - } - private long secondsSince(long startTime) { return (System.currentTimeMillis() - startTime) / 1000; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java index 5b8752af8..402804e63 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; + import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; @@ -32,13 +34,10 @@ import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelMaker; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.BlankNodeFilteringModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerUtils; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; // This ContextListener must run after the JenaDataSourceSetup ContextListener @@ -72,12 +71,10 @@ public class FileGraphSetup implements ServletContextListener { try { OntDocumentManager.getInstance().setProcessImports(true); - Dataset dataset = JenaDataSourceSetupBase.getStartupDataset(ctx); - RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx, - WhichService.CONTENT).getRDFService(); + Dataset dataset = ModelAccess.on(ctx).getDataset(); + RDFService rdfService = ModelAccess.on(ctx).getRDFService(CONTENT); ModelMaker modelMaker = new BlankNodeFilteringModelMaker( - rdfService, ModelMakerUtils.getModelMaker(ctx, - WhichService.CONTENT)); + rdfService, ModelAccess.on(ctx).getModelMaker(CONTENT)); // ABox files Set paths = getFilegraphPaths(ctx, RDF, ABOX, FILEGRAPH); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java index bc0b3923f..b7a77de7d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java @@ -7,8 +7,6 @@ import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.hp.hpl.jena.query.Dataset; - import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDaoCon; @@ -40,13 +38,4 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { } } - public static void setStartupDataset(Dataset dataset, ServletContext ctx) { - ctx.setAttribute("startupDataset", dataset); - } - - public static Dataset getStartupDataset(ServletContext ctx) { - Object o = ctx.getAttribute("startupDataset"); - return (o instanceof Dataset) ? ((Dataset) o) : null; - } - } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java index 2687af6fa..0338109eb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java @@ -13,15 +13,15 @@ import net.sf.jga.fn.UnaryFunctor; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.beans.Property; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.EntityPropertyListFilter; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class PropertyMaskingSetup implements ServletContextListener { private final static String ENTITY_PROPERTY_LIST_FILTER_ATTR_NAME = "entityPropertyListFilter"; public void contextInitialized(ServletContextEvent sce) { - OntModel jenaOntModel = ModelAccess.on(sce.getServletContext()).getJenaOntModel(); + OntModel jenaOntModel = ModelAccess.on(sce.getServletContext()).getOntModel(); sce.getServletContext().setAttribute(ENTITY_PROPERTY_LIST_FILTER_ATTR_NAME, new EntityPropertyListFilter(jenaOntModel)); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RemoveObsoletePermissions.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RemoveObsoletePermissions.java index b673e2423..68bd8dfa7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RemoveObsoletePermissions.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RemoveObsoletePermissions.java @@ -2,7 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONFIGURATION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; @@ -19,10 +20,9 @@ import com.hp.hpl.jena.update.UpdateAction; import com.hp.hpl.jena.update.UpdateFactory; import com.hp.hpl.jena.update.UpdateRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** @@ -84,11 +84,11 @@ public class RemoveObsoletePermissions implements ServletContextListener { } public void update() { - OntModel model = ModelAccess.on(ctx).getUserAccountsModel(); + OntModel model = ModelAccess.on(ctx).getOntModel(USER_ACCOUNTS); long statementsAtStart = model.size(); - RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx, - CONFIGURATION).getRDFService(); + RDFService rdfService = ModelAccess.on(ctx).getRDFService( + CONFIGURATION); for (String permissionUri : OBSOLETE_PERMISSIONS) { removeStatements(rdfService, permissionUri); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RunSparqlConstructs.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RunSparqlConstructs.java index c495496d7..0a381cb16 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RunSparqlConstructs.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RunSparqlConstructs.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS; + import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; @@ -29,8 +31,8 @@ import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.util.ResourceUtils; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class RunSparqlConstructs implements ServletContextListener { @@ -50,7 +52,7 @@ public class RunSparqlConstructs implements ServletContextListener { String namespace = (wadf != null && wadf.getDefaultNamespace() != null) ? wadf.getDefaultNamespace() : DEFAULT_DEFAULT_NAMESPACE; - OntModel baseOntModel = ModelAccess.on(ctx).getBaseOntModel(); + OntModel baseOntModel = ModelAccess.on(ctx).getOntModel(FULL_ASSERTIONS); Model anonModel = ModelFactory.createDefaultModel(); Model namedModel = ModelFactory.createDefaultModel(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index a306f5bf4..08d3b5cc3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_INFERENCES; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -21,15 +23,13 @@ import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.vocabulary.OWL; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener; import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.ReasonerConfiguration; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin; import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasonerTBoxListener; @@ -88,12 +88,12 @@ public class SimpleReasonerSetup implements ServletContextListener { // set up simple reasoning for the ABox - RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService(); - Dataset dataset = new RDFServiceDataset(rdfService); + RDFService rdfService = ModelAccess.on(ctx).getRDFService(); + Dataset dataset = ModelAccess.on(ctx).getDataset(); Model rebuildModel = dataset.getNamedModel(JENA_INF_MODEL_REBUILD); Model scratchModel = dataset.getNamedModel(JENA_INF_MODEL_SCRATCHPAD); - Model inferenceModel = dataset.getNamedModel(ModelNames.ABOX_INFERENCES); + Model inferenceModel = dataset.getNamedModel(ABOX_INFERENCES); // the simple reasoner will register itself as a listener to the ABox assertions SimpleReasoner simpleReasoner = new SimpleReasoner( diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ThemeInfoSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ThemeInfoSetup.java index 0d7f65658..8fb5a968a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ThemeInfoSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ThemeInfoSetup.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.APPLICATION_METADATA; + import java.io.File; import java.util.ArrayList; import java.util.Collections; @@ -23,8 +25,8 @@ import com.hp.hpl.jena.util.iterator.ClosableIterator; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean.ThemeInfo; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; public class ThemeInfoSetup implements ServletContextListener { @@ -91,7 +93,7 @@ public class ThemeInfoSetup implements ServletContextListener { } private String getCurrentThemeName(ServletContext ctx) { - OntModel ontModel = ModelAccess.on(ctx).getApplicationMetadataModel(); + OntModel ontModel = ModelAccess.on(ctx).getOntModel(APPLICATION_METADATA); ontModel.enterCriticalSection(Lock.READ); try { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index 5d1e01160..b2482eb94 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -2,6 +2,10 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.ASSERTIONS_ONLY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.INFERENCES_ONLY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -42,11 +46,10 @@ import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** @@ -90,13 +93,13 @@ public class UpdateKnowledgeBase implements ServletContextListener { WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); settings.setDefaultNamespace(wadf.getDefaultNamespace()); - settings.setAssertionOntModelSelector(ModelAccess.on(ctx).getBaseOntModelSelector()); - settings.setInferenceOntModelSelector(ModelAccess.on(ctx).getInferenceOntModelSelector()); - settings.setUnionOntModelSelector(ModelAccess.on(ctx).getUnionOntModelSelector()); + settings.setAssertionOntModelSelector(ModelAccess.on(ctx).getOntModelSelector(ASSERTIONS_ONLY)); + settings.setInferenceOntModelSelector(ModelAccess.on(ctx).getOntModelSelector(INFERENCES_ONLY)); + settings.setUnionOntModelSelector(ModelAccess.on(ctx).getOntModelSelector()); ConfigurationProperties props = ConfigurationProperties.getBean(ctx); Path homeDir = Paths.get(props.getProperty("vitro.home")); - settings.setDisplayModel(ModelAccess.on(ctx).getDisplayModel()); + settings.setDisplayModel(ModelAccess.on(ctx).getOntModel(DISPLAY)); OntModel oldTBoxModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_MODEL_DIR)); settings.setOldTBoxModel(oldTBoxModel); OntModel newTBoxModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "filegraph").toString()); @@ -105,7 +108,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel); OntModel newTBoxAnnotationsModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "firsttime").toString()); settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel); - settings.setRDFService(RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService()); + settings.setRDFService(ModelAccess.on(ctx).getRDFService()); boolean tryMigrateDisplay = true; try { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/DataStructuresProvider.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/DataStructuresProvider.java new file mode 100644 index 000000000..bd84e0f0c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/DataStructuresProvider.java @@ -0,0 +1,35 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup; + +import javax.servlet.http.HttpServletRequest; + +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +/** + * Provides the long-term data structures, and a way to obtain the short-term + * data structures. + * + * Repeated calls for the same data structure should yield the same instance. + * + * Repeated calls for the ShortTermDataStructuresProvider need not yield the + * same instance, but must yield an instance that will return the same + * structures as any other instance for the same request. + */ +public interface DataStructuresProvider { + RDFService getRDFService(WhichService whichService); + + Dataset getDataset(WhichService whichService); + + ModelMaker getModelMaker(WhichService whichService); + + OntModelCache getOntModelCache(); + + ShortTermDataStructuresProvider getShortTermDataStructuresProvider( + HttpServletRequest req); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/RDFSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/RDFSetup.java index ed0f918e7..00fb71fd4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/RDFSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/RDFSetup.java @@ -2,38 +2,43 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup; -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONFIGURATION; -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONTENT; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql.RDFSourceSPARQL.PROPERTY_SPARQL_ENDPOINT_URI; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb.RDFSourceTDB.PROPERTY_CONTENT_TDB_PATH; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql.ContentDataStructuresProviderSPARQL.PROPERTY_SPARQL_ENDPOINT_URI; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb.ContentDataStructuresProviderTDB.PROPERTY_CONTENT_TDB_PATH; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntDocumentManager; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelMakerID; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerUtils; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql.RDFSourceSPARQL; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb.RDFSourceTDB; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.BasicDataStructuresProvider; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ConfigurationDataStructuresProvider; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ContentDataStructuresProvider; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql.ContentDataStructuresProviderSPARQL; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb.ConfigurationDataStructuresProviderTDB; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb.ContentDataStructuresProviderTDB; /** * Create the RDFServiceFactories and ModelMakers for the application to use. */ public class RDFSetup implements ServletContextListener { + private static final Log log = LogFactory.getLog(RDFSetup.class); + private ServletContext ctx; private ConfigurationProperties configProps; - private RDFSource contentRdfSource; - private RDFSource configurationRdfSource; + private ContentDataStructuresProvider contentProvider; + private ConfigurationDataStructuresProvider configurationProvider; + private BasicDataStructuresProvider provider; @Override public void contextInitialized(ServletContextEvent sce) { @@ -42,23 +47,14 @@ public class RDFSetup implements ServletContextListener { configureJena(); - createRdfSources(); + createProviders(); RDFServiceUtils.setRDFServiceFactory(ctx, - contentRdfSource.getRDFServiceFactory(), WhichService.CONTENT); - ModelMakerUtils.setContentModelMakerFactory(ctx, - contentRdfSource.getContentModelMakerFactory()); - ModelAccess.on(ctx).setModelMaker(ModelMakerID.CONTENT, - ModelMakerUtils.getModelMaker(ctx, WhichService.CONTENT)); - + contentProvider.getRDFServiceFactory()); RDFServiceUtils.setRDFServiceFactory(ctx, - configurationRdfSource.getRDFServiceFactory(), - WhichService.CONFIGURATION); - ModelMakerUtils.setConfigurationModelMakerFactory(ctx, - configurationRdfSource.getConfigurationModelMakerFactory()); - ModelAccess.on(ctx).setModelMaker(ModelMakerID.CONFIGURATION, - ModelMakerUtils.getModelMaker(ctx, WhichService.CONFIGURATION)); + configurationProvider.getRDFServiceFactory(), CONFIGURATION); + ModelAccess.setDataStructuresProvider(provider); } private void configureJena() { @@ -70,15 +66,20 @@ public class RDFSetup implements ServletContextListener { * For now, these steps are hard-coded. They should be driven by a * configuration file. */ - private void createRdfSources() { + private void createProviders() { if (isSparqlEndpointContentConfigured()) { - contentRdfSource = new RDFSourceSPARQL(ctx, this); + contentProvider = new ContentDataStructuresProviderSPARQL(ctx, this); } else if (isTdbConfigured()) { - contentRdfSource = new RDFSourceTDB(ctx, this, CONTENT); + contentProvider = new ContentDataStructuresProviderTDB(ctx, this); } else { - contentRdfSource = new RDFSourceSDB(ctx, this); + contentProvider = new ContentDataStructuresProviderSDB(ctx, this); } - configurationRdfSource = new RDFSourceTDB(ctx, this, CONFIGURATION); + + configurationProvider = new ConfigurationDataStructuresProviderTDB(ctx, + this); + + provider = new BasicDataStructuresProvider(contentProvider, + configurationProvider); } private boolean isSparqlEndpointContentConfigured() { @@ -93,11 +94,19 @@ public class RDFSetup implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent sce) { - if (configurationRdfSource != null) { - configurationRdfSource.close(); + if (contentProvider != null) { + try { + contentProvider.close(); + } catch (Exception e) { + log.error("Problem when closing content provider", e); + } } - if (contentRdfSource != null) { - contentRdfSource.close(); + if (configurationProvider != null) { + try { + configurationProvider.close(); + } catch (Exception e) { + log.error("Problem when closing configuration provider", e); + } } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/RDFSource.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/RDFSource.java deleted file mode 100644 index 9528a3bad..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/RDFSource.java +++ /dev/null @@ -1,25 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup; - -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; - -/** - * The interface for a triple-store implementation. It returns an - * RDFServiceFactory and either or both of the ModelMakerFactories. - * - * You should call close() when shutting down the triple-store. - */ -public interface RDFSource extends AutoCloseable { - - RDFServiceFactory getRDFServiceFactory(); - - ModelMakerFactory getContentModelMakerFactory(); - - ModelMakerFactory getConfigurationModelMakerFactory(); - - @Override - void close(); - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/ShortTermDataStructuresProvider.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/ShortTermDataStructuresProvider.java new file mode 100644 index 000000000..2b7d1c6ea --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/ShortTermDataStructuresProvider.java @@ -0,0 +1,27 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup; + +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +/** + * Provide the short-term data structures. Should be closed when no longer + * needed. + * + * Repeated calls for the same data structure should yield the same instance. + * + * Repeated calls for the WebappDaoFactoryConfig need not yield the same + * instance. + */ +public interface ShortTermDataStructuresProvider { + RDFService getRDFService(WhichService whichService); + + OntModelCache getOntModelCache(); + + WebappDaoFactoryConfig getWebappDaoFactoryConfig(); + + void close(); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/BasicDataStructuresProvider.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/BasicDataStructuresProvider.java new file mode 100644 index 000000000..ab31e1dd4 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/BasicDataStructuresProvider.java @@ -0,0 +1,124 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.ABOX_UNION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_UNION; + +import java.util.EnumMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.JoinedOntModelCache; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.ModelMakerOntModelCache; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.UnionModelsOntModelsCache; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.UnionModelsOntModelsCache.UnionSpec; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.DataStructuresProvider; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.ShortTermDataStructuresProvider; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * A simple implementation of DataStructuresProvider. + * + * Note that we don't bother to cache the RDFServices, RDFServiceFactories, and + * ModelMakers, since the providers can be expected to cache them. + * + * We must cache the OntModelCache because it was created here. If we were to + * recreate it, we would lose any sub-models that had been attached in the + * meantime. + */ +public class BasicDataStructuresProvider implements DataStructuresProvider { + /** + * Create union models for ABox and TBox, and full models for assertions and + * inferences. No need to create FULL_UNION, since it's the default model. + */ + public static final UnionSpec[] CONTENT_UNIONS = new UnionSpec[] { + UnionSpec.base(ABOX_ASSERTIONS).plus(ABOX_INFERENCES) + .yields(ABOX_UNION), + UnionSpec.base(TBOX_ASSERTIONS).plus(TBOX_INFERENCES) + .yields(TBOX_UNION), + UnionSpec.base(ABOX_ASSERTIONS).plus(TBOX_ASSERTIONS) + .yields(FULL_ASSERTIONS), + UnionSpec.base(ABOX_INFERENCES).plus(TBOX_INFERENCES) + .yields(FULL_INFERENCES) }; + + private final Map providers; + private final Map ontModels; + private final OntModelCache ontModelCache; + + public BasicDataStructuresProvider( + SingleSourceDataStructuresProvider contentProvider, + SingleSourceDataStructuresProvider configurationProvider) { + providers = new EnumMap<>(WhichService.class); + providers.put(CONTENT, contentProvider); + providers.put(CONFIGURATION, configurationProvider); + + ontModels = new EnumMap<>(WhichService.class); + ontModels.put(CONTENT, new ModelMakerOntModelCache( + getModelMaker(CONTENT))); + ontModels.put(CONFIGURATION, new ModelMakerOntModelCache( + getModelMaker(CONFIGURATION))); + + ontModelCache = new UnionModelsOntModelsCache(new JoinedOntModelCache( + ontModels.get(CONTENT), ontModels.get(CONFIGURATION)), + CONTENT_UNIONS); + } + + protected OntModelCache getOntModels(WhichService whichService) { + return ontModels.get(whichService); + } + + protected RDFServiceFactory getRDFServiceFactory(WhichService whichService) { + return providers.get(whichService).getRDFServiceFactory(); + } + + @Override + public RDFService getRDFService(WhichService whichService) { + return providers.get(whichService).getRDFService(); + } + + @Override + public Dataset getDataset(WhichService whichService) { + return providers.get(whichService).getDataset(); + } + + @Override + public ModelMaker getModelMaker(WhichService whichService) { + return providers.get(whichService).getModelMaker(); + } + + @Override + public OntModelCache getOntModelCache() { + return ontModelCache; + } + + @Override + public ShortTermDataStructuresProvider getShortTermDataStructuresProvider( + HttpServletRequest req) { + return new BasicShortTermDataStructuresProvider(req, this, providers); + } + + @Override + public String toString() { + return "BasicDataStructuresProvider[" + ToString.hashHex(this) + + ", providers=" + providers + ", ontModels=" + ontModelCache + + "]"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/BasicShortTermDataStructuresProvider.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/BasicShortTermDataStructuresProvider.java new file mode 100644 index 000000000..8c371cbe7 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/BasicShortTermDataStructuresProvider.java @@ -0,0 +1,150 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jena.atlas.lib.Pair; + +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.JoinedOntModelCache; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringUtils; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.ShortTermDataStructuresProvider; +import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; + +/** + * The simple implementation of ShortTermDataStructuresProvider. + * + * The short-term RDFServices are cached, lest we somehow create duplicates for + * the same request. Similarly with the short-term OntModels. + */ +public class BasicShortTermDataStructuresProvider implements + ShortTermDataStructuresProvider { + private static final Log log = LogFactory + .getLog(BasicShortTermDataStructuresProvider.class); + + private final HttpServletRequest req; + private final ServletContext ctx; + private final ConfigurationProperties props; + private final BasicDataStructuresProvider parent; + private final Map providers; + private final Map rdfServices; + private final OntModelCache ontModelCache; + + public BasicShortTermDataStructuresProvider( + HttpServletRequest req, + BasicDataStructuresProvider parent, + final Map providers) { + this.req = req; + this.ctx = req.getSession().getServletContext(); + this.props = ConfigurationProperties.getBean(ctx); + this.parent = parent; + this.providers = providers; + this.rdfServices = populateRdfServicesMap(); + this.ontModelCache = createOntModelCache(); + } + + private Map populateRdfServicesMap() { + Map map = new EnumMap<>(WhichService.class); + for (WhichService which : WhichService.values()) { + map.put(which, parent.getRDFServiceFactory(which) + .getShortTermRDFService()); + } + return Collections.unmodifiableMap(map); + } + + private OntModelCache createOntModelCache() { + return new JoinedOntModelCache(shortModels(CONTENT), + shortModels(CONFIGURATION)); + } + + /** + * Ask each provider what short-term models should mask their long-term + * counterparts. + */ + private OntModelCache shortModels(WhichService which) { + return providers.get(which).getShortTermOntModels( + rdfServices.get(which), parent.getOntModels(which)); + } + + @Override + public RDFService getRDFService(WhichService whichService) { + return rdfServices.get(whichService); + } + + @Override + public OntModelCache getOntModelCache() { + return ontModelCache; + } + + @Override + public WebappDaoFactoryConfig getWebappDaoFactoryConfig() { + List langs = getPreferredLanguages(); + WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); + config.setDefaultNamespace(props.getProperty("Vitro.defaultNamespace")); + config.setPreferredLanguages(langs); + config.setUnderlyingStoreReasoned(isStoreReasoned()); + config.setCustomListViewConfigFileMap(getCustomListViewConfigFileMap()); + return config; + } + + private List getPreferredLanguages() { + log.debug("Accept-Language: " + req.getHeader("Accept-Language")); + return LanguageFilteringUtils.localesToLanguages(getPreferredLocales()); + } + + @SuppressWarnings("unchecked") + private Enumeration getPreferredLocales() { + return req.getLocales(); + } + + private boolean isStoreReasoned() { + String isStoreReasoned = props.getProperty( + "VitroConnection.DataSource.isStoreReasoned", "true"); + return ("true".equals(isStoreReasoned)); + } + + private Map>, String> getCustomListViewConfigFileMap() { + Map>, String> map = (Map>, String>) ctx + .getAttribute("customListViewConfigFileMap"); + if (map == null) { + map = new ConcurrentHashMap>, String>(); + ctx.setAttribute("customListViewConfigFileMap", map); + } + return map; + } + + @Override + public void close() { + for (WhichService which : WhichService.values()) { + rdfServices.get(which).close(); + } + } + + @Override + public String toString() { + return "BasicShortTermDataStructuresProvider[" + ToString.hashHex(this) + + ", req=" + ToString.hashHex(req) + ", providers=" + providers + + ", ontModels=" + ontModelCache + "]"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ConfigurationModelMakerFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/ConfigurationDataStructuresProvider.java similarity index 63% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ConfigurationModelMakerFactory.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/ConfigurationDataStructuresProvider.java index f0ae53616..9d9fa90ab 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/modelaccess/ConfigurationModelMakerFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/ConfigurationDataStructuresProvider.java @@ -1,23 +1,20 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vitro.webapp.modelaccess; +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl; import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_DISPLAY; import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_TBOX; import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS; -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONFIGURATION; import com.hp.hpl.jena.rdf.model.ModelMaker; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService; - /** - * Common functionality among the Configuration-based ModelMakerFactorys + * The base class for a provider of configuration models. It just contains some + * useful constants and utility methods. */ -public abstract class ConfigurationModelMakerFactory implements - ModelMakerFactory { - +public abstract class ConfigurationDataStructuresProvider implements + SingleSourceDataStructuresProvider { /** * A list of all Configuration models, in case the implementation wants to * add memory-mapping. @@ -30,13 +27,11 @@ public abstract class ConfigurationModelMakerFactory implements * the source. */ protected ModelMaker addConfigurationDecorators(ModelMaker sourceMM) { - // No decorators yet. + // Insure that these models are created here, and not in the Content. + for (String name : CONFIGURATION_MODELS) { + sourceMM.getModel(name); + } return sourceMM; } - @Override - public WhichService whichModelMaker() { - return CONFIGURATION; - } - } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/ContentDataStructuresProvider.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/ContentDataStructuresProvider.java new file mode 100644 index 000000000..f5fa82053 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/ContentDataStructuresProvider.java @@ -0,0 +1,44 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.APPLICATION_METADATA; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.*; + +import com.hp.hpl.jena.rdf.model.ModelMaker; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.NamedDefaultModelMaker; + +/** + * The base class for a provider of content models. It just contains some useful + * constants and utility methods. + */ +public abstract class ContentDataStructuresProvider implements + SingleSourceDataStructuresProvider { + + /** + * These are the small content models that we want to keep in memory. + */ + protected static final String[] SMALL_CONTENT_MODELS = { + APPLICATION_METADATA, TBOX_ASSERTIONS, TBOX_INFERENCES }; + + /** + * These are the small content OntModels for which we don't need short-term instances. + */ + protected static final String[] MEMORY_MAPPED_CONTENT_MODELS = { + APPLICATION_METADATA, TBOX_ASSERTIONS, TBOX_INFERENCES }; + + private static final String CONTENT_DEFAULT_MODEL_NAME = FULL_UNION; + + /** + * These decorations are added to a Content ModelMaker, regardless of the + * source. + * + * Use the default model as the full union. + */ + protected static ModelMaker addContentDecorators(ModelMaker sourceMM) { + return new NamedDefaultModelMaker(sourceMM, CONTENT_DEFAULT_MODEL_NAME); + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/SingleSourceDataStructuresProvider.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/SingleSourceDataStructuresProvider.java new file mode 100644 index 000000000..cae8beafc --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/SingleSourceDataStructuresProvider.java @@ -0,0 +1,30 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl; + +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; + +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; + +/** + * An RDFSource that provides Content models or Configuration models, but not + * both. + * + * Repeated calls for the same data structure should yield the same instance, + * except for the short-term OntModelCache. + */ +public interface SingleSourceDataStructuresProvider extends AutoCloseable { + RDFServiceFactory getRDFServiceFactory(); + + RDFService getRDFService(); + + Dataset getDataset(); + + ModelMaker getModelMaker(); + + OntModelCache getShortTermOntModels(RDFService shortTermRdfService, + OntModelCache longTermOntModelCache); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/ConfigurationModelMakerFactorySDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/ConfigurationModelMakerFactorySDB.java deleted file mode 100644 index ec037d72a..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/ConfigurationModelMakerFactorySDB.java +++ /dev/null @@ -1,45 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb; - -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ConfigurationModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; - -/** - * In SDB, Configuration models require database connections. - * - * However, they are all small enough for memory-mapping. Once memory-mapped, - * they are suitable for short-term or long-term use. - * - * RDFService doesn't support empty models, so support them with ListCaching - */ -public class ConfigurationModelMakerFactorySDB extends - ConfigurationModelMakerFactory { - - private final ModelMaker longTermModelMaker; - - public ConfigurationModelMakerFactorySDB(RDFService longTermRdfService) { - this.longTermModelMaker = new ListCachingModelMaker( - new MemoryMappingModelMaker(new RDFServiceModelMaker( - longTermRdfService), CONFIGURATION_MODELS)); - } - - @Override - public ModelMaker getModelMaker(RDFService longTermRdfService) { - return addConfigurationDecorators(longTermModelMaker); - } - - /** - * The long-term models are all memory-mapped, so use them. - */ - @Override - public ModelMaker getShortTermModelMaker(RDFService shortTermRdfService) { - return addConfigurationDecorators(longTermModelMaker); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/RDFSourceSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/ContentDataStructuresProviderSDB.java similarity index 62% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/RDFSourceSDB.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/ContentDataStructuresProviderSDB.java index 190e20289..ba6d249de 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/RDFSourceSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/ContentDataStructuresProviderSDB.java @@ -2,7 +2,10 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.BasicDataStructuresProvider.CONTENT_UNIONS; + import java.sql.SQLException; +import java.util.Arrays; import javax.servlet.ServletContext; import javax.servlet.ServletContextListener; @@ -11,6 +14,8 @@ import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; import com.hp.hpl.jena.sdb.SDB; import com.hp.hpl.jena.sdb.SDBFactory; import com.hp.hpl.jena.sdb.Store; @@ -22,25 +27,33 @@ import com.hp.hpl.jena.sdb.util.StoreUtils; import com.mchange.v2.c3p0.ComboPooledDataSource; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerFactory; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; +import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.MaskingOntModelCache; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.ModelMakerOntModelCache; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.UnionModelsOntModelsCache; 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.servlet.setup.JenaDataSourceSetupBase; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.RDFSource; +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; /** * Create the connection to the SDB triple-store. * * Do some smoke-tests on the parameters, create the connection pool, and create * the RDFServiceFactory. - * - * Create the ModelMakerFactories only if requested. */ -public class RDFSourceSDB implements RDFSource { - private static final Log log = LogFactory.getLog(RDFSourceSDB.class); +public class ContentDataStructuresProviderSDB extends + ContentDataStructuresProvider { + private static final Log log = LogFactory + .getLog(ContentDataStructuresProviderSDB.class); static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url"; static final String PROPERTY_DB_USERNAME = "VitroConnection.DataSource.username"; @@ -69,24 +82,30 @@ public class RDFSourceSDB implements RDFSource { private final ComboPooledDataSource ds; private final RDFServiceFactory rdfServiceFactory; private final RDFService rdfService; + private final Dataset dataset; + private final ModelMaker modelMaker; - public RDFSourceSDB(ServletContext ctx, ServletContextListener parent) { + public ContentDataStructuresProviderSDB(ServletContext ctx, + ServletContextListener ctxListener) { try { this.ctx = ctx; this.ss = StartupStatus.getBean(ctx); configureSDBContext(); - new SDBConnectionSmokeTests(ctx, parent) + new SDBConnectionSmokeTests(ctx, ctxListener) .checkDatabaseConnection(); this.ds = new SDBDataSource(ctx).getDataSource(); this.rdfServiceFactory = createRdfServiceFactory(); this.rdfService = rdfServiceFactory.getRDFService(); - ss.info(parent, "Initialized the RDF source for SDB"); + this.dataset = new RDFServiceDataset(this.rdfService); + this.modelMaker = createModelMaker(); + ss.info(ctxListener, + "Initialized the content data structures for SDB"); } catch (SQLException e) { throw new RuntimeException( - "Failed to set up the RDF source for SDB", e); + "Failed to set up the content data structures for SDB", e); } } @@ -105,12 +124,9 @@ public class RDFSourceSDB implements RDFSource { return new RDFServiceFactorySDB(ds, storeDesc); } - + /** * Tests whether an SDB store has been formatted and populated for use. - * - * @param store - * @return */ private boolean isSetUp(Store store) throws SQLException { if (!(StoreUtils.isFormatted(store))) { @@ -118,7 +134,6 @@ public class RDFSourceSDB implements RDFSource { } // even if the store exists, it may be empty - try { return (SDBFactory.connectNamedModel(store, ModelNames.TBOX_ASSERTIONS)).size() > 0; @@ -148,19 +163,49 @@ public class RDFSourceSDB implements RDFSource { store.getTableFormatter().truncate(); } + private ModelMaker createModelMaker() { + return addContentDecorators(new ListCachingModelMaker( + new MemoryMappingModelMaker(new RDFServiceModelMaker( + this.rdfService), SMALL_CONTENT_MODELS))); + } + @Override public RDFServiceFactory getRDFServiceFactory() { return this.rdfServiceFactory; } @Override - public ModelMakerFactory getContentModelMakerFactory() { - return new ContentModelMakerFactorySDB(this.rdfService); + public RDFService getRDFService() { + return this.rdfService; } @Override - public ModelMakerFactory getConfigurationModelMakerFactory() { - return new ConfigurationModelMakerFactorySDB(this.rdfService); + public Dataset getDataset() { + return this.dataset; + } + + @Override + public ModelMaker getModelMaker() { + return this.modelMaker; + } + + /** + * Use models from the short-term RDFService, since there is less contention + * for the database connections that way. The exceptions are the + * memory-mapped models. By keeping them, we also keep their sub-models. + */ + @Override + public OntModelCache getShortTermOntModels(RDFService shortTermRdfService, + OntModelCache longTermOntModelCache) { + ModelMakerOntModelCache shortCache = new ModelMakerOntModelCache( + addContentDecorators(new ListCachingModelMaker( + new RDFServiceModelMaker(shortTermRdfService)))); + + MaskingOntModelCache combinedCache = new MaskingOntModelCache( + shortCache, longTermOntModelCache, + Arrays.asList(MEMORY_MAPPED_CONTENT_MODELS)); + + return new UnionModelsOntModelsCache(combinedCache, CONTENT_UNIONS); } @Override @@ -170,4 +215,10 @@ public class RDFSourceSDB implements RDFSource { } } + @Override + public String toString() { + return "ContentDataStructuresProviderSDB[" + ToString.hashHex(this) + + "]"; + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/ContentModelMakerFactorySDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/ContentModelMakerFactorySDB.java deleted file mode 100644 index 08b51ae22..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/ContentModelMakerFactorySDB.java +++ /dev/null @@ -1,59 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb; - -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ContentModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ShadowingModelMaker; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; - -/** - * In SDB, Content models require database connections. - * - * Memory-map the small models, and use a short-term connection for the others - * (when available). - * - * RDFService doesn't support empty models, so support them with ListCaching - */ -public class ContentModelMakerFactorySDB extends ContentModelMakerFactory - implements ModelMakerFactory { - - private final ModelMaker longTermModelMaker; - - public ContentModelMakerFactorySDB(RDFService longTermRdfService) { - this.longTermModelMaker = new ListCachingModelMaker( - new MemoryMappingModelMaker(new RDFServiceModelMaker( - longTermRdfService), SMALL_CONTENT_MODELS)); - } - - /** - * The small content models (tbox, app_metadata) are memory mapped, for - * speed. - */ - @Override - public ModelMaker getModelMaker(RDFService longTermRdfService) { - return addContentDecorators(longTermModelMaker); - } - - /** - * For short-term use, the large models (abox) will come from a short-term - * service. The small models can be the memory-mapped ones that we created - * for long-term use. - */ - @Override - public ModelMaker getShortTermModelMaker(RDFService shortTermRdfService) { - ModelMaker shortTermModelMaker = new RDFServiceModelMaker( - shortTermRdfService); - - // No need to create a fresh memory map of the small models: use the - // long-term ones. - return addContentDecorators(new ShadowingModelMaker( - shortTermModelMaker, longTermModelMaker, SMALL_CONTENT_MODELS)); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/SDBConnectionSmokeTests.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/SDBConnectionSmokeTests.java index ad9162c0c..b1eedcb00 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/SDBConnectionSmokeTests.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/SDBConnectionSmokeTests.java @@ -2,12 +2,12 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.DEFAULT_DRIVER_CLASS; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_DRIVER_CLASS_NAME; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_PASSWORD; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_TYPE; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_URL; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_USERNAME; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.DEFAULT_DRIVER_CLASS; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_DRIVER_CLASS_NAME; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_PASSWORD; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_TYPE; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_URL; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_USERNAME; import java.io.UnsupportedEncodingException; import java.sql.Connection; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/SDBDataSource.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/SDBDataSource.java index d598bc185..d842fd623 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/SDBDataSource.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sdb/SDBDataSource.java @@ -2,22 +2,22 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.DEFAULT_DRIVER_CLASS; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.DEFAULT_MAXACTIVE; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.DEFAULT_MAXIDLE; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.DEFAULT_TESTONBORROW; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.DEFAULT_TESTONRETURN; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.DEFAULT_TYPE; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.DEFAULT_VALIDATION_QUERY; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.MINIMUM_MAXACTIVE; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_DRIVER_CLASS_NAME; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_MAX_ACTIVE; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_MAX_IDLE; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_PASSWORD; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_TYPE; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_URL; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_USERNAME; -import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.RDFSourceSDB.PROPERTY_DB_VALIDATION_QUERY; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.DEFAULT_DRIVER_CLASS; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.DEFAULT_MAXACTIVE; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.DEFAULT_MAXIDLE; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.DEFAULT_TESTONBORROW; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.DEFAULT_TESTONRETURN; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.DEFAULT_TYPE; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.DEFAULT_VALIDATION_QUERY; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.MINIMUM_MAXACTIVE; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_DRIVER_CLASS_NAME; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_MAX_ACTIVE; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_MAX_IDLE; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_PASSWORD; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_TYPE; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_URL; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_USERNAME; +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB.PROPERTY_DB_VALIDATION_QUERY; import java.beans.PropertyVetoException; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/ConfigurationModelMakerFactorySPARQL.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/ConfigurationModelMakerFactorySPARQL.java deleted file mode 100644 index c516d7e57..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/ConfigurationModelMakerFactorySPARQL.java +++ /dev/null @@ -1,46 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql; - -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ConfigurationModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; - -/** - * On a SPARQL endpoint, is there any difference between short-term and - * long-term connections? - * - * In any case, memory-map all of the Configuration models, and apply them to - * both short-term and long-term use. - * - * RDFService doesn't support empty models, so support them with ListCaching - */ -public class ConfigurationModelMakerFactorySPARQL extends - ConfigurationModelMakerFactory { - - private final ModelMaker longTermModelMaker; - - public ConfigurationModelMakerFactorySPARQL(RDFService longTermRdfService) { - this.longTermModelMaker = new ListCachingModelMaker(new MemoryMappingModelMaker( - new RDFServiceModelMaker(longTermRdfService), - CONFIGURATION_MODELS)); - } - - @Override - public ModelMaker getModelMaker(RDFService longTermRdfService) { - return addConfigurationDecorators(longTermModelMaker); - } - - /** - * The long-term models are all memory-mapped, so use them. - */ - @Override - public ModelMaker getShortTermModelMaker(RDFService shortTermRdfService) { - return addConfigurationDecorators(longTermModelMaker); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/ContentDataStructuresProviderSPARQL.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/ContentDataStructuresProviderSPARQL.java new file mode 100644 index 000000000..9b43cbcbe --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/ContentDataStructuresProviderSPARQL.java @@ -0,0 +1,133 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; + +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; + +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; +import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; +import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; +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.sparql.RDFServiceSparql; +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; + +/** + * For a SPARQL endpoint, each connection is created as needed by the + * RDFService, so there is no need to manage connections here. + * + * As a result, we have a single RDFService, a RDFServiceFactory that always + * returns that single RDFService, a single instance of the Dataset and the + * ModelMaker. + * + * Memory-map the small content models, and add the standard decorators. + */ +public class ContentDataStructuresProviderSPARQL extends + ContentDataStructuresProvider { + public static final String PROPERTY_SPARQL_ENDPOINT_URI = "VitroConnection.DataSource.endpointURI"; + public static final String PROPERTY_SPARQL_UPDATE_ENDPOINT_URI = "VitroConnection.DataSource.updateEndpointURI"; + + private final ServletContextListener ctxListener; + private final ConfigurationProperties props; + private final StartupStatus ss; + private final String endpointURI; + private final String updateEndpointURI; + + private final RDFService rdfService; + private final RDFServiceFactory rdfServiceFactory; + private final Dataset dataset; + private final ModelMaker modelMaker; + + public ContentDataStructuresProviderSPARQL(ServletContext ctx, + ServletContextListener ctxListener) { + this.ctxListener = ctxListener; + this.props = ConfigurationProperties.getBean(ctx); + this.ss = StartupStatus.getBean(ctx); + + this.endpointURI = props.getProperty(PROPERTY_SPARQL_ENDPOINT_URI); + this.updateEndpointURI = props + .getProperty(PROPERTY_SPARQL_UPDATE_ENDPOINT_URI); + + this.rdfService = createRDFService(); + this.rdfServiceFactory = createRDFServiceFactory(); + this.dataset = createDataset(); + this.modelMaker = createModelMaker(); + } + + private RDFService createRDFService() { + if (updateEndpointURI == null) { + ss.info(ctxListener, "Using endpoint at " + endpointURI); + return new RDFServiceSparql(endpointURI); + } else { + ss.info(ctxListener, "Using read endpoint at " + endpointURI + + " and update endpoint at " + updateEndpointURI); + return new RDFServiceSparql(endpointURI, updateEndpointURI); + } + } + + private RDFServiceFactory createRDFServiceFactory() { + return new RDFServiceFactorySingle(this.rdfService); + } + + private Dataset createDataset() { + return new RDFServiceDataset(getRDFService()); + } + + private ModelMaker createModelMaker() { + return addContentDecorators(new ListCachingModelMaker( + new MemoryMappingModelMaker(new RDFServiceModelMaker( + getRDFService()), SMALL_CONTENT_MODELS))); + } + + @Override + public RDFServiceFactory getRDFServiceFactory() { + return this.rdfServiceFactory; + } + + @Override + public RDFService getRDFService() { + return this.rdfService; + } + + @Override + public Dataset getDataset() { + return this.dataset; + } + + @Override + public ModelMaker getModelMaker() { + return this.modelMaker; + } + + @Override + public OntModelCache getShortTermOntModels(RDFService shortTermRdfService, + OntModelCache longTermOntModelCache) { + // No need to use short-term models. + return longTermOntModelCache; + } + + @Override + public void close() { + if (this.rdfService != null) { + this.rdfService.close(); + } + } + + @Override + public String toString() { + return "ContentDataStructuresProviderSPARQL[" + ToString.hashHex(this) + + ", endpointURI=" + endpointURI + ", updateEndpointURI=" + + updateEndpointURI + "]"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/ContentModelMakerFactorySPARQL.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/ContentModelMakerFactorySPARQL.java deleted file mode 100644 index f8d636ceb..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/ContentModelMakerFactorySPARQL.java +++ /dev/null @@ -1,60 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql; - -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ContentModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ShadowingModelMaker; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; - -/** - * On a SPARQL endpoint, is there any difference between short-term and - * long-term connections? - * - * Anyway, memory-map the small models, and use a short-term connection for the - * others (when available). - * - * RDFService doesn't support empty models, so support them with ListCaching - */ -public class ContentModelMakerFactorySPARQL extends ContentModelMakerFactory - implements ModelMakerFactory { - - private final ModelMaker longTermModelMaker; - - public ContentModelMakerFactorySPARQL(RDFService longTermRdfService) { - this.longTermModelMaker = new ListCachingModelMaker(new MemoryMappingModelMaker( - new RDFServiceModelMaker(longTermRdfService), - SMALL_CONTENT_MODELS)); - } - - /** - * The small content models (tbox, app_metadata) are memory mapped, for - * speed. - */ - @Override - public ModelMaker getModelMaker(RDFService longTermRdfService) { - return addContentDecorators(longTermModelMaker); - } - - /** - * For short-term use, the large models (abox) will come from a short-term - * service. The small models can be the memory-mapped ones that we created - * for long-term use. - */ - @Override - public ModelMaker getShortTermModelMaker(RDFService shortTermRdfService) { - ModelMaker shortTermModelMaker = new RDFServiceModelMaker( - shortTermRdfService); - - // No need to create a fresh memory map of the small models: use the - // long-term ones. - return addContentDecorators(new ShadowingModelMaker( - shortTermModelMaker, longTermModelMaker, SMALL_CONTENT_MODELS)); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/RDFSourceSPARQL.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/RDFSourceSPARQL.java deleted file mode 100644 index 58166d9dc..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/sparql/RDFSourceSPARQL.java +++ /dev/null @@ -1,93 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerFactory; -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.sparql.RDFServiceSparql; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.RDFSource; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; - -/** - * Create the connection to a SPARQL endpoint. - * - * Depending on the settings, we might use two endpoints: one for reads and one - * for updates. - * - * Create the RDFServiceFactory. - */ -public class RDFSourceSPARQL implements RDFSource { - private static final Log log = LogFactory.getLog(RDFSourceSPARQL.class); - - public static final String PROPERTY_SPARQL_ENDPOINT_URI = "VitroConnection.DataSource.endpointURI"; - public static final String PROPERTY_SPARQL_UPDATE_ENDPOINT_URI = "VitroConnection.DataSource.updateEndpointURI"; - - private final ServletContextListener parent; - private final ConfigurationProperties props; - private final StartupStatus ss; - private final String endpointURI; - private final String updateEndpointURI; - - private final RDFService rdfService; - private final RDFServiceFactory rdfServiceFactory; - - public RDFSourceSPARQL(ServletContext ctx, ServletContextListener parent) { - this.parent = parent; - this.props = ConfigurationProperties.getBean(ctx); - this.ss = StartupStatus.getBean(ctx); - - this.endpointURI = props.getProperty(PROPERTY_SPARQL_ENDPOINT_URI); - this.updateEndpointURI = props - .getProperty(PROPERTY_SPARQL_UPDATE_ENDPOINT_URI); - - this.rdfService = createRDFService(); - this.rdfServiceFactory = createRDFServiceFactory(); - } - - private RDFService createRDFService() { - if (updateEndpointURI == null) { - ss.info(parent, "Using endpoint at " + endpointURI); - return new RDFServiceSparql(endpointURI); - } else { - ss.info(parent, "Using read endpoint at " + endpointURI - + " and update endpoint at " + updateEndpointURI); - return new RDFServiceSparql(endpointURI, updateEndpointURI); - } - } - - private RDFServiceFactory createRDFServiceFactory() { - return new RDFServiceFactorySingle(this.rdfService); - } - - @Override - public RDFServiceFactory getRDFServiceFactory() { - return this.rdfServiceFactory; - } - - @Override - public ModelMakerFactory getContentModelMakerFactory() { - return new ContentModelMakerFactorySPARQL(this.rdfService); - } - - @Override - public ModelMakerFactory getConfigurationModelMakerFactory() { - return new ConfigurationModelMakerFactorySPARQL(this.rdfService); - } - - @Override - public void close() { - if (this.rdfService != null) { - this.rdfService.close(); - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ConfigurationDataStructuresProviderTDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ConfigurationDataStructuresProviderTDB.java new file mode 100644 index 000000000..003cdb1f6 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ConfigurationDataStructuresProviderTDB.java @@ -0,0 +1,128 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb; + +import java.io.File; +import java.io.IOException; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; + +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; +import com.hp.hpl.jena.tdb.TDB; + +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; +import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; +import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; +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.jena.tdb.RDFServiceTDB; +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; + +/** + * A TDB triple-store has no concept of connections, so we need not manage them + * here. + * + * As a result, we have a single RDFService, a RDFServiceFactory that always + * returns that single RDFService, a single instance of the Dataset and the + * ModelMaker. + * + * Memory-map all of the configuration models, and add the standard decorators. + */ +public class ConfigurationDataStructuresProviderTDB extends + ConfigurationDataStructuresProvider { + + private static final String DIRECTORY_TDB = "tdbModels"; + + private final ConfigurationProperties props; + private final StartupStatus ss; + + private final RDFServiceFactory rdfServiceFactory; + private final RDFService rdfService; + private final Dataset dataset; + private final ModelMaker modelMaker; + + public ConfigurationDataStructuresProviderTDB(ServletContext ctx, + ServletContextListener ctxListener) { + this.props = ConfigurationProperties.getBean(ctx); + this.ss = StartupStatus.getBean(ctx); + + configureTDB(); + + String tdbPath = props.getProperty("vitro.home") + File.separatorChar + + DIRECTORY_TDB; + + try { + this.rdfService = new RDFServiceTDB(tdbPath); + this.rdfServiceFactory = createRDFServiceFactory(); + this.dataset = new RDFServiceDataset(this.rdfService); + this.modelMaker = createModelMaker(); + ss.info(ctxListener, "Initialized the RDF source for TDB"); + } catch (IOException e) { + throw new RuntimeException( + "Failed to set up the RDF source for TDB", e); + } + } + + private void configureTDB() { + TDB.getContext().setTrue(TDB.symUnionDefaultGraph); + } + + private RDFServiceFactory createRDFServiceFactory() { + return new RDFServiceFactorySingle(this.rdfService); + } + + private ModelMaker createModelMaker() { + ModelMaker longTermModelMaker = new ListCachingModelMaker( + new MemoryMappingModelMaker(new RDFServiceModelMaker( + this.rdfService), CONFIGURATION_MODELS)); + return addConfigurationDecorators(longTermModelMaker); + } + + @Override + public RDFServiceFactory getRDFServiceFactory() { + return this.rdfServiceFactory; + } + + @Override + public RDFService getRDFService() { + return this.rdfService; + } + + @Override + public Dataset getDataset() { + return this.dataset; + } + + @Override + public ModelMaker getModelMaker() { + return this.modelMaker; + } + + @Override + public OntModelCache getShortTermOntModels(RDFService shortTermRdfService, + OntModelCache longTermOntModelCache) { + // No need to use short-term models. + return longTermOntModelCache; + } + + @Override + public void close() { + if (this.rdfService != null) { + this.rdfService.close(); + } + } + + @Override + public String toString() { + return "ConfigurationDataStructuresProviderTDB[" + + ToString.hashHex(this) + "]"; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ConfigurationModelMakerFactoryTDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ConfigurationModelMakerFactoryTDB.java deleted file mode 100644 index ac5aa7368..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ConfigurationModelMakerFactoryTDB.java +++ /dev/null @@ -1,45 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb; - -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ConfigurationModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; - -/** - * In TDB, is there any difference between short-term and long-term connections? - * - * In any case, memory-map all of the Configuration models, and apply them to - * both short-term and long-term use. - * - * RDFService doesn't support empty models, so support them with ListCaching - */ -public class ConfigurationModelMakerFactoryTDB extends - ConfigurationModelMakerFactory { - - private final ModelMaker longTermModelMaker; - - public ConfigurationModelMakerFactoryTDB(RDFService longTermRdfService) { - this.longTermModelMaker = new ListCachingModelMaker(new MemoryMappingModelMaker( - new RDFServiceModelMaker(longTermRdfService), - CONFIGURATION_MODELS)); - } - - @Override - public ModelMaker getModelMaker(RDFService longTermRdfService) { - return addConfigurationDecorators(longTermModelMaker); - } - - /** - * The long-term models are all memory-mapped, so use them. - */ - @Override - public ModelMaker getShortTermModelMaker(RDFService shortTermRdfService) { - return addConfigurationDecorators(longTermModelMaker); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ContentDataStructuresProviderTDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ContentDataStructuresProviderTDB.java new file mode 100644 index 000000000..641f2d02c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ContentDataStructuresProviderTDB.java @@ -0,0 +1,126 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb; + +import java.io.IOException; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; + +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; +import com.hp.hpl.jena.tdb.TDB; + +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; +import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; +import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; +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.jena.tdb.RDFServiceTDB; +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; + +/** + * A TDB triple-store has no concept of connections, so we need not manage them + * here. + * + * As a result, we have a single RDFService, a RDFServiceFactory that always + * returns that single RDFService, a single instance of the Dataset and the + * ModelMaker. + * + * Memory-map the small content models, and add the standard decorators. + */ +public class ContentDataStructuresProviderTDB extends + ContentDataStructuresProvider { + + public static final String PROPERTY_CONTENT_TDB_PATH = "VitroConnection.DataSource.tdbDirectory"; + + private final ConfigurationProperties props; + private final StartupStatus ss; + + private final RDFServiceFactory rdfServiceFactory; + private final RDFService rdfService; + private final Dataset dataset; + private final ModelMaker modelMaker; + + public ContentDataStructuresProviderTDB(ServletContext ctx, + ServletContextListener ctxListener) { + this.props = ConfigurationProperties.getBean(ctx); + this.ss = StartupStatus.getBean(ctx); + + configureTDB(); + + String tdbPath = props.getProperty(PROPERTY_CONTENT_TDB_PATH); + + try { + this.rdfService = new RDFServiceTDB(tdbPath); + this.rdfServiceFactory = createRDFServiceFactory(); + this.dataset = new RDFServiceDataset(this.rdfService); + this.modelMaker = createModelMaker(); + ss.info(ctxListener, "Initialized the RDF source for TDB"); + } catch (IOException e) { + throw new RuntimeException( + "Failed to set up the RDF source for TDB", e); + } + } + + private void configureTDB() { + TDB.getContext().setTrue(TDB.symUnionDefaultGraph); + } + + private RDFServiceFactory createRDFServiceFactory() { + return new RDFServiceFactorySingle(this.rdfService); + } + + private ModelMaker createModelMaker() { + return addContentDecorators(new ListCachingModelMaker( + new MemoryMappingModelMaker(new RDFServiceModelMaker( + this.rdfService), SMALL_CONTENT_MODELS))); + } + + @Override + public RDFServiceFactory getRDFServiceFactory() { + return this.rdfServiceFactory; + } + + @Override + public RDFService getRDFService() { + return this.rdfService; + } + + @Override + public Dataset getDataset() { + return this.dataset; + } + + @Override + public ModelMaker getModelMaker() { + return this.modelMaker; + } + + @Override + public OntModelCache getShortTermOntModels(RDFService shortTermRdfService, + OntModelCache longTermOntModelCache) { + // No need to use short-term models. + return longTermOntModelCache; + } + + @Override + public void close() { + if (this.rdfService != null) { + this.rdfService.close(); + } + } + + @Override + public String toString() { + return "ContentDataStructuresProviderTDB[" + ToString.hashHex(this) + + "]"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ContentModelMakerFactoryTDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ContentModelMakerFactoryTDB.java deleted file mode 100644 index 1812129de..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/ContentModelMakerFactoryTDB.java +++ /dev/null @@ -1,49 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb; - -import com.hp.hpl.jena.rdf.model.ModelMaker; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ContentModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ListCachingModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; - -/** - * In TDB, is there any difference between short-term and long-term connections? - * For now, use long-term connections for all models, memory-mapping the small - * ones. - * - * RDFService doesn't support empty models, so support them with ListCaching. - */ -public class ContentModelMakerFactoryTDB extends ContentModelMakerFactory - implements ModelMakerFactory { - - private final ModelMaker longTermModelMaker; - - public ContentModelMakerFactoryTDB(RDFService longTermRdfService) { - this.longTermModelMaker = new ListCachingModelMaker( - new MemoryMappingModelMaker(new RDFServiceModelMaker( - longTermRdfService), SMALL_CONTENT_MODELS)); - } - - /** - * The small content models are memory mapped, for speed. - */ - @Override - public ModelMaker getModelMaker(RDFService longTermRdfService) { - return addContentDecorators(longTermModelMaker); - } - - /** - * There are no connections or connection pool, so short-term use is the - * same as long-term use. - */ - @Override - public ModelMaker getShortTermModelMaker(RDFService shortTermRdfService) { - return addContentDecorators(longTermModelMaker); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/RDFSourceTDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/RDFSourceTDB.java deleted file mode 100644 index 51dd10f98..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/rdfsetup/impl/tdb/RDFSourceTDB.java +++ /dev/null @@ -1,112 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb; - -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONFIGURATION; -import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONTENT; - -import java.io.File; -import java.io.IOException; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.tdb.TDB; - -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelMakerFactory; -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.RDFServiceUtils.WhichService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.tdb.RDFServiceTDB; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.RDFSource; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; - -/** - * Create the connection to the TDB triple-store. This connection is either for - * CONTENT or for CONFIGURATION, but not both. - * - * Create the RDFService on the directory. Create the RDFServiceFactory. - */ -public class RDFSourceTDB implements RDFSource { - private static final Log log = LogFactory.getLog(RDFSourceTDB.class); - - private static final String DIRECTORY_TDB = "tdbModels"; - public static final String PROPERTY_CONTENT_TDB_PATH = "VitroConnection.DataSource.tdbDirectory"; - - private final ConfigurationProperties props; - private final StartupStatus ss; - - private final WhichService which; - private final RDFService rdfService; - private final RDFServiceFactory rdfServiceFactory; - - public RDFSourceTDB(ServletContext ctx, ServletContextListener parent, - WhichService which) { - this.props = ConfigurationProperties.getBean(ctx); - this.ss = StartupStatus.getBean(ctx); - this.which = which; - - configureTDB(); - - String tdbPath; - if (CONTENT == which) { - tdbPath = props.getProperty(PROPERTY_CONTENT_TDB_PATH); - } else { - String vitroHome = props.getProperty("vitro.home"); - tdbPath = vitroHome + File.separatorChar + DIRECTORY_TDB; - } - - try { - this.rdfService = new RDFServiceTDB(tdbPath); - this.rdfServiceFactory = createRDFServiceFactory(); - ss.info(parent, "Initialized the RDF source for TDB"); - } catch (IOException e) { - throw new RuntimeException( - "Failed to set up the RDF source for TDB", e); - } - } - - private void configureTDB() { - TDB.getContext().setTrue(TDB.symUnionDefaultGraph); - } - - private RDFServiceFactory createRDFServiceFactory() { - return new RDFServiceFactorySingle(this.rdfService); - } - - @Override - public RDFServiceFactory getRDFServiceFactory() { - return this.rdfServiceFactory; - } - - @Override - public ModelMakerFactory getContentModelMakerFactory() { - if (CONTENT == which) { - return new ContentModelMakerFactoryTDB(this.rdfService); - } else { - throw new IllegalStateException("This RDFSource is for " + which); - } - } - - @Override - public ModelMakerFactory getConfigurationModelMakerFactory() { - if (CONFIGURATION == which) { - return new ConfigurationModelMakerFactoryTDB(this.rdfService); - } else { - throw new IllegalStateException("This RDFSource is for " + which); - } - } - - @Override - public void close() { - if (this.rdfService != null) { - this.rdfService.close(); - } - } - -} 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 new file mode 100644 index 000000000..df6760e4f --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoader.java @@ -0,0 +1,139 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +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; + +/** + * Load one or more Configuration beans from a specified model. + */ +public class ConfigurationBeanLoader { + + private static final String JAVA_URI_PREFIX = "java:"; + + // ---------------------------------------------------------------------- + // utility methods + // ---------------------------------------------------------------------- + + public static String toJavaUri(Class clazz) { + return JAVA_URI_PREFIX + clazz.getName(); + } + + public static boolean isJavaUri(String uri) { + return uri.startsWith(JAVA_URI_PREFIX); + } + + public static String fromJavaUri(String uri) { + if (!isJavaUri(uri)) { + throw new IllegalArgumentException("Not a java class URI: '" + uri + + "'"); + } + return uri.substring(JAVA_URI_PREFIX.length()); + } + + // ---------------------------------------------------------------------- + // the instance + // ---------------------------------------------------------------------- + + /** Must not be null. */ + private final Model model; + + /** + * May be null, but the loader will be unable to satisfy instances of + * ContextModelUser. + */ + private final ServletContext ctx; + + /** + * May be null, but the loader will be unable to satisfy instances of + * RequestModelUser. + */ + private final HttpServletRequest req; + + public ConfigurationBeanLoader(Model model) { + this(model, null, null); + } + + public ConfigurationBeanLoader(Model model, ServletContext ctx) { + this(model, ctx, null); + } + + public ConfigurationBeanLoader(Model model, HttpServletRequest req) { + this(model, + (req == null) ? null : req.getSession().getServletContext(), + req); + } + + private ConfigurationBeanLoader(Model model, ServletContext ctx, + HttpServletRequest req) { + if (model == null) { + throw new NullPointerException("model may not be null."); + } + + this.model = model; + this.req = req; + this.ctx = ctx; + } + + /** + * Load the instance with this URI, if it is assignable to this class. + */ + public T loadInstance(String uri, Class resultClass) + throws ConfigurationBeanLoaderException { + if (uri == null) { + throw new NullPointerException("uri may not be null."); + } + if (resultClass == null) { + throw new NullPointerException("resultClass may not be null."); + } + + try { + ConfigurationRdf parsedRdf = ConfigurationRdfParser.parse(model, + uri, resultClass); + WrappedInstance wrapper = InstanceWrapper.wrap(parsedRdf + .getConcreteClass()); + wrapper.satisfyInterfaces(ctx, req); + wrapper.setProperties(this, parsedRdf.getPropertyStatements()); + wrapper.validate(); + return wrapper.getInstance(); + } catch (Exception e) { + throw new ConfigurationBeanLoaderException("Failed to load '" + uri + + "'", e); + } + } + + /** + * Find all of the resources with the specified class, and instantiate them. + */ + public Set loadAll(Class resultClass) + throws ConfigurationBeanLoaderException { + Set uris = new HashSet<>(); + try (Critical section = Critical.read(model)) { + List resources = model.listResourcesWithProperty( + RDF.type, createResource(toJavaUri(resultClass))).toList(); + for (Resource r : resources) { + if (r.isURIResource()) { + uris.add(r.getURI()); + } + } + } + + Set instances = new HashSet<>(); + for (String uri : uris) { + instances.add(loadInstance(uri, resultClass)); + } + return instances; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoaderException.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoaderException.java new file mode 100644 index 000000000..e1084f7bc --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoaderException.java @@ -0,0 +1,16 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +/** + * Indicates that the loading of configuration beans did not succeed. + */ +public class ConfigurationBeanLoaderException extends Exception { + public ConfigurationBeanLoaderException(String message) { + super(message); + } + + public ConfigurationBeanLoaderException(String message, Throwable cause) { + super(message, cause); + } +} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationRdf.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationRdf.java new file mode 100644 index 000000000..b43fc2b16 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationRdf.java @@ -0,0 +1,29 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyStatement; + +public class ConfigurationRdf { + private final Class concreteClass; + private final Set properties; + + public ConfigurationRdf(Class concreteClass, + Set properties) { + this.concreteClass = concreteClass; + this.properties = Collections + .unmodifiableSet(new HashSet<>(properties)); + } + + public Class getConcreteClass() { + return concreteClass; + } + + public Set getPropertyStatements() { + return new HashSet<>(properties); + } +} \ No newline at end of file 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 new file mode 100644 index 000000000..507e71319 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationRdfParser.java @@ -0,0 +1,251 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createStatement; +import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.fromJavaUri; +import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.isJavaUri; +import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.toJavaUri; + +import java.lang.reflect.Modifier; +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; +import com.hp.hpl.jena.rdf.model.SimpleSelector; +import com.hp.hpl.jena.rdf.model.Statement; +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; + +/** + * 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 { + 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."); + } + + confirmExistenceInModel(model, uri); + + confirmEligibilityForResultClass(model, uri, resultClass); + + Set properties = loadProperties(model, uri); + + Class concreteClass = determineConcreteClass(model, uri, + resultClass); + + return new ConfigurationRdf(concreteClass, properties); + } + + private static void confirmExistenceInModel(Model model, String uri) + throws InvalidConfigurationRdfException { + Selector s = new SimpleSelector(createResource(uri), null, + (RDFNode) null); + try (Critical section = Critical.read(model)) { + if (model.listStatements(s).toList().isEmpty()) { + throw individualDoesNotAppearInModel(uri); + } + } + } + + private static void confirmEligibilityForResultClass(Model model, + String uri, Class resultClass) + throws InvalidConfigurationRdfException { + Statement s = createStatement(createResource(uri), RDF.type, + createResource(toJavaUri(resultClass))); + try (Critical section = Critical.read(model)) { + if (!model.contains(s)) { + throw noTypeStatementForResultClass(s); + } + } + } + + private static Set loadProperties(Model model, String uri) + throws InvalidConfigurationRdfException { + Set set = new HashSet<>(); + + try (Critical section = Critical.read(model)) { + List rawStatements = model.listStatements( + model.getResource(uri), (Property) null, (RDFNode) null) + .toList(); + if (rawStatements.isEmpty()) { + throw noRdfStatements(uri); + } + + for (Statement s : rawStatements) { + if (s.getPredicate().equals(RDF.type)) { + continue; + } else { + try { + set.add(PropertyType.createPropertyStatement(s)); + } catch (PropertyTypeException e) { + throw new InvalidConfigurationRdfException( + "Invalid property statement on '" + uri + "'", + e); + } + } + } + return set; + } + } + + private static Class determineConcreteClass(Model model, + String uri, Class resultClass) + throws InvalidConfigurationRdfException { + Set> concreteClasses = new HashSet<>(); + + try (Critical section = Critical.read(model)) { + for (RDFNode node : model.listObjectsOfProperty( + createResource(uri), RDF.type).toSet()) { + if (!node.isURIResource()) { + throw typeMustBeUriResource(node); + } + + String typeUri = node.asResource().getURI(); + if (!isConcreteClass(typeUri)) { + continue; + } + + concreteClasses.add(processTypeUri(typeUri, resultClass)); + } + } + + if (concreteClasses.isEmpty()) { + throw noConcreteClasses(uri); + } + + if (concreteClasses.size() > 1) { + throw tooManyConcreteClasses(uri, concreteClasses); + } + + return concreteClasses.iterator().next(); + } + + private static boolean isConcreteClass(String typeUri) + throws InvalidConfigurationRdfException { + try { + if (!isJavaUri(typeUri)) { + return false; + } + Class clazz = Class.forName(fromJavaUri(typeUri)); + if (clazz.isInterface()) { + return false; + } + if (Modifier.isAbstract(clazz.getModifiers())) { + return false; + } + return true; + } catch (ClassNotFoundException | ExceptionInInitializerError e) { + throw failedToLoadClass(typeUri, e); + } + } + + @SuppressWarnings("unchecked") + private static Class processTypeUri(String typeUri, + Class resultClass) throws InvalidConfigurationRdfException { + try { + Class clazz = Class.forName(fromJavaUri(typeUri)); + if (!resultClass.isAssignableFrom(clazz)) { + throw notAssignable(resultClass, clazz); + } + try { + clazz.getConstructor(); + } catch (NoSuchMethodException e) { + throw noZeroArgumentConstructor(clazz); + } catch (SecurityException e) { + throw constructorNotPublic(clazz); + } + return (Class) clazz; + } catch (ClassNotFoundException e) { + throw failedToLoadClass(typeUri, e); + } + } + + private static InvalidConfigurationRdfException individualDoesNotAppearInModel( + String uri) { + return new InvalidConfigurationRdfException( + "The model contains no statements about '" + uri + "'"); + } + + private static InvalidConfigurationRdfException noConcreteClasses(String uri) { + return new InvalidConfigurationRdfException( + "No concrete class is declared for '" + uri + "'"); + } + + private static InvalidConfigurationRdfException tooManyConcreteClasses( + String uri, Set concreteClasses) { + return new InvalidConfigurationRdfException("'" + uri + + "' is declared with more than one " + "concrete class: " + + concreteClasses); + } + + private static InvalidConfigurationRdfException notAssignable( + Class resultClass, Class clazz) { + return new InvalidConfigurationRdfException(clazz + + " cannot be assigned to " + resultClass); + } + + private static InvalidConfigurationRdfException noZeroArgumentConstructor( + Class clazz) { + return new InvalidConfigurationRdfException("Can't instantiate '" + + clazz + "': no zero-argument constructor."); + } + + private static InvalidConfigurationRdfException constructorNotPublic( + Class clazz) { + return new InvalidConfigurationRdfException("Can't instantiate '" + + clazz + "': zero-argument constructor is not public."); + } + + private static InvalidConfigurationRdfException failedToLoadClass( + String typeUri, Throwable e) { + return new InvalidConfigurationRdfException("Can't load this type: '" + + typeUri + "'", e); + } + + private static InvalidConfigurationRdfException typeMustBeUriResource( + RDFNode node) { + return new InvalidConfigurationRdfException( + "Type must be a URI Resource: " + node); + } + + private static InvalidConfigurationRdfException noTypeStatementForResultClass( + Statement s) { + return new InvalidConfigurationRdfException( + "A type statement is required: '" + s); + } + + private static InvalidConfigurationRdfException noRdfStatements(String uri) { + return new InvalidConfigurationRdfException("'" + uri + + "' does not appear as the subject of any " + + "statements in the model."); + } + + public static class InvalidConfigurationRdfException extends Exception { + public InvalidConfigurationRdfException(String message) { + super(message); + } + + public InvalidConfigurationRdfException(String message, Throwable cause) { + super(message, cause); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ContextModelsUser.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ContextModelsUser.java new file mode 100644 index 000000000..304b37bf7 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/ContextModelsUser.java @@ -0,0 +1,13 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; + +/** + * When the ConfigurationBeanLoader creates an instance of this class, it will + * call this method, supplying the RDF models from the context. + */ +public interface ContextModelsUser { + void setContextModels(ContextModelAccess models); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/InstanceWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/InstanceWrapper.java new file mode 100644 index 000000000..c882ccfd5 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/InstanceWrapper.java @@ -0,0 +1,100 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyMethod; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyTypeException; + +/** + * Parse the annotations on this class and package them with a newly-created + * instance of the class. + */ +public class InstanceWrapper { + public static WrappedInstance wrap(Class concreteClass) + throws InstanceWrapperException { + return new WrappedInstance(createInstance(concreteClass), + parsePropertyAnnotations(concreteClass), + parseValidationAnnotations(concreteClass)); + } + + private static T createInstance(Class concreteClass) + throws InstanceWrapperException { + try { + return concreteClass.newInstance(); + } catch (Exception e) { + throw new InstanceWrapperException("Failed to create an instance.", + e); + } + } + + private static Map parsePropertyAnnotations( + Class concreteClass) throws InstanceWrapperException { + Map map = new HashMap<>(); + for (Method method : concreteClass.getDeclaredMethods()) { + Property annotation = method.getAnnotation(Property.class); + if (annotation == null) { + continue; + } + if (!method.getReturnType().equals(Void.TYPE)) { + throw new InstanceWrapperException("Property method '" + method + + "' should return void."); + } + Class[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length != 1) { + throw new InstanceWrapperException("Property method '" + method + + "' must accept exactly one parameter."); + } + + String uri = annotation.uri(); + if (map.containsKey(uri)) { + throw new InstanceWrapperException( + "Two property methods have the same URI value: " + + map.get(uri).getMethod() + ", and " + method); + } + try { + map.put(uri, PropertyType.createPropertyMethod(method)); + } catch (PropertyTypeException e) { + throw new InstanceWrapperException( + "Failed to create the PropertyMethod", e); + } + } + return map; + } + + private static Set parseValidationAnnotations(Class concreteClass) + throws InstanceWrapperException { + Set methods = new HashSet<>(); + for (Method method : concreteClass.getDeclaredMethods()) { + if (method.getAnnotation(Validation.class) == null) { + continue; + } + if (method.getParameterTypes().length > 0) { + throw new InstanceWrapperException("Validation method '" + + method + "' should not have parameters."); + } + if (!method.getReturnType().equals(Void.TYPE)) { + throw new InstanceWrapperException("Validation method '" + + method + "' should return void."); + } + methods.add(method); + } + return methods; + } + + public static class InstanceWrapperException extends Exception { + public InstanceWrapperException(String message) { + super(message); + } + + public InstanceWrapperException(String message, Throwable cause) { + super(message, cause); + } + + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/Property.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/Property.java new file mode 100644 index 000000000..0eecb23e8 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/Property.java @@ -0,0 +1,18 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The annotated method should be called each time a property with a matching + * URI is found on the bean. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Property { + String uri(); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/PropertyType.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/PropertyType.java new file mode 100644 index 000000000..397008548 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/PropertyType.java @@ -0,0 +1,243 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import static com.hp.hpl.jena.datatypes.xsd.XSDDatatype.XSDfloat; +import static com.hp.hpl.jena.datatypes.xsd.XSDDatatype.XSDstring; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.hp.hpl.jena.datatypes.RDFDatatype; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Property; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.Statement; + +/** + * An enumeration of the types of properties that the ConfigurationBeanLoader + * will support. + * + * Also, classes that represent the Java methods and RDF statements associated + * with those types. + */ +public enum PropertyType { + RESOURCE { + @Override + public PropertyStatement buildPropertyStatement(Statement s) { + return new ResourcePropertyStatement(s.getPredicate(), s + .getObject().asResource().getURI()); + } + + @Override + protected PropertyMethod buildPropertyMethod(Method method) { + return new ResourcePropertyMethod(method); + } + + }, + STRING { + @Override + public PropertyStatement buildPropertyStatement(Statement s) { + return new StringPropertyStatement(s.getPredicate(), s.getObject() + .asLiteral().getString()); + } + + @Override + protected PropertyMethod buildPropertyMethod(Method method) { + return new StringPropertyMethod(method); + } + }, + FLOAT { + @Override + public PropertyStatement buildPropertyStatement(Statement s) { + return new FloatPropertyStatement(s.getPredicate(), s.getObject() + .asLiteral().getFloat()); + } + + @Override + protected PropertyMethod buildPropertyMethod(Method method) { + return new FloatPropertyMethod(method); + } + }; + + public static PropertyType typeForObject(RDFNode object) + throws PropertyTypeException { + if (object.isURIResource()) { + return RESOURCE; + } + if (object.isLiteral()) { + Literal literal = object.asLiteral(); + RDFDatatype datatype = literal.getDatatype(); + if (datatype == null || datatype.equals(XSDstring)) { + return STRING; + } + if (datatype.equals(XSDfloat)) { + return FLOAT; + } + } + throw new PropertyTypeException("Unsupported datatype on object: " + + object); + } + + public static PropertyType typeForParameterType(Class parameterType) + throws PropertyTypeException { + if (Float.TYPE.equals(parameterType)) { + return FLOAT; + } + if (String.class.equals(parameterType)) { + return STRING; + } + if (!parameterType.isPrimitive()) { + return RESOURCE; + } + throw new PropertyTypeException( + "Unsupported parameter type on method: " + parameterType); + } + + public static PropertyStatement createPropertyStatement(Statement s) + throws PropertyTypeException { + PropertyType type = PropertyType.typeForObject(s.getObject()); + return type.buildPropertyStatement(s); + } + + public static PropertyMethod createPropertyMethod(Method method) + throws PropertyTypeException { + Class parameterType = method.getParameterTypes()[0]; + PropertyType type = PropertyType.typeForParameterType(parameterType); + return type.buildPropertyMethod(method); + } + + protected abstract PropertyStatement buildPropertyStatement(Statement s); + + protected abstract PropertyMethod buildPropertyMethod(Method method); + + public static abstract class PropertyStatement { + private final PropertyType type; + private final String predicateUri; + + public PropertyStatement(PropertyType type, Property predicate) { + this.type = type; + this.predicateUri = predicate.getURI(); + } + + public PropertyType getType() { + return type; + } + + public String getPredicateUri() { + return predicateUri; + } + + public abstract Object getValue(); + } + + public static class ResourcePropertyStatement extends PropertyStatement { + private final String objectUri; + + public ResourcePropertyStatement(Property predicate, String objectUri) { + super(RESOURCE, predicate); + this.objectUri = objectUri; + } + + @Override + public String getValue() { + return objectUri; + } + } + + public static class StringPropertyStatement extends PropertyStatement { + private final String string; + + public StringPropertyStatement(Property predicate, String string) { + super(STRING, predicate); + this.string = string; + } + + @Override + public String getValue() { + return string; + } + } + + public static class FloatPropertyStatement extends PropertyStatement { + private final float f; + + public FloatPropertyStatement(Property predicate, float f) { + super(FLOAT, predicate); + this.f = f; + } + + @Override + public Float getValue() { + return f; + } + } + + public static abstract class PropertyMethod { + protected final PropertyType type; + protected final Method method; + + public PropertyMethod(PropertyType type, Method method) { + this.type = type; + this.method = method; + } + + public Method getMethod() { + return method; + } + + public Class getParameterType() { + return method.getParameterTypes()[0]; + } + + public void confirmCompatible(PropertyStatement ps) + throws PropertyTypeException { + if (type != ps.getType()) { + throw new PropertyTypeException( + "Can't apply statement of type " + ps.getType() + + " to a method of type " + type); + } + } + + public void invoke(Object instance, Object value) + throws PropertyTypeException { + try { + method.invoke(instance, value); + } catch (IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + throw new PropertyTypeException("Property method failed.", e); + } + } + + } + + public static class ResourcePropertyMethod extends PropertyMethod { + public ResourcePropertyMethod(Method method) { + super(RESOURCE, method); + } + } + + public static class StringPropertyMethod extends PropertyMethod { + public StringPropertyMethod(Method method) { + super(STRING, method); + } + } + + public static class FloatPropertyMethod extends PropertyMethod { + public FloatPropertyMethod(Method method) { + super(FLOAT, method); + } + } + + public static class PropertyTypeException extends Exception { + public PropertyTypeException(String message) { + super(message); + } + + public PropertyTypeException(String message, Throwable cause) { + super(message, cause); + } + + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/RequestModelsUser.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/RequestModelsUser.java new file mode 100644 index 000000000..e5dfe08e2 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/RequestModelsUser.java @@ -0,0 +1,13 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.RequestModelAccess; + +/** + * When the ConfigurationBeanLoader creates an instance of this class, it will + * call this method, supplying the RDF models for the current HTTP request. + */ +public interface RequestModelsUser { + void setRequestModels(RequestModelAccess models); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/Validation.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/Validation.java new file mode 100644 index 000000000..2e3c7c1f5 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/Validation.java @@ -0,0 +1,20 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The annotated method should be called after the bean is instantiated, to + * confirm that the bean is correctly formed. + * + * If the bean is not correctly formed, throw a runtime exception. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Validation { + // No elements +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/WrappedInstance.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/WrappedInstance.java new file mode 100644 index 000000000..ced8285bb --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/configuration/WrappedInstance.java @@ -0,0 +1,135 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyMethod; +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.ResourcePropertyStatement; + +/** + * An instance of a ConfigurationBean, packaged with the distilled information + * about the annotated methods on the class. + */ +public class WrappedInstance { + private final T instance; + private final Map propertyMethods; + private final Set validationMethods; + + public WrappedInstance(T instance, + Map propertyMethods, + Set validationMethods) { + this.instance = instance; + this.propertyMethods = propertyMethods; + this.validationMethods = validationMethods; + } + + /** + * The loader calls this as soon as the instance is created. + * + * If the loader did not have access to a request object, then req will be + * null. If the instance expects request models, an exception will be + * thrown. + */ + public void satisfyInterfaces(ServletContext ctx, HttpServletRequest req) + throws ResourceUnavailableException { + if (instance instanceof ContextModelsUser) { + if (ctx == null) { + throw new ResourceUnavailableException("Cannot satisfy " + + "ContextModelsUser interface: context not available."); + } else { + ContextModelsUser cmu = (ContextModelsUser) instance; + cmu.setContextModels(ModelAccess.on(ctx)); + } + } + if (instance instanceof RequestModelsUser) { + if (req == null) { + throw new ResourceUnavailableException("Cannot satisfy " + + "RequestModelsUser interface: request not available."); + } else { + RequestModelsUser rmu = (RequestModelsUser) instance; + rmu.setRequestModels(ModelAccess.on(req)); + } + } + } + + /** + * The loader provides the distilled property statements from the RDF, to + * populate the instance. + */ + public void setProperties(ConfigurationBeanLoader loader, + Collection propertyStatements) + throws PropertyTypeException, NoSuchPropertyMethodException, + ConfigurationBeanLoaderException { + for (PropertyStatement ps : propertyStatements) { + PropertyMethod pm = propertyMethods.get(ps.getPredicateUri()); + if (pm == null) { + throw new NoSuchPropertyMethodException(ps); + } + + pm.confirmCompatible(ps); + + if (ps instanceof ResourcePropertyStatement) { + ResourcePropertyStatement rps = (ResourcePropertyStatement) ps; + Object subordinate = loader.loadInstance(rps.getValue(), + pm.getParameterType()); + pm.invoke(instance, subordinate); + } else { + pm.invoke(instance, ps.getValue()); + } + } + } + + /** + * After the interfaces have been satisfied and the instance has been + * populated, call any validation methods to see whether the instance is + * viable. + */ + public void validate() throws ValidationFailedException { + for (Method method : validationMethods) { + try { + method.invoke(instance); + } catch (IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + throw new ValidationFailedException( + "Error executing validation method '" + method + "'", e); + } + } + } + + /** + * Once satisfied, populated, and validated, the instance is ready to go. + */ + public T getInstance() { + return instance; + } + + public static class ResourceUnavailableException extends Exception { + public ResourceUnavailableException(String message) { + super(message); + } + } + + public static class ValidationFailedException extends Exception { + public ValidationFailedException(String message, Throwable cause) { + super(message, cause); + } + } + + public static class NoSuchPropertyMethodException extends Exception { + public NoSuchPropertyMethodException(PropertyStatement ps) { + super("No property method for '" + ps.getPredicateUri() + "'"); + } + } + +} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterBase.java index 79a1b7400..f42384c9c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterBase.java @@ -1,6 +1,8 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ package edu.cornell.mannlib.vitro.webapp.utils.dataGetter; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; + import javax.servlet.ServletContext; import org.apache.commons.lang.StringUtils; @@ -9,7 +11,7 @@ import com.hp.hpl.jena.rdf.model.Model; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.jena.JenaIngestController; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public abstract class DataGetterBase implements DataGetter { @@ -25,7 +27,7 @@ public abstract class DataGetterBase implements DataGetter { }else if( REQUEST_JENA_ONT_MODEL.equals(modelName)){ return vreq.getJenaOntModel(); }else if( CONTEXT_DISPLAY_MODEL.equals(modelName)){ - return ModelAccess.on(context).getDisplayModel(); + return ModelAccess.on(context).getOntModel(DISPLAY); }else if( ! StringUtils.isEmpty( modelName)){ Model model = JenaIngestController.getModel( modelName, vreq); if( model == null ) 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 new file mode 100644 index 000000000..113645909 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/Critical.java @@ -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; + +import static com.hp.hpl.jena.shared.Lock.READ; +import static com.hp.hpl.jena.shared.Lock.WRITE; + +import com.hp.hpl.jena.rdf.model.Model; + +/** + * Use this in a try-with-resources block. + * + *
+ * try (Critical section = Critical.read(model)) {
+ * }
+ * 
+ */ +public class Critical implements AutoCloseable { + public static Critical read(Model model) { + return new Critical(model, READ); + } + + public static Critical write(Model model) { + return new Critical(model, WRITE); + } + + private final Model model; + + private Critical(Model model, boolean readLockRequested) { + this.model = model; + this.model.enterCriticalSection(readLockRequested); + } + + @Override + public void close() { + this.model.leaveCriticalSection(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/logging/ComplexStringFormatter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/logging/ComplexStringFormatter.java new file mode 100644 index 000000000..d00a2e7a2 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/logging/ComplexStringFormatter.java @@ -0,0 +1,141 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.logging; + +import java.util.Stack; + +/** + *
+ * The string form of a data structure might look like this:
+ * HolderOfSeveralComponents[@1023948fe, 
+ *     AComponentThing[@dc0048ba],
+ *     AThingWithSurprisingFormatting,
+ *     ThingWithOneComponent[@120985093,
+ *         HoldsNoComponents[@99999999]
+ *         ], 
+ *     ThingWithNoHashCodeAndAMap[
+ *         map={
+ *             one,
+ *             two,
+ *             three
+ *             }
+ *         ],
+ *     AnotherThingWithSurprisingFormatting
+ *     ]
+ *    
+ * Created by following these rules:
+ *    create stack holding line number: size of stack is indent level
+ *    on [ or { -- write "[" or "{", add line number to stack. If next character is not @, } or ], line-break.
+ *    on , -- write ",", line-break
+ *    on ] or } -- pop, if same line number, write "]" or "}"
+ *                 if different line number, line-break (indent plus 1), write "]" or "}"
+ *    where each line-break includes indentation, and skipping any subsequent spaces.
+ * 
+ */ +public class ComplexStringFormatter { + private final String rawString; + private final String indentText; + + private int cursor; + private Stack stack = new Stack<>(); + private StringBuilder buffer = new StringBuilder(); + private int lineNumber; + + public ComplexStringFormatter(String rawString) { + this(rawString, " "); + } + + public ComplexStringFormatter(String rawString, String indentText) { + this.rawString = rawString; + this.indentText = indentText; + } + + @Override + public String toString() { + while (cursor < rawString.length()) { + char c = currentChar(); + switch (c) { + case '[': + case '{': + addChar(); + pushDelimiter(); + skipWhiteSpace(); + if (!isNextCharacter('@', '}', ']')) { + lineBreak(); + } + break; + case ',': + addChar(); + lineBreak(); + break; + case ']': + case '}': + boolean multiline = popDelimiter(); + if (multiline) { + lineBreak(); + addOneIndent(); + } + addChar(); + break; + default: + addChar(); + } + next(); + } + return buffer.toString(); + } + + private void next() { + cursor++; + } + + private char currentChar() { + return rawString.charAt(cursor); + } + + private void addChar() { + buffer.append(currentChar()); + } + + private void addOneIndent() { + buffer.append(indentText); + } + + private void pushDelimiter() { + stack.push(lineNumber); + } + + /** Return true if there was a line break since the delimiter was pushed. */ + private boolean popDelimiter() { + return lineNumber != stack.pop(); + } + + private boolean isNextCharacter(char... chars) { + if (cursor + 1 >= rawString.length()) { + return false; + } + char nextChar = rawString.charAt(cursor + 1); + for (char c : chars) { + if (nextChar == c) { + return true; + } + } + return false; + } + + /** Advance the cursor to before the next non-white character. */ + private void skipWhiteSpace() { + while (isNextCharacter(' ', '\r', '\n', '\t')) { + next(); + } + } + + private void lineBreak() { + buffer.append('\n'); + lineNumber++; + for (int i = 0; i < stack.size(); i++) { + addOneIndent(); + } + skipWhiteSpace(); + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ToString.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/logging/ToString.java similarity index 74% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ToString.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/utils/logging/ToString.java index af18b6a38..c5f0620bb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ToString.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/logging/ToString.java @@ -1,10 +1,13 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vitro.webapp.utils; +package edu.cornell.mannlib.vitro.webapp.utils.logging; + +import static edu.cornell.mannlib.vitro.webapp.servlet.setup.FileGraphSetup.FILEGRAPH_URI_ROOT; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Map.Entry; import java.util.Set; import org.apache.commons.lang.StringUtils; @@ -14,6 +17,8 @@ import com.hp.hpl.jena.graph.compose.Polyadic; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Model; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; + /** * Some useful methods for printing out the contents of data structures: * OntModels, Models, Datasets, etc. @@ -88,15 +93,39 @@ public class ToString { } /** - * If the string is found in ModelNames, return the name of the constant. If - * not, use the string itself. + * If the string is found in ModelNames, return the name of the constant. * - * TODO: Make it work. + * If the name is a filegraph, convert it to filegraph:[suffix] + * + * Otherwise, return the string itself. */ public static String modelName(String name) { + if (name == null) { + return "null"; + } + for (Entry entry : ModelNames.namesMap.entrySet()) { + if (name.equals(entry.getValue())) { + return entry.getKey(); + } + } + if (name.startsWith(FILEGRAPH_URI_ROOT)) { + return "filegraph:" + name.substring(FILEGRAPH_URI_ROOT.length()); + } return name; } + /** + * Replace all Model URIs with their short names. If the filegraph URI root + * is found, replace it with "filegraph:". + */ + public static String replaceModelNames(String raw) { + String s = raw; + for (Entry entry : ModelNames.namesMap.entrySet()) { + s = s.replace(entry.getValue(), entry.getKey()); + } + return s.replace(FILEGRAPH_URI_ROOT, "filegraph:"); + } + public static boolean isVitroClass(Object o) { return (o == null) ? false : o.getClass().getName() .startsWith("edu.cornell"); @@ -107,7 +136,7 @@ public class ToString { } public static String hashHex(Object o) { - return (o == null) ? "00000000" : Integer.toString(o.hashCode(), 16); + return (o == null) ? "@00000000" : String.format("@%08x", o.hashCode()); } /** @@ -116,4 +145,5 @@ public class ToString { private ToString() { // Nothing to initialize. } + } diff --git a/webapp/test/edu/cornell/mannlib/vitro/testing/AbstractTestClass.java b/webapp/test/edu/cornell/mannlib/vitro/testing/AbstractTestClass.java index 423feb8e7..9c9a2adb6 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/testing/AbstractTestClass.java +++ b/webapp/test/edu/cornell/mannlib/vitro/testing/AbstractTestClass.java @@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.testing; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.fail; +import static org.hamcrest.Matchers.containsString; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; @@ -41,8 +42,12 @@ import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; import org.junit.After; import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.ExpectedException; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -52,8 +57,6 @@ import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; -import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectorTest; - /** * A collection of useful routines to help when testing. *
    @@ -264,6 +267,46 @@ public abstract class AbstractTestClass { return tempDirectory; } + // ---------------------------------------------------------------------- + // A better way of handling expected exceptions. + // ---------------------------------------------------------------------- + + @Rule + public ExpectedException exception = ExpectedException.none(); + + protected void expectException(Class type, + String messageSubstring) { + exception.expect(type); + exception.expectMessage(messageSubstring); + } + + protected void expectException(Class type, + Matcher messageMatcher) { + exception.expect(type); + exception.expectMessage(messageMatcher); + } + + protected void expectExceptionCause(Class type, + String messageSubstring) { + exception.expectCause(Matchers. instanceOf(type)); + exception.expectCause(Matchers. hasProperty("message", + containsString(messageSubstring))); + } + + protected void expectExceptionCause(Class type, + Matcher messageMatcher) { + exception.expectCause(Matchers. instanceOf(type)); + exception.expectCause(Matchers. hasProperty("message", + messageMatcher)); + } + + protected void expectException(Class clazz, + String messageSubstring, Class causeClazz, + String causeMessageSubstring) { + expectException(clazz, messageSubstring); + expectExceptionCause(causeClazz, causeMessageSubstring); + } + // ---------------------------------------------------------------------- // Other utilities. // ---------------------------------------------------------------------- @@ -416,9 +459,9 @@ public abstract class AbstractTestClass { return new HashSet(Arrays.asList(array)); } - protected OntModel readModelFromFile(String relativePath, String rdfType) throws IOException { - InputStream stream = this.getClass() - .getResourceAsStream(relativePath); + protected OntModel readModelFromFile(String relativePath, String rdfType) + throws IOException { + InputStream stream = this.getClass().getResourceAsStream(relativePath); Model model = ModelFactory.createDefaultModel(); model.read(stream, null, rdfType); stream.close(); diff --git a/webapp/test/edu/cornell/mannlib/vitro/testing/ModelUtilitiesTestHelper.java b/webapp/test/edu/cornell/mannlib/vitro/testing/ModelUtilitiesTestHelper.java new file mode 100644 index 000000000..69c29537f --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/testing/ModelUtilitiesTestHelper.java @@ -0,0 +1,68 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.testing; + +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createLangLiteral; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createPlainLiteral; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createStatement; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createTypedLiteral; + +import java.util.SortedSet; +import java.util.TreeSet; + +import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.vocabulary.RDF; + +/** + * Just some helper methods for Test classes that work with models. + */ +public class ModelUtilitiesTestHelper { + public static Model model(Statement... stmts) { + return ModelFactory.createDefaultModel().add(stmts); + } + + public static Statement typeStatement(String subjectUri, String classUri) { + return createStatement(createResource(subjectUri), RDF.type, + createResource(classUri)); + } + + public static Statement objectProperty(String subjectUri, + String propertyUri, String objectUri) { + return createStatement(createResource(subjectUri), + createProperty(propertyUri), createResource(objectUri)); + } + + public static Statement dataProperty(String subjectUri, String propertyUri, + String objectValue) { + return createStatement(createResource(subjectUri), + createProperty(propertyUri), createPlainLiteral(objectValue)); + } + + public static Statement dataProperty(String subjectUri, String propertyUri, + Object objectValue, XSDDatatype dataType) { + return createStatement(createResource(subjectUri), + createProperty(propertyUri), + createTypedLiteral(String.valueOf(objectValue), dataType)); + } + + public static Statement dataProperty(String subjectUri, String propertyUri, + String objectValue, String language) { + return createStatement(createResource(subjectUri), + createProperty(propertyUri), + createLangLiteral(objectValue, language)); + } + + public static SortedSet modelToStrings(Model m) { + SortedSet set = new TreeSet<>(); + for (Statement stmt : m.listStatements().toList()) { + set.add(stmt.toString()); + } + return set; + } + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java index a5facb4ef..7e3646070 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java @@ -14,6 +14,7 @@ import org.junit.Test; import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; import stubs.javax.servlet.ServletContextStub; import stubs.javax.servlet.http.HttpServletRequestStub; import stubs.javax.servlet.http.HttpSessionStub; @@ -29,7 +30,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** * Can we tell whether a user is logged in as root? @@ -80,7 +80,7 @@ public class HasPermissionFactoryTest extends AbstractTestClass { wdf.setUserAccountsDao(uaDao); ctx = new ServletContextStub(); - ModelAccess.on(ctx).setWebappDaoFactory(wdf); + new ModelAccessFactoryStub().get(ctx).setWebappDaoFactory(wdf); session = new HttpSessionStub(); session.setServletContext(ctx); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java index 2ab4e0fff..42a847679 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java @@ -9,6 +9,7 @@ import org.junit.Test; import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; import stubs.javax.servlet.ServletContextStub; import stubs.javax.servlet.http.HttpServletRequestStub; import stubs.javax.servlet.http.HttpSessionStub; @@ -19,7 +20,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** * Can we tell whether a user is logged in as root? @@ -57,7 +57,7 @@ public class IsRootUserFactoryTest extends AbstractTestClass { wdf.setUserAccountsDao(uaDao); ctx = new ServletContextStub(); - ModelAccess.on(ctx).setWebappDaoFactory(wdf); + new ModelAccessFactoryStub().get(ctx).setWebappDaoFactory(wdf); session = new HttpSessionStub(); session.setServletContext(ctx); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java index e9c7d59fb..c9b69b018 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java @@ -9,6 +9,7 @@ import org.junit.Test; import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; import stubs.javax.servlet.ServletContextStub; import stubs.javax.servlet.http.HttpServletRequestStub; import stubs.javax.servlet.http.HttpSessionStub; @@ -19,7 +20,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsUser; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** * The simplest of the IdentifierBundleFactory classes. @@ -42,12 +42,12 @@ public class IsUserFactoryTest extends AbstractTestClass { @Before public void setup() { uaDao = new UserAccountsDaoStub(); - + wdf = new WebappDaoFactoryStub(); wdf.setUserAccountsDao(uaDao); ctx = new ServletContextStub(); - ModelAccess.on(ctx).setWebappDaoFactory(wdf); + new ModelAccessFactoryStub().get(ctx).setWebappDaoFactory(wdf); session = new HttpSessionStub(); session.setServletContext(ctx); @@ -70,7 +70,7 @@ public class IsUserFactoryTest extends AbstractTestClass { LoginStatusBean lsb = new LoginStatusBean(USER_URI, AuthenticationSource.EXTERNAL); LoginStatusBean.setBean(session, lsb); - + UserAccount user = new UserAccount(); user.setUri(USER_URI); uaDao.addUser(user); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java index 0529007ea..bb64ad10a 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java @@ -27,6 +27,7 @@ import stubs.edu.cornell.mannlib.vitro.webapp.dao.IndividualDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; import stubs.edu.cornell.mannlib.vitro.webapp.i18n.I18nStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; import stubs.javax.servlet.ServletConfigStub; import stubs.javax.servlet.ServletContextStub; import stubs.javax.servlet.http.HttpServletRequestStub; @@ -48,7 +49,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.AuthenticatorStub; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** */ @@ -132,11 +132,15 @@ public class AuthenticateTest extends AbstractTestClass { authenticator.setAssociatedUri(OLD_SELF.username, "old_self_associated_uri"); + servletContext = new ServletContextStub(); + servletContext.setAttribute(AuthenticatorStub.FACTORY_ATTRIBUTE_NAME, + authenticatorFactory); + PermissionSet adminPermissionSet = new PermissionSet(); adminPermissionSet.setUri(URI_DBA); adminPermissionSet.setPermissionUris(Collections .singleton(SimplePermission.SEE_SITE_ADMIN_PAGE.getUri())); - + userAccountsDao = new UserAccountsDaoStub(); userAccountsDao.addPermissionSet(adminPermissionSet); userAccountsDao.addUser(createUserFromUserInfo(NEW_DBA)); @@ -150,10 +154,8 @@ public class AuthenticateTest extends AbstractTestClass { webappDaoFactory.setUserAccountsDao(userAccountsDao); webappDaoFactory.setIndividualDao(individualDao); - servletContext = new ServletContextStub(); - ModelAccess.on(servletContext).setWebappDaoFactory(webappDaoFactory); - servletContext.setAttribute(AuthenticatorStub.FACTORY_ATTRIBUTE_NAME, - authenticatorFactory); + ModelAccessFactoryStub mafs = new ModelAccessFactoryStub(); + mafs.get(servletContext).setWebappDaoFactory(webappDaoFactory); setLoggerLevel(ServletPolicyList.class, Level.WARN); ServletPolicyList.addPolicy(servletContext, new PermissionsPolicy()); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRdfAssemblerTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRdfAssemblerTest.java index dd1fcb711..638e00cfc 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRdfAssemblerTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRdfAssemblerTest.java @@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.controller.individual; import static com.hp.hpl.jena.ontology.OntModelSpec.OWL_MEM; import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.LABEL; import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.RDF_TYPE; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption.LANGUAGE_NEUTRAL; import static org.junit.Assert.fail; import java.io.IOException; @@ -22,6 +23,7 @@ import org.apache.log4j.Level; import org.junit.Before; import org.junit.Test; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; import stubs.javax.servlet.ServletContextStub; import stubs.javax.servlet.http.HttpServletRequestStub; import stubs.javax.servlet.http.HttpSessionStub; @@ -45,8 +47,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; import edu.cornell.mannlib.vitro.webapp.web.ContentType; @@ -349,8 +351,7 @@ public class IndividualRdfAssemblerTest extends AbstractTestClass { private void setupIndividualRdfAssembler() { rdfService = new RDFServiceModel(rawRdf); - req.setAttribute("rdfService", rdfService); - req.setAttribute("unfilteredRDFService", rdfService); + new ModelAccessFactoryStub().get(req).setRDFService(rdfService, LANGUAGE_NEUTRAL); vreq = new VitroRequest(req); ira = new IndividualRdfAssembler(vreq, INDIVIDUAL_URI, ContentType.N3); } diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java index 8de80829f..dcdf92aca 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java @@ -20,6 +20,7 @@ import org.junit.Test; import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; import stubs.edu.cornell.mannlib.vitro.webapp.modules.ApplicationStub; import stubs.edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineStub; import stubs.javax.servlet.ServletConfigStub; @@ -29,7 +30,7 @@ import stubs.javax.servlet.http.HttpServletResponseStub; import stubs.javax.servlet.http.HttpSessionStub; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * TODO @@ -107,7 +108,7 @@ public class JsonServletTest extends AbstractTestClass { resp = new HttpServletResponseStub(); wadf = new WebappDaoFactoryStub(); - ModelAccess.on(ctx).setWebappDaoFactory(wadf); + new ModelAccessFactoryStub().get(req).setWebappDaoFactory(wadf); vcDao = new VClassDaoStub(); wadf.setVClassDao(vcDao); @@ -185,9 +186,9 @@ public class JsonServletTest extends AbstractTestClass { /** * TODO test successful responses. This will require figuring out how to - * stub SearchEngine. Since we are no longer dealing with an abstract class - * (like SolrServer), so we just need to figure out - * what sort of NamedList is required as a response to a request. + * stub SearchEngine. Since we are no longer dealing with an abstract class + * (like SolrServer), so we just need to figure out what sort of NamedList + * is required as a response to a request. */ @Test public void individualsByClassNoIndividuals() throws ServletException, @@ -230,8 +231,10 @@ public class JsonServletTest extends AbstractTestClass { assertEquals("count", count, getFieldValue(actual, "totalCount")); JSONObject vclassObj = (JSONObject) getFieldValue(actual, "vclass"); - assertEquals("vclass name", vclassId.split("://")[1], getFieldValue(vclassObj, "name")); - assertEquals("vclass uri", vclassId, getFieldValue(vclassObj, "URI")); + assertEquals("vclass name", vclassId.split("://")[1], + getFieldValue(vclassObj, "name")); + assertEquals("vclass uri", vclassId, + getFieldValue(vclassObj, "URI")); assertEquals("status", SC_OK, resp.getStatus()); } catch (JSONException e) { diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/ListCachingModelMakerTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/ListCachingModelMakerTest.java index 7f3013d5c..7d087227f 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/ListCachingModelMakerTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/ListCachingModelMakerTest.java @@ -28,7 +28,8 @@ import com.hp.hpl.jena.shared.DoesNotExistException; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; /** - * TODO + * Test the functions of a ListCachingModelMaker. Does it properly register the + * presence of a model with no triples? */ public class ListCachingModelMakerTest extends AbstractTestClass { private static final String URI_ONE = "http://model.one"; diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/MemoryMappingModelMakerTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/MemoryMappingModelMakerTest.java index 28803c097..78b2cf164 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/MemoryMappingModelMakerTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/MemoryMappingModelMakerTest.java @@ -31,7 +31,8 @@ import com.hp.hpl.jena.rdf.model.Statement; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; /** - * TODO + * Checks the function of a MemoryMappingModelMaker, testing the difference in + * behavior between an mapped model and an unmapped model. */ public class MemoryMappingModelMakerTest extends AbstractTestClass { private static final String URI_MAPPED = "http://memory.mapped.model"; diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/UnionModelsModelMakerTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/UnionModelsModelMakerTest.java deleted file mode 100644 index dc5ee5a72..000000000 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/modelaccess/adapters/UnionModelsModelMakerTest.java +++ /dev/null @@ -1,259 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; - -import stubs.com.hp.hpl.jena.rdf.model.ModelMaker.ModelMakerStub; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.ModelMaker; -import com.hp.hpl.jena.shared.AlreadyExistsException; -import com.hp.hpl.jena.shared.CannotCreateException; -import com.hp.hpl.jena.shared.DoesNotExistException; - -import edu.cornell.mannlib.vitro.testing.AbstractTestClass; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.UnionModelsModelMaker.UnionSpec; - -/** - * Test the functionality of the UnionModelsModelMaker. - */ -public class UnionModelsModelMakerTest extends AbstractTestClass { - private static final String URI_ONE = "http://model.one"; - private static final String URI_TWO = "http://model.two"; - private static final String URI_THREE = "http://model.three"; - private static final String URI_UNION = "http://model.union"; - private static final String URI_NONE = "http://model.does.not.exist"; - - private static final Model MODEL_ONE = createModel(); - private static final Model MODEL_TWO = createModel(); - private static final Model MODEL_THREE = createModel(); - private static final Model MODEL_DEFAULT = createModel(); - private static final Model MODEL_FRESH = createModel(); - - private static Model createModel() { - return ModelFactory.createDefaultModel(); - } - - private ModelMaker inner; - private ModelMaker mm; - - @Before - public void setup() { - /* - * Use a rigorous inner model maker, but it doesn't make much difference. - */ - inner = ModelMakerStub.rigorous(MODEL_DEFAULT, MODEL_FRESH) - .put(URI_ONE, MODEL_ONE).put(URI_TWO, MODEL_TWO) - .put(URI_THREE, MODEL_THREE); - - mm = new UnionModelsModelMaker(inner, UnionSpec.base(URI_ONE) - .plus(URI_TWO).yields(URI_UNION)); - } - - @SuppressWarnings("unused") - @Test(expected = NullPointerException.class) - public void nullInnerModel() { - new UnionModelsModelMaker(null, UnionSpec.base(URI_ONE).plus(URI_TWO) - .yields(URI_UNION)); - } - - @SuppressWarnings("unused") - @Test(expected = IllegalArgumentException.class) - public void duplicateUnionUri() { - new UnionModelsModelMaker(inner, UnionSpec.base(URI_ONE).plus(URI_TWO) - .yields(URI_UNION), UnionSpec.base(URI_ONE).plus(URI_THREE) - .yields(URI_UNION)); - } - - @SuppressWarnings("unused") - @Test(expected = IllegalArgumentException.class) - public void nestedUnions() { - new UnionModelsModelMaker(inner, UnionSpec.base(URI_ONE).plus(URI_TWO) - .yields(URI_UNION), UnionSpec.base(URI_UNION).plus(URI_THREE) - .yields("http://nestedUnion")); - } - - @Test - public void hasModelActual() { - assertTrue(mm.hasModel(URI_ONE)); - } - - @Test - public void hasModelNone() { - assertFalse(mm.hasModel(URI_NONE)); - } - - @Test - public void hasModelUnion() { - assertTrue(mm.hasModel(URI_UNION)); - } - - @Test - public void listModels() { - assertExpectedModelsList(URI_ONE, URI_TWO, URI_THREE, URI_UNION); - } - - @Test - public void createModelActual() { - assertEquals(MODEL_ONE, mm.createModel(URI_ONE)); - } - - @Test - public void createModelNone() { - assertEquals(MODEL_FRESH, mm.createModel(URI_NONE)); - } - - @Test - public void createModelUnion() { - assertTrue(isUnionModel(mm.createModel(URI_UNION))); - } - - @Test(expected = AlreadyExistsException.class) - public void createModelActualStrict() { - mm.createModel(URI_ONE, true); - } - - @Test - public void createModelNoneStrict() { - assertEquals(MODEL_FRESH, mm.createModel(URI_NONE, true)); - } - - @Test(expected = AlreadyExistsException.class) - public void createModelUnionStrict() { - mm.createModel(URI_UNION, true); - } - - @Test - public void openModelActual() { - assertEquals(MODEL_ONE, mm.openModel(URI_ONE)); - } - - @Test(expected = DoesNotExistException.class) - public void openModelNone() { - mm.openModel(URI_NONE); - } - - @Test - public void openModelUnion() { - assertTrue(isUnionModel(mm.openModel(URI_UNION))); - } - - @Test - public void openModelActualStrict() { - assertEquals(MODEL_ONE, mm.openModel(URI_ONE, true)); - } - - @Test(expected = DoesNotExistException.class) - public void openModelNoneStrict() { - mm.openModel(URI_NONE, true); - } - - @Test - public void openModelUnionStrict() { - assertTrue(isUnionModel(mm.openModel(URI_UNION, true))); - } - - @Test - public void openModelIfPresentActual() { - assertEquals(MODEL_ONE, mm.openModelIfPresent(URI_ONE)); - } - - @Test - public void openModelIfPresentNone() { - assertNull(mm.openModelIfPresent(URI_NONE)); - } - - @Test - public void openModelIfPresentUnion() { - assertTrue(isUnionModel(mm.openModelIfPresent(URI_UNION))); - } - - @Test - public void removeModelActual() { - mm.removeModel(URI_ONE); - assertExpectedModelsList(URI_TWO, URI_THREE, URI_UNION); - } - - @Test(expected = DoesNotExistException.class) - public void removeModelNone() { - mm.removeModel(URI_NONE); - } - - @Test - public void removeModelUnion() { - mm.removeModel(URI_UNION); - assertExpectedModelsList(URI_ONE, URI_TWO, URI_THREE); - } - - @Test - public void getModelActual() { - assertEquals(MODEL_ONE, mm.getModel(URI_ONE)); - } - - @Test - public void getModelNone() { - assertEquals(null, mm.getModel(URI_NONE)); - } - - @Test - public void getModelUnion() { - assertTrue(isUnionModel(mm.getModel(URI_UNION))); - } - - @Test - public void getModelLoadIfAbsentActual() { - assertEquals(MODEL_ONE, mm.getModel(URI_ONE, null)); - } - - @Test(expected = CannotCreateException.class) - public void getModelLoadIfAbsentNone() { - mm.getModel(URI_NONE, null); - } - - @Test - public void getModelLoadIfAbsentUnion() { - assertTrue(isUnionModel(mm.getModel(URI_UNION, null))); - } - - // ---------------------------------------------------------------------- - // Helper methods - // ---------------------------------------------------------------------- - - /** - * No easy way to assert that this is actually the union model, but we can - * assert that it is not null, and not any model we know of. - */ - private boolean isUnionModel(Model m) { - Model[] knownModels = { MODEL_ONE, MODEL_TWO, MODEL_THREE, - MODEL_DEFAULT, MODEL_FRESH }; - if (m == null) { - return false; - } - - for (Model knownModel : knownModels) { - if (m == knownModel) { - return false; - } - } - - return true; - } - - private void assertExpectedModelsList(String... uris) { - Set expected = new HashSet<>(Arrays.asList(uris)); - assertEquals(expected, mm.listModels().toSet()); - } - -} \ No newline at end of file diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameFieldsTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameFieldsTest.java new file mode 100644 index 000000000..d4e2767cf --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/NameFieldsTest.java @@ -0,0 +1,107 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.search.documentBuilding; + +import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_RAW; +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import stubs.edu.cornell.mannlib.vitro.webapp.beans.IndividualStub; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Statement; + +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument; +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.model.RDFServiceModel; +import edu.cornell.mannlib.vitro.webapp.searchengine.base.BaseSearchInputDocument; + +/** + * TODO NameFields should add the values as separate objects. + */ +public class NameFieldsTest { + private static final String INDIVIDUAL_URI = "http://mydomain.edu/individual/n3012"; + private static final String LABEL_PROPERTY_URI = "http://www.w3.org/2000/01/rdf-schema#label"; + private Model baseModel; + private NameFields nameFields; + private BaseSearchInputDocument doc; + + @Before + public void setup() { + baseModel = ModelFactory.createDefaultModel(); + + doc = new BaseSearchInputDocument(); + + RDFServiceModel rdfService = new RDFServiceModel(baseModel); + RDFServiceFactory rdfServiceFactory = new RDFServiceFactorySingle( + rdfService); + nameFields = new NameFields(rdfServiceFactory); + } + + @Test + public void nullIndividual() throws SkipIndividualException { + SearchInputDocument expected = new BaseSearchInputDocument(doc); + + assertResultingSearchDocument(null, expected); + } + + @Test + public void nullUri() throws SkipIndividualException { + SearchInputDocument expected = new BaseSearchInputDocument(doc); + + assertResultingSearchDocument(new IndividualStub(null), expected); + } + + @Test + public void foundNoLabels() throws SkipIndividualException { + SearchInputDocument expected = new BaseSearchInputDocument(doc); + expected.addField(NAME_RAW, ""); + + assertResultingSearchDocument(new IndividualStub(INDIVIDUAL_URI), + expected); + } + + @Test + public void foundOneLabel() throws SkipIndividualException { + baseModel.add(stmt(INDIVIDUAL_URI, LABEL_PROPERTY_URI, "label1")); + + SearchInputDocument expected = new BaseSearchInputDocument(doc); + expected.addField(NAME_RAW, "label1 "); + + assertResultingSearchDocument(new IndividualStub(INDIVIDUAL_URI), + expected); + } + + @Test + public void foundTwoLabels() throws SkipIndividualException { + baseModel.add(stmt(INDIVIDUAL_URI, LABEL_PROPERTY_URI, "label1")); + baseModel.add(stmt(INDIVIDUAL_URI, LABEL_PROPERTY_URI, "label2")); + + SearchInputDocument expected = new BaseSearchInputDocument(doc); + expected.addField(NAME_RAW, "label2 label1 "); + + assertResultingSearchDocument(new IndividualStub(INDIVIDUAL_URI), + expected); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private Statement stmt(String subjectUri, String propertyUri, String literal) { + return baseModel.createStatement(baseModel.createResource(subjectUri), + baseModel.createProperty(propertyUri), + baseModel.createLiteral(literal)); + } + + private void assertResultingSearchDocument(Individual ind, + SearchInputDocument expected) throws SkipIndividualException { + nameFields.modifyDocument(ind, doc); + assertEquals(expected, doc); + } +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ThumbnailImageURLTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ThumbnailImageURLTest.java index 1c963c99d..285152e8d 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ThumbnailImageURLTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/search/documentBuilding/ThumbnailImageURLTest.java @@ -29,8 +29,6 @@ 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.model.RDFServiceModel; import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames; -import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.SkipIndividualException; -import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.ThumbnailImageURL; public class ThumbnailImageURLTest extends AbstractTestClass{ RDFServiceFactory testRDF; @@ -62,11 +60,7 @@ public class ThumbnailImageURLTest extends AbstractTestClass{ ind.setURI(personsURI); //make sure that the person is in the RDF - try { - testMe.modifyDocument(ind, doc, null); - } catch (SkipIndividualException e) { - Assert.fail("Test individual was skipped by classes that build the search document: " + e.getMessage()); - } + testMe.modifyDocument(ind, doc); //make sure that a search document field got created for the thumbnail image diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputDocumentTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputDocumentTest.java new file mode 100644 index 000000000..9ff844e9c --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/searchengine/base/BaseSearchInputDocumentTest.java @@ -0,0 +1,56 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.searchengine.base; + +import static org.junit.Assert.*; + +import java.util.Collection; +import java.util.Map; + +import org.junit.Test; + +import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField; + +/** + * TODO + */ +public class BaseSearchInputDocumentTest { + /** + * The copy constructor should make a deep copy, down to (but not including) + * the field values. The component parts should be equal, but not the same. + */ + @Test + public void copyConstructor() { + BaseSearchInputDocument doc = new BaseSearchInputDocument(); + doc.setDocumentBoost(42.6F); + + SearchInputField field1 = new BaseSearchInputField("testField"); + field1.addValues("value1", "value2"); + field1.setBoost(1.1F); + doc.addField(field1); + + SearchInputField field2 = new BaseSearchInputField("anotherField"); + field2.setBoost(-16F); + doc.addField(field2); + + BaseSearchInputDocument other = new BaseSearchInputDocument(doc); + assertEquals(doc, other); + assertEquals(doc.getDocumentBoost(), other.getDocumentBoost(), 0.01F); + + Map docMap = doc.getFieldMap(); + Map otherMap = other.getFieldMap(); + assertEquals(docMap, otherMap); + assertNotSame(docMap, otherMap); + + for (String fieldName : docMap.keySet()) { + SearchInputField docField = doc.getField(fieldName); + SearchInputField otherField = other.getField(fieldName); + assertEquals(docField, otherField); + assertNotSame(docField, otherField); + + Collection docFieldValues = docField.getValues(); + Collection otherFieldValues = otherField.getValues(); + assertEquals(docFieldValues, otherFieldValues); + } + } +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoaderTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoaderTest.java new file mode 100644 index 000000000..a6b17e116 --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/utils/configuration/ConfigurationBeanLoaderTest.java @@ -0,0 +1,1106 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.configuration; + +import static com.hp.hpl.jena.datatypes.xsd.XSDDatatype.XSDfloat; +import static com.hp.hpl.jena.datatypes.xsd.XSDDatatype.XSDstring; +import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.dataProperty; +import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.model; +import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.objectProperty; +import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.typeStatement; +import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.toJavaUri; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; +import stubs.javax.servlet.ServletContextStub; +import stubs.javax.servlet.http.HttpServletRequestStub; +import stubs.javax.servlet.http.HttpSessionStub; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.Statement; + +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ModelAccessFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.RequestModelAccess; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationRdfParser.InvalidConfigurationRdfException; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.InstanceWrapper.InstanceWrapperException; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyTypeException; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.WrappedInstance.NoSuchPropertyMethodException; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.WrappedInstance.ResourceUnavailableException; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.WrappedInstance.ValidationFailedException; + +/** + * TODO + * + * Circularity prevention. Before setting properties, create a WeakMap of + * instances by URIs, so if a property refers to a created instance, we just + * pass it in. + */ +public class ConfigurationBeanLoaderTest extends AbstractTestClass { + private static final String GENERIC_INSTANCE_URI = "http://mytest.edu/some_instance"; + private static final String GENERIC_PROPERTY_URI = "http://mytest.edu/some_property"; + + private static final String SIMPLE_SUCCESS_INSTANCE_URI = "http://mytest.edu/simple_success_instance"; + + private static final String FULL_SUCCESS_INSTANCE_URI = "http://mytest.edu/full_success_instance"; + private static final String FULL_SUCCESS_BOOST_PROPERTY = "http://mydomain.edu/hasBoost"; + private static final String FULL_SUCCESS_TEXT_PROPERTY = "http://mydomain.edu/hasText"; + private static final String FULL_SUCCESS_HELPER_PROPERTY = "http://mydomain.edu/hasHelper"; + private static final String FULL_SUCCESS_HELPER_INSTANCE_URI = "http://mytest.edu/full_success_helper_instance"; + + private ServletContextStub ctx; + private HttpSessionStub session; + private HttpServletRequestStub req; + + private Model model; + + private ConfigurationBeanLoader loader; + private ConfigurationBeanLoader noRequestLoader; + private ConfigurationBeanLoader noContextLoader; + + @Before + public void setup() { + ctx = new ServletContextStub(); + + session = new HttpSessionStub(); + session.setServletContext(ctx); + + req = new HttpServletRequestStub(); + req.setSession(session); + + @SuppressWarnings("unused") + ModelAccessFactory maf = new ModelAccessFactoryStub(); + + model = model(); + + loader = new ConfigurationBeanLoader(model, req); + noRequestLoader = new ConfigurationBeanLoader(model, ctx); + noContextLoader = new ConfigurationBeanLoader(model); + } + + // ---------------------------------------------------------------------- + // Constructor tests + // ---------------------------------------------------------------------- + + @Test + public void constructor_modelIsNull_throwsException() { + expectException(NullPointerException.class, "model may not be null"); + + @SuppressWarnings("unused") + Object unused = new ConfigurationBeanLoader(null); + } + + // ---------------------------------------------------------------------- + // loadInstance() failures + // ---------------------------------------------------------------------- + + @Test + public void loadInstance_uriIsNull_throwsException() + throws ConfigurationBeanLoaderException { + expectException(NullPointerException.class, "uri may not be null"); + + @SuppressWarnings("unused") + Object unused = loader.loadInstance(null, SimpleSuccess.class); + } + + @Test + public void load_instance_resultClassIsNull_throwsException() + throws ConfigurationBeanLoaderException { + expectException(NullPointerException.class, + "resultClass may not be null"); + + @SuppressWarnings("unused") + Object unused = loader.loadInstance(GENERIC_INSTANCE_URI, null); + } + + @Test + public void noStatementsAboutUri_throwsException() + throws ConfigurationBeanLoaderException { + expectSimpleFailure( + SimpleSuccess.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InvalidConfigurationRdfException.class, + "The model contains no statements about")); + } + + @Test + public void uriDoesNotDeclareResultClassAsType_throwsException() + throws ConfigurationBeanLoaderException { + model.add(dataProperty(GENERIC_INSTANCE_URI, + "http://some.simple/property", "a value")); + + expectSimpleFailure( + SimpleSuccess.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InvalidConfigurationRdfException.class, + "A type statement is required")); + } + + // -------------------------------------------- + + @Test + public void uriHasNoConcreteType_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(SimpleInterfaceFailure.class))); + + expectSimpleFailure( + SimpleInterfaceFailure.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InvalidConfigurationRdfException.class, + "No concrete class is declared")); + } + + public static interface SimpleInterfaceFailure { + // This is not concrete, and there is no concrete implementation. + } + + // -------------------------------------------- + + @Test + public void uriHasMultipleConcreteTypes_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(SimpleSuccess.class))); + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(SecondConcreteClass.class))); + + expectSimpleFailure( + SimpleSuccess.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InvalidConfigurationRdfException.class, + "more than one concrete class")); + } + + public static class SecondConcreteClass extends SimpleSuccess { + // Since this and SimpleSuccessClass are both concrete, they may not be + // used together. + } + + // -------------------------------------------- + + @Test + public void cantLoadConcreteType_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(UnloadableClass.class))); + + expectSimpleFailure( + UnloadableClass.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InvalidConfigurationRdfException.class, + "Can't load this type")); + } + + public static class UnloadableClass { + static { + if (true) { + throw new IllegalStateException("This class cannot be loaded."); + } + } + } + + // -------------------------------------------- + + @Test + public void concreteTypeNotAssignableToResultClass_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(SimpleSuccess.class))); + model.add(typeStatement(GENERIC_INSTANCE_URI, toJavaUri(String.class))); + + expectSimpleFailure( + SimpleSuccess.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InvalidConfigurationRdfException.class, + "cannot be assigned to class")); + } + + // -------------------------------------------- + + @Test + public void noNiladicConstructor_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(NoNiladicConstructor.class))); + + expectSimpleFailure( + NoNiladicConstructor.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InvalidConfigurationRdfException.class, + "no zero-argument constructor.")); + } + + public static class NoNiladicConstructor { + @SuppressWarnings("unused") + public NoNiladicConstructor(String s) { + // Not suitable as a bean + } + } + + // -------------------------------------------- + + @Test + public void niladicConstructorNotAccessible_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(PrivateConstructor.class))); + + expectSimpleFailure( + PrivateConstructor.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InvalidConfigurationRdfException.class, + "no zero-argument constructor.")); + } + + public static class PrivateConstructor { + private PrivateConstructor() { + // Can't access the constructor. + } + } + + // -------------------------------------------- + + @Test + public void constructorThrowsException_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(ConstructorFails.class))); + + expectSimpleFailure( + ConstructorFails.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InstanceWrapperException.class, + "Failed to create an instance.")); + } + + public static class ConstructorFails { + public ConstructorFails() { + if (true) { + throw new IllegalStateException( + "The constructor throws an exception."); + } + } + } + + // -------------------------------------------- + + @Test + public void propertyMethodHasNoParameter_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(NoParameterOnPropertyMethod.class))); + + expectSimpleFailure( + NoParameterOnPropertyMethod.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InstanceWrapperException.class, + "must accept exactly one parameter")); + } + + public static class NoParameterOnPropertyMethod { + @Property(uri = GENERIC_PROPERTY_URI) + public void methodTakesNoParameters() { + // Not suitable as a property method. + } + } + + // -------------------------------------------- + + @Test + public void propertyMethodHasMultipleParameters_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(MultipleParametersOnPropertyMethod.class))); + + expectSimpleFailure( + MultipleParametersOnPropertyMethod.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InstanceWrapperException.class, + "must accept exactly one parameter")); + } + + public static class MultipleParametersOnPropertyMethod { + @SuppressWarnings("unused") + @Property(uri = GENERIC_PROPERTY_URI) + public void methodTakesMultipleParameters(String s, Float f) { + // Not suitable as a property method. + } + } + + // -------------------------------------------- + + @Test + public void propertyMethodHasInvalidParameter_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(InvalidParameterOnPropertyMethod.class))); + + expectSimpleFailure( + InvalidParameterOnPropertyMethod.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InstanceWrapperException.class, + "Failed to create the PropertyMethod")); + } + + public static class InvalidParameterOnPropertyMethod { + @SuppressWarnings("unused") + @Property(uri = GENERIC_PROPERTY_URI) + public void methodTakesInvalidParameters(byte b) { + // Not suitable as a property method. + } + } + + // -------------------------------------------- + + @Test + public void propertyMethodDoesNotReturnVoid_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(PropertyMethodMustReturnVoid.class))); + + expectSimpleFailure( + PropertyMethodMustReturnVoid.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InstanceWrapperException.class, "should return void")); + } + + public static class PropertyMethodMustReturnVoid { + @Property(uri = GENERIC_PROPERTY_URI) + public String methodReturnIsNotVoid(String s) { + // Not suitable as a property method. + return s; + } + } + + // -------------------------------------------- + + @Test + public void propertyMethodNotAccessible_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(PropertyMethodIsPrivate.class))); + model.add(dataProperty(GENERIC_INSTANCE_URI, GENERIC_PROPERTY_URI, + "can't store in a private method.")); + + expectSimpleFailure( + PropertyMethodIsPrivate.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(PropertyTypeException.class, + "Property method failed.")); + } + + public static class PropertyMethodIsPrivate { + @SuppressWarnings("unused") + @Property(uri = GENERIC_PROPERTY_URI) + private void methodReturnIsNotVoid(String s) { + // Not suitable as a property method. + } + } + + // -------------------------------------------- + + @Test + public void propertyMethodThrowsException_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(PropertyMethodFails.class))); + model.add(dataProperty(GENERIC_INSTANCE_URI, GENERIC_PROPERTY_URI, + "exception while loading.")); + + expectSimpleFailure( + PropertyMethodFails.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(PropertyTypeException.class, + "Property method failed.")); + } + + public static class PropertyMethodFails { + @SuppressWarnings("unused") + @Property(uri = GENERIC_PROPERTY_URI) + public void methodThrowsException(String s) { + if (true) { + throw new RuntimeException("property method fails."); + } + } + } + + // -------------------------------------------- + + @Test + public void propertyMethodDuplicateUri_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(TwoMethodsWithSameUri.class))); + + expectSimpleFailure( + TwoMethodsWithSameUri.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InstanceWrapperException.class, + "methods have the same URI")); + } + + public static class TwoMethodsWithSameUri { + @SuppressWarnings("unused") + @Property(uri = GENERIC_PROPERTY_URI) + public void firstProperty(String s) { + // Nothing to do + } + + @SuppressWarnings("unused") + @Property(uri = GENERIC_PROPERTY_URI) + public void secondProperty(String s) { + // Nothing to do + } + } + + // -------------------------------------------- + + @Test + public void validationMethodHasParameters_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(ValidationMethodWithParameter.class))); + + expectSimpleFailure( + ValidationMethodWithParameter.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InstanceWrapperException.class, + "should not have parameters")); + } + + public static class ValidationMethodWithParameter { + @SuppressWarnings("unused") + @Validation + public void validateWithParameter(String s) { + // Nothing to do + } + } + + // -------------------------------------------- + + @Test + public void validationMethodDoesNotReturnVoid_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(ValidationMethodShouldReturnVoid.class))); + + expectSimpleFailure( + ValidationMethodShouldReturnVoid.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(InstanceWrapperException.class, "should return void")); + } + + public static class ValidationMethodShouldReturnVoid { + @Validation + public String validateWithReturnType() { + return "Hi there!"; + } + } + + // -------------------------------------------- + + @Test + public void validationMethodNotAccessible_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(ValidationMethodIsPrivate.class))); + + expectSimpleFailure( + ValidationMethodIsPrivate.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(ValidationFailedException.class, + "Error executing validation method")); + } + + public static class ValidationMethodIsPrivate { + @Validation + private void validateIsPrivate() { + // private method + } + } + + // -------------------------------------------- + + @Test + public void validationMethodThrowsException_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(ValidationThrowsException.class))); + + expectSimpleFailure( + ValidationThrowsException.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(ValidationFailedException.class, + "Error executing validation method")); + } + + public static class ValidationThrowsException { + @Validation + public void validateFails() { + throw new RuntimeException("from validation method"); + } + } + + // -------------------------------------------- + + @Test + public void loaderCantSatisfyContextModelsUser_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(NeedsContextModels.class))); + + loader = noContextLoader; + + expectSimpleFailure( + NeedsContextModels.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(ResourceUnavailableException.class, + "Cannot satisfy ContextModelsUser")); + } + + public static class NeedsContextModels implements ContextModelsUser { + @Override + public void setContextModels(ContextModelAccess models) { + // Nothing to do + } + } + + // -------------------------------------------- + + @Test + public void loaderCantSatisfyRequestModelsUser_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(NeedsRequestModels.class))); + + loader = noRequestLoader; + + expectSimpleFailure( + NeedsRequestModels.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(ResourceUnavailableException.class, + "Cannot satisfy RequestModelsUser")); + } + + public static class NeedsRequestModels implements RequestModelsUser { + @Override + public void setRequestModels(RequestModelAccess models) { + // Nothing to do + } + } + + // -------------------------------------------- + + @Test + public void tripleHasUnrecognizedProperty_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(SimpleSuccess.class))); + model.add(dataProperty(GENERIC_INSTANCE_URI, + "http://bogus.property/name", "No place to put it.")); + + expectSimpleFailure( + SimpleSuccess.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(NoSuchPropertyMethodException.class, + "No property method")); + } + + // -------------------------------------------- + + @Test + public void valueTypeDoesNotMatchArgumentOfPropertyMethod_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(ExpectingAString.class))); + model.add(objectProperty(GENERIC_INSTANCE_URI, GENERIC_PROPERTY_URI, + "http://some.other/uri")); + + expectSimpleFailure( + ExpectingAString.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(PropertyTypeException.class, + "type RESOURCE to a method of type STRING")); + } + + public static class ExpectingAString { + @SuppressWarnings("unused") + @Property(uri = GENERIC_PROPERTY_URI) + public void setString(String s) { + // Nothing to do + } + } + + // -------------------------------------------- + + @Test + public void subordinateObjectCantBeLoaded_throwsException() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(NoSuchSubordinateInstance.class))); + model.add(objectProperty(GENERIC_INSTANCE_URI, GENERIC_PROPERTY_URI, + "http://some.other/uri")); + + expectSimpleFailure( + NoSuchSubordinateInstance.class, + throwable(ConfigurationBeanLoaderException.class, + "Failed to load"), + throwable(ConfigurationBeanLoaderException.class, + "Failed to load")); + } + + public static class NoSuchSubordinateInstance { + @SuppressWarnings("unused") + @Property(uri = GENERIC_PROPERTY_URI) + public void setHelper(SimpleDateFormat sdf) { + // Nothing to do + } + } + + // ---------------------------------------------------------------------- + // loadInstance() successes + // ---------------------------------------------------------------------- + + /** + * Has a concrete result class. + */ + @Test + public void simpleSuccess() throws ConfigurationBeanLoaderException { + model.add(typeStatement(SIMPLE_SUCCESS_INSTANCE_URI, + toJavaUri(SimpleSuccess.class))); + + SimpleSuccess instance = loader.loadInstance( + SIMPLE_SUCCESS_INSTANCE_URI, SimpleSuccess.class); + + assertNotNull(instance); + } + + public static class SimpleSuccess { + // Nothing of interest. + } + + // -------------------------------------------- + + /** + * Exercise the full repertoire: properties of all types, validation + * methods. Result class is an interface; result class of helper is + * abstract. + */ + @Test + public void fullSuccess() throws ConfigurationBeanLoaderException { + model.add(FULL_SUCCESS_STATEMENTS); + + FullSuccessResultClass instance = loader.loadInstance( + FULL_SUCCESS_INSTANCE_URI, FullSuccessResultClass.class); + + assertNotNull(instance); + + HashSet expectedTextValues = new HashSet<>( + Arrays.asList(new String[] { "Huey", "Dewey", "Louis" })); + assertEquals(expectedTextValues, instance.getTextValues()); + + HashSet expectedBoostValues = new HashSet<>( + Arrays.asList(new Float[] { 1.5F, -99F })); + assertEquals(expectedBoostValues, instance.getBoostValues()); + + assertEquals(1, instance.getHelpers().size()); + assertTrue(instance.isValidated()); + } + + public static interface FullSuccessResultClass { + Set getTextValues(); + + Set getBoostValues(); + + Set getHelpers(); + + boolean isValidated(); + } + + public static class FullSuccessConcreteClass implements + FullSuccessResultClass { + private Set textValues = new HashSet<>(); + private Set boostValues = new HashSet<>(); + private Set helpers = new HashSet<>(); + + private boolean validatorOneHasRun; + private boolean validatorTwoHasRun; + + @Property(uri = FULL_SUCCESS_TEXT_PROPERTY) + public void addText(String text) { + textValues.add(text); + } + + @Property(uri = FULL_SUCCESS_BOOST_PROPERTY) + public void addBoost(float boost) { + boostValues.add(boost); + } + + @Property(uri = FULL_SUCCESS_HELPER_PROPERTY) + public void addHelper(FullSuccessHelperResultClass helper) { + helpers.add(helper); + } + + @Validation + public void validatorOne() { + if (validatorOneHasRun) { + throw new RuntimeException("validatorOne has already run."); + } + validatorOneHasRun = true; + } + + @Validation + public void validatorTwo() { + if (validatorTwoHasRun) { + throw new RuntimeException("validatorTwo has already run."); + } + validatorTwoHasRun = true; + } + + @Override + public Set getTextValues() { + return textValues; + } + + @Override + public Set getBoostValues() { + return boostValues; + } + + @Override + public Set getHelpers() { + return helpers; + } + + @Override + public boolean isValidated() { + return validatorOneHasRun && validatorTwoHasRun; + } + + } + + public static abstract class FullSuccessHelperResultClass { + // Abstract class, with concrete subclass. + } + + public static class FullSuccessHelperConcreteClass extends + FullSuccessHelperResultClass { + // No properties + } + + private static final Statement[] FULL_SUCCESS_STATEMENTS = new Statement[] { + // Create the instance itself. + typeStatement(FULL_SUCCESS_INSTANCE_URI, + toJavaUri(FullSuccessResultClass.class)), + typeStatement(FULL_SUCCESS_INSTANCE_URI, + toJavaUri(FullSuccessConcreteClass.class)), + + // Add some boost values. + dataProperty(FULL_SUCCESS_INSTANCE_URI, + FULL_SUCCESS_BOOST_PROPERTY, 1.5F, XSDfloat), + dataProperty(FULL_SUCCESS_INSTANCE_URI, + FULL_SUCCESS_BOOST_PROPERTY, -99F, XSDfloat), + + // Add some text values: plain, typed, language + dataProperty(FULL_SUCCESS_INSTANCE_URI, FULL_SUCCESS_TEXT_PROPERTY, + "Huey", XSDstring), + dataProperty(FULL_SUCCESS_INSTANCE_URI, FULL_SUCCESS_TEXT_PROPERTY, + "Dewey", "en-US"), + dataProperty(FULL_SUCCESS_INSTANCE_URI, FULL_SUCCESS_TEXT_PROPERTY, + "Louis"), + + // Add a subordinate object. + objectProperty(FULL_SUCCESS_INSTANCE_URI, + FULL_SUCCESS_HELPER_PROPERTY, + FULL_SUCCESS_HELPER_INSTANCE_URI), + typeStatement(FULL_SUCCESS_HELPER_INSTANCE_URI, + toJavaUri(FullSuccessHelperResultClass.class)), + typeStatement(FULL_SUCCESS_HELPER_INSTANCE_URI, + toJavaUri(FullSuccessHelperConcreteClass.class)) }; + + // -------------------------------------------- + + @Test + public void irrelevantNonConcreteTypesAreIgnored() + throws ConfigurationBeanLoaderException { + model.add(new Statement[] { + typeStatement(SIMPLE_SUCCESS_INSTANCE_URI, + toJavaUri(SimpleSuccess.class)), + typeStatement(SIMPLE_SUCCESS_INSTANCE_URI, + toJavaUri(IrrelevantInterface.class)), + typeStatement(SIMPLE_SUCCESS_INSTANCE_URI, + toJavaUri(IrrelevantAbstractClass.class)), + typeStatement(SIMPLE_SUCCESS_INSTANCE_URI, + "http://irrelevant.nonJava/class") }); + + SimpleSuccess instance = loader.loadInstance( + SIMPLE_SUCCESS_INSTANCE_URI, SimpleSuccess.class); + + assertNotNull(instance); + } + + public interface IrrelevantInterface { + // Nothing of interest. + } + + public abstract class IrrelevantAbstractClass { + // Nothing of interest. + } + + // -------------------------------------------- + + @Test + public void loaderHasNoRequestButClassDoesntRequireIt_success() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(SIMPLE_SUCCESS_INSTANCE_URI, + toJavaUri(SimpleSuccess.class))); + + loader = noRequestLoader; + + SimpleSuccess instance = loader.loadInstance( + SIMPLE_SUCCESS_INSTANCE_URI, SimpleSuccess.class); + + assertNotNull(instance); + } + + // -------------------------------------------- + + @Test + public void loaderHasNoContextButClassDoesntRequireIt_success() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(SIMPLE_SUCCESS_INSTANCE_URI, + toJavaUri(SimpleSuccess.class))); + + loader = noContextLoader; + + SimpleSuccess instance = loader.loadInstance( + SIMPLE_SUCCESS_INSTANCE_URI, SimpleSuccess.class); + + assertNotNull(instance); + } + + // -------------------------------------------- + + /** + * FullSuccess already tests for multiple validation methods. + * + * SimpleSuccess already test for no validation methods, and for no property + * methods. + */ + @Test + public void noValuesForProperty_success() + throws ConfigurationBeanLoaderException { + model.add(new Statement[] { + typeStatement(FULL_SUCCESS_INSTANCE_URI, + toJavaUri(FullSuccessConcreteClass.class)), + typeStatement(FULL_SUCCESS_INSTANCE_URI, + toJavaUri(FullSuccessResultClass.class)) }); + + FullSuccessResultClass instance = loader.loadInstance( + FULL_SUCCESS_INSTANCE_URI, FullSuccessResultClass.class); + + assertNotNull(instance); + assertEquals(Collections.emptySet(), instance.getTextValues()); + assertEquals(Collections.emptySet(), instance.getBoostValues()); + assertEquals(Collections.emptySet(), instance.getHelpers()); + assertTrue(instance.isValidated()); + } + + // ---------------------------------------------------------------------- + // loadAll() failures + // ---------------------------------------------------------------------- + + @Test + public void loadAll_oneObjectCantBeLoaded_throwsException() + throws ConfigurationBeanLoaderException { + model.add(new Statement[] { + typeStatement("http://apple/good", + toJavaUri(OneBadAppleSpoilsTheBunch.class)), + typeStatement("http://apple/good", toJavaUri(AGoodApple.class)), + typeStatement("http://apple/bad", + toJavaUri(OneBadAppleSpoilsTheBunch.class)) }); + + expectException(ConfigurationBeanLoaderException.class, + "Failed to load", InvalidConfigurationRdfException.class, + "No concrete class is declared"); + + loader.loadAll(OneBadAppleSpoilsTheBunch.class); + } + + public interface OneBadAppleSpoilsTheBunch { + // Nothing. + } + + public class AGoodApple implements OneBadAppleSpoilsTheBunch { + // Nothing + } + + // ---------------------------------------------------------------------- + // loadAll() successes + // ---------------------------------------------------------------------- + + @Test + public void loadAll_noResults_success() + throws ConfigurationBeanLoaderException { + Set instances = loader.loadAll(SimpleSuccess.class); + assertTrue(instances.isEmpty()); + } + + // -------------------------------------------- + + @Test + public void loadAll_oneResult_success() + throws ConfigurationBeanLoaderException { + model.add(typeStatement(GENERIC_INSTANCE_URI, + toJavaUri(SimpleSuccess.class))); + + Set instances = loader.loadAll(SimpleSuccess.class); + assertEquals(1, instances.size()); + } + + // -------------------------------------------- + + @Test + public void loadAll_multipleResults_success() + throws ConfigurationBeanLoaderException { + model.add(new Statement[] { + typeStatement("http://simple.instance/one", + toJavaUri(InstanceWithProperty.class)), + dataProperty("http://simple.instance/one", + "http://simple.text/property", "FIRST"), + typeStatement("http://simple.instance/two", + toJavaUri(InstanceWithProperty.class)), + dataProperty("http://simple.instance/two", + "http://simple.text/property", "SECOND") }); + + Set instances = loader + .loadAll(InstanceWithProperty.class); + assertEquals(2, instances.size()); + + Set textValues = new HashSet<>(); + for (InstanceWithProperty instance : instances) { + textValues.add(instance.getText()); + } + assertEquals(new HashSet<>(Arrays.asList("FIRST", "SECOND")), + textValues); + } + + public static class InstanceWithProperty { + private String text; + + @Property(uri = "http://simple.text/property") + public void setText(String text) { + this.text = text; + } + + public String getText() { + return text; + } + } + + // ---------------------------------------------------------------------- + // Additional tests + // ---------------------------------------------------------------------- + + @Test + @Ignore + // TODO + public void circularReferencesAreNotFatal() + throws ConfigurationBeanLoaderException { + fail("circularReferencesAreNotFatal not implemented"); + } + + @Test + @Ignore + // TODO deals with circularity. + public void subordinateObjectCantBeLoaded_leavesNoAccessibleInstanceOfParent() + throws ConfigurationBeanLoaderException { + fail("subordinateObjectCantBeLoaded_leavesNoAccessibleInstanceOfParent not implemented"); + } + + @Test + @Ignore + // TODO deals with circularity. + public void parentObjectCantBeLoaded_leavesNoAccessibleInstanceOfSubordinate() + throws ConfigurationBeanLoaderException { + fail("parentObjectCantBeLoaded_leavesNoAccessibleInstanceOfSubordinate not implemented"); + } + + // ---------------------------------------------------------------------- + // Helper methods for simple failure + // ---------------------------------------------------------------------- + + private void expectSimpleFailure(Class failureClass, + ExpectedThrowable expected, ExpectedThrowable cause) + throws ConfigurationBeanLoaderException { + expectException(expected.getClazz(), expected.getMessageSubstring(), + cause.getClazz(), cause.getMessageSubstring()); + + @SuppressWarnings("unused") + Object unused = loader.loadInstance(GENERIC_INSTANCE_URI, failureClass); + } + + private ExpectedThrowable throwable(Class clazz, + String messageSubstring) { + return new ExpectedThrowable(clazz, messageSubstring); + } + + private static class ExpectedThrowable { + private final Class clazz; + private final String messageSubstring; + + public ExpectedThrowable(Class clazz, + String messageSubstring) { + this.clazz = clazz; + this.messageSubstring = messageSubstring; + } + + public Class getClazz() { + return clazz; + } + + public String getMessageSubstring() { + return messageSubstring; + } + } + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel_PropertyListConfigTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel_PropertyListConfigTest.java index 8e123cf3e..7e608b44e 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel_PropertyListConfigTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel_PropertyListConfigTest.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.ASSERTIONS_AND_INFERENCES; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; @@ -27,6 +29,7 @@ import org.junit.rules.ExpectedException; import stubs.edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; import stubs.freemarker.cache.TemplateLoaderStub; import stubs.javax.servlet.ServletContextStub; import stubs.javax.servlet.http.HttpServletRequestStub; @@ -41,9 +44,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.PropertyListConfig; import freemarker.cache.TemplateLoader; @@ -70,6 +71,8 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends private TemplateLoaderStub tl; private StringWriter logMessages; + + private ModelAccessFactoryStub mafs; /** * In general, we expect no exception, but individual tests may override, @@ -130,7 +133,9 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends hreq.setSession(session); vreq = new VitroRequest(hreq); - ModelAccess.on(vreq).setWebappDaoFactory(wadf); + + mafs = new ModelAccessFactoryStub(); + mafs.get(vreq).setWebappDaoFactory(wadf, ASSERTIONS_AND_INFERENCES); subject = new IndividualImpl(); @@ -280,7 +285,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends @Test public void constructQueryNodeMissing() throws InvalidConfigurationException { - ModelAccess.on(vreq).setOntModel(ModelNames.FULL_UNION, emptyOntModel()); + mafs.get(vreq).setOntModel(emptyOntModel(), FULL_UNION); op = buildOperation("constructQueryMissing"); optm = new NonCollatingOPTM(op, subject, vreq, true); // Not an error. @@ -289,7 +294,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends @Test public void constructQueryMultipleValues() throws InvalidConfigurationException { - ModelAccess.on(vreq).setOntModel(ModelNames.FULL_UNION, emptyOntModel()); + mafs.get(vreq).setOntModel(emptyOntModel(), FULL_UNION); op = buildOperation("constructQueryMultiple"); optm = new NonCollatingOPTM(op, subject, vreq, true); assertConstructQueries("multiple construct queries", "ONE", "TWO", diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/modelaccess/ContextModelAccessStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/modelaccess/ContextModelAccessStub.java new file mode 100644 index 000000000..1ab169f23 --- /dev/null +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/modelaccess/ContextModelAccessStub.java @@ -0,0 +1,122 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package stubs.edu.cornell.mannlib.vitro.webapp.modelaccess; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.ASSERTIONS_AND_INFERENCES; + +import java.util.HashMap; +import java.util.Map; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelMaker; + +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +/** + * A mock instance of ContextModelAccess for use in unit tests. + * + * I have only implemented the methods that I needed for my tests. Feel free to + * implement the rest, as needed. + */ +public class ContextModelAccessStub implements ContextModelAccess { + // ---------------------------------------------------------------------- + // Stub infrastructure + // ---------------------------------------------------------------------- + + private final Map wadfMap = new HashMap<>(); + + public void setWebappDaoFactory(WebappDaoFactory wadf) { + setWebappDaoFactory(wadf, ASSERTIONS_AND_INFERENCES); + } + + public void setWebappDaoFactory(WebappDaoFactory wadf, + ReasoningOption option) { + wadfMap.put(option, wadf); + } + + // ---------------------------------------------------------------------- + // Stub methods + // ---------------------------------------------------------------------- + + @Override + public WebappDaoFactory getWebappDaoFactory() { + return wadfMap.get(ASSERTIONS_AND_INFERENCES); + } + + // ---------------------------------------------------------------------- + // Un-implemented methods + // ---------------------------------------------------------------------- + + @Override + public RDFService getRDFService() { + throw new RuntimeException( + "ContextModelAccessStub.getRDFService() not implemented."); + } + + @Override + public RDFService getRDFService(WhichService which) { + throw new RuntimeException( + "ContextModelAccessStub.getRDFService() not implemented."); + } + + @Override + public Dataset getDataset() { + throw new RuntimeException( + "ContextModelAccessStub.getDataset() not implemented."); + } + + @Override + public Dataset getDataset(WhichService which) { + throw new RuntimeException( + "ContextModelAccessStub.getDataset() not implemented."); + } + + @Override + public ModelMaker getModelMaker() { + throw new RuntimeException( + "ContextModelAccessStub.getModelMaker() not implemented."); + } + + @Override + public ModelMaker getModelMaker(WhichService which) { + throw new RuntimeException( + "ContextModelAccessStub.getModelMaker() not implemented."); + } + + @Override + public OntModel getOntModel() { + throw new RuntimeException( + "ContextModelAccessStub.getOntModel() not implemented."); + } + + @Override + public OntModel getOntModel(String name) { + throw new RuntimeException( + "ContextModelAccessStub.getOntModel() not implemented."); + } + + @Override + public OntModelSelector getOntModelSelector() { + throw new RuntimeException( + "ContextModelAccessStub.getOntModelSelector() not implemented."); + } + + @Override + public OntModelSelector getOntModelSelector(ReasoningOption option) { + throw new RuntimeException( + "ContextModelAccessStub.getOntModelSelector() not implemented."); + } + + @Override + public WebappDaoFactory getWebappDaoFactory(ReasoningOption option) { + throw new RuntimeException( + "ContextModelAccessStub.getWebappDaoFactory() not implemented."); + } + +} diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelAccessFactoryStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelAccessFactoryStub.java new file mode 100644 index 000000000..bdee3b0fe --- /dev/null +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/modelaccess/ModelAccessFactoryStub.java @@ -0,0 +1,57 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package stubs.edu.cornell.mannlib.vitro.webapp.modelaccess; + +import java.lang.reflect.Field; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ModelAccessFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.RequestModelAccess; + +/** + * A mock instance of ModelAccessFactory for use in unit tests. + * + * I have only implemented the methods that I needed for my tests. Feel free to + * implement the rest, as needed. + */ +public class ModelAccessFactoryStub extends ModelAccessFactory { + private final ContextModelAccessStub contextMA; + private final RequestModelAccessStub requestMA; + + public ModelAccessFactoryStub() { + try { + Field factoryField = ModelAccess.class.getDeclaredField("factory"); + factoryField.setAccessible(true); + factoryField.set(null, this); + } catch (NoSuchFieldException | SecurityException + | IllegalArgumentException | IllegalAccessException e) { + throw new RuntimeException( + "Failed to create the ModelAccessFactoryStub", e); + } + + contextMA = new ContextModelAccessStub(); + requestMA = new RequestModelAccessStub(); + } + + @Override + public ContextModelAccess buildContextModelAccess(ServletContext ctx) { + return contextMA; + } + + @Override + public RequestModelAccess buildRequestModelAccess(HttpServletRequest req) { + return requestMA; + } + + public ContextModelAccessStub get(ServletContext ctx) { + return contextMA; + } + + public RequestModelAccessStub get(HttpServletRequest req) { + return requestMA; + } +} diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/modelaccess/RequestModelAccessStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/modelaccess/RequestModelAccessStub.java new file mode 100644 index 000000000..00ac671c7 --- /dev/null +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/modelaccess/RequestModelAccessStub.java @@ -0,0 +1,104 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package stubs.edu.cornell.mannlib.vitro.webapp.modelaccess; + +import java.util.HashMap; +import java.util.Map; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Dataset; + +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.DatasetOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.OntModelSelectorOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.RdfServiceOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WebappDaoFactoryOption; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.modelaccess.RequestModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys.OntModelKey; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys.RDFServiceKey; +import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.keys.WebappDaoFactoryKey; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +/** + * A mock instance of RequestModelAccess for use in unit tests. + * + * I have only implemented the methods that I needed for my tests. Feel free to + * implement the rest, as needed. + */ +public class RequestModelAccessStub implements RequestModelAccess { + // ---------------------------------------------------------------------- + // Stub infrastructure + // ---------------------------------------------------------------------- + + private final Map rdfServiceMap = new HashMap<>(); + + public void setRDFService(RDFService rdfService, + RdfServiceOption... options) { + rdfServiceMap.put(new RDFServiceKey(options), rdfService); + } + + private final Map ontModelMap = new HashMap<>(); + + public void setOntModel(OntModel model, String name) { + ontModelMap.put(new OntModelKey(name), model); + } + + private final Map wadfMap = new HashMap<>(); + + public void setWebappDaoFactory(WebappDaoFactory wadf, + WebappDaoFactoryOption... options) { + wadfMap.put(new WebappDaoFactoryKey(options), wadf); + } + + // ---------------------------------------------------------------------- + // Stub methods + // ---------------------------------------------------------------------- + + @Override + public RDFService getRDFService(RdfServiceOption... options) { + return rdfServiceMap.get(new RDFServiceKey(options)); + } + + @Override + public OntModel getOntModel(LanguageOption... options) { + return getOntModel(ModelNames.FULL_UNION, options); + } + + @Override + public OntModel getOntModel(String name, LanguageOption... options) { + return ontModelMap.get(new OntModelKey(name, options)); + } + + @Override + public WebappDaoFactory getWebappDaoFactory( + WebappDaoFactoryOption... options) { + return wadfMap.get(new WebappDaoFactoryKey(options)); + } + + // ---------------------------------------------------------------------- + // Un-implemented methods + // ---------------------------------------------------------------------- + + @Override + public Dataset getDataset(DatasetOption... options) { + throw new RuntimeException( + "RequestModelAccessStub.getDataset() not implemented."); + } + + @Override + public OntModelSelector getOntModelSelector( + OntModelSelectorOption... options) { + throw new RuntimeException( + "RequestModelAccessStub.getOntModelSelector() not implemented."); + } + + @Override + public void close() { + throw new RuntimeException( + "RequestModelAccessStub.close() not implemented."); + } + +} diff --git a/webapp/web/admin/conceptRepair.jsp b/webapp/web/admin/conceptRepair.jsp index 301b105e3..1d18a48fd 100644 --- a/webapp/web/admin/conceptRepair.jsp +++ b/webapp/web/admin/conceptRepair.jsp @@ -3,7 +3,8 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page import="edu.cornell.mannlib.vitro.webapp.controller.Controllers" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> +<%@ page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess"%> +<%@ page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames"%> <%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %> <%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %> @@ -22,7 +23,7 @@ " FILTER(afn:bnode(?bnode) = \"" + conceptIdStr + "\")\n" + "}"; - OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(ModelNames.FULL_ASSERTIONS); Model conceptDescription = ModelFactory.createDefaultModel(); try { ontModel.enterCriticalSection(Lock.READ); diff --git a/webapp/web/admin/removeBadRestrictions.jsp b/webapp/web/admin/removeBadRestrictions.jsp index 18e8e78d8..af3a03bcf 100644 --- a/webapp/web/admin/removeBadRestrictions.jsp +++ b/webapp/web/admin/removeBadRestrictions.jsp @@ -4,13 +4,15 @@ <%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %> <%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %> -<%@page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> +<%@page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess"%> +<%@page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames"%> + <% request.setAttribute("requestedActions", SimplePermission.USE_MISCELLANEOUS_CURATOR_PAGES.ACTION); %> <% if (request.getParameter("execute") != null) { - OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(ModelNames.FULL_ASSERTIONS); int results = doRemoval(ontModel); request.setAttribute("removalCount", results); } @@ -67,7 +69,7 @@ " FILTER(afn:bnode(?bnode) = \"" + bnodeId + "\")\n" + "}"; - OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(ModelNames.FULL_ASSERTIONS); Model conceptDescription = ModelFactory.createDefaultModel(); try { ontModel.enterCriticalSection(Lock.READ); diff --git a/webapp/web/admin/removeResourceDescription.jsp b/webapp/web/admin/removeResourceDescription.jsp index 874e1f0cb..276eb713e 100644 --- a/webapp/web/admin/removeResourceDescription.jsp +++ b/webapp/web/admin/removeResourceDescription.jsp @@ -6,7 +6,8 @@ <%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %> <%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %> -<%@page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> +<%@page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess"%> +<%@page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames"%> <% request.setAttribute("requestedActions", SimplePermission.USE_MISCELLANEOUS_CURATOR_PAGES.ACTION); %> @@ -17,7 +18,7 @@ String describeQueryStr = "DESCRIBE <" + resourceURIStr + ">"; - OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); + OntModel ontModel = ModelAccess.on(getServletContext()).getOntModel(ModelNames.FULL_ASSERTIONS); Model resourceDescription = ModelFactory.createDefaultModel(); try { ontModel.enterCriticalSection(Lock.READ); diff --git a/webapp/web/admin/sparql.jsp b/webapp/web/admin/sparql.jsp index f1671ea9f..2ecc3f58d 100644 --- a/webapp/web/admin/sparql.jsp +++ b/webapp/web/admin/sparql.jsp @@ -1,8 +1,8 @@ <%@page import="com.hp.hpl.jena.vocabulary.OWL"%> <%@page import="com.hp.hpl.jena.rdf.model.ModelMaker"%> -<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> -<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelMakerID"%> +<%@ page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess"%> +<%@ page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService"%> <%@page import="java.util.Iterator"%> <%@page import="java.util.ArrayList"%> <%@page import="java.util.List"%> @@ -123,7 +123,7 @@ td {
      <% try { - ModelMaker maker = ModelAccess.on(application).getModelMaker(ModelMakerID.CONFIGURATION); + ModelMaker maker = ModelAccess.on(application).getModelMaker(WhichService.CONFIGURATION); for (Iterator it = maker.listModels(); it.hasNext();) { String modelName = (String) it.next(); %> diff --git a/webapp/web/css/showSources.css b/webapp/web/css/showSources.css new file mode 100644 index 000000000..da39589ea --- /dev/null +++ b/webapp/web/css/showSources.css @@ -0,0 +1,21 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +/* Styles for Freemarker template admin/showSources */ + +#show-sources pre { + font-family: monospace; + line-height: 1.1em; +} + +#show-sources table { + width: 100%; + border: solid black; +} + +#show-sources th { + background-color: #EEEEEE; +} + +#show-sources td { + border: 1px solid gray; +} diff --git a/webapp/web/jenaIngest/executeWorkflow.jsp b/webapp/web/jenaIngest/executeWorkflow.jsp index 8f5751f83..c1483e621 100644 --- a/webapp/web/jenaIngest/executeWorkflow.jsp +++ b/webapp/web/jenaIngest/executeWorkflow.jsp @@ -3,7 +3,7 @@ <%@ page import="com.hp.hpl.jena.ontology.Individual" %> <%@ page import="com.hp.hpl.jena.ontology.OntModel" %> <%@ page import="com.hp.hpl.jena.rdf.model.ModelMaker" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> +<%@ page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess"%> <%@ page import="com.hp.hpl.jena.shared.Lock" %> <%@ page import="java.util.Iterator" %> <%@ page import="java.util.List" %> @@ -24,7 +24,7 @@ <% - OntModel jenaOntModel = ModelAccess.on(getServletContext()).getJenaOntModel(); + OntModel jenaOntModel = ModelAccess.on(getServletContext()).getOntModel(); jenaOntModel.enterCriticalSection(Lock.READ); try { List savedQueries = (List) request.getAttribute("savedQueries"); diff --git a/webapp/web/jenaIngest/workflowStep.jsp b/webapp/web/jenaIngest/workflowStep.jsp index 360093eb2..7ba852dda 100644 --- a/webapp/web/jenaIngest/workflowStep.jsp +++ b/webapp/web/jenaIngest/workflowStep.jsp @@ -3,7 +3,7 @@ <%@ page import="com.hp.hpl.jena.ontology.Individual" %> <%@ page import="com.hp.hpl.jena.ontology.OntModel" %> <%@ page import="com.hp.hpl.jena.rdf.model.ModelMaker" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> +<%@ page import="edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess"%> <%@ page import="com.hp.hpl.jena.shared.Lock" %> <%@ page import="java.util.Iterator" %> <%@ page import="java.util.List" %> @@ -26,7 +26,7 @@ <#list classGroups as aClassGroup> - + diff --git a/webapp/web/templates/freemarker/page/partials/developerPanel.ftl b/webapp/web/templates/freemarker/page/partials/developerPanel.ftl index ecce6cbb9..1390ee5ee 100644 --- a/webapp/web/templates/freemarker/page/partials/developerPanel.ftl +++ b/webapp/web/templates/freemarker/page/partials/developerPanel.ftl @@ -66,6 +66,8 @@
      Show authorization info Show background threads +
      + Show RDF data sources