Java tutorial
/* $This file is distributed under the terms of the license in /doc/license.txt$ */ package edu.cornell.mannlib.vitro.webapp.servlet.setup; import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.DISPLAY_ONT_MODEL; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ResIterator; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.shared.Lock; 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.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.ModelContext; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; 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.RDFServiceModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.SpecialBulkUpdateHandlerGraph; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.utils.jena.InitialJenaModelUtils; /** * Primarily sets up webapp DAO factories. */ public class WebappDaoSetup extends JenaDataSourceSetupBase implements javax.servlet.ServletContextListener { private static final Log log = LogFactory.getLog(WebappDaoSetup.class); @Override public void contextInitialized(ServletContextEvent sce) { ServletContext ctx = sce.getServletContext(); StartupStatus ss = StartupStatus.getBean(ctx); try { long startTime = System.currentTimeMillis(); setUpJenaDataSource(ctx, ss); log.info((System.currentTimeMillis() - startTime) / 1000 + " seconds to set up models and DAO factories"); } catch (Throwable t) { log.error("Throwable in " + this.getClass().getName(), t); ss.fatal(this, "Throwable in " + this.getClass().getName(), t); } } private void setUpJenaDataSource(ServletContext ctx, StartupStatus ss) { OntModelSelectorImpl baseOms = new OntModelSelectorImpl(); OntModelSelectorImpl inferenceOms = new OntModelSelectorImpl(); OntModelSelectorImpl unionOms = new OntModelSelectorImpl(); OntModel userAccountsModel = ontModelFromContextAttribute(ctx, "userAccountsOntModel"); baseOms.setUserAccountsModel(userAccountsModel); inferenceOms.setUserAccountsModel(userAccountsModel); unionOms.setUserAccountsModel(userAccountsModel); OntModel displayModel = ontModelFromContextAttribute(ctx, DISPLAY_ONT_MODEL); baseOms.setDisplayModel(displayModel); inferenceOms.setDisplayModel(displayModel); unionOms.setDisplayModel(displayModel); RDFServiceFactory rdfServiceFactory = RDFServiceUtils.getRDFServiceFactory(ctx); RDFService rdfService = rdfServiceFactory.getRDFService(); Dataset dataset = new RDFServiceDataset(rdfService); setStartupDataset(dataset, ctx); // ABox assertions Model aboxAssertions = dataset.getNamedModel(JenaDataSourceSetupBase.JENA_DB_MODEL); baseOms.setABoxModel(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, aboxAssertions)); // ABox inferences Model aboxInferences = dataset.getNamedModel(JenaDataSourceSetupBase.JENA_INF_MODEL); inferenceOms.setABoxModel(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, aboxInferences)); // TBox assertions try { Model tboxAssertionsDB = dataset.getNamedModel(JENA_TBOX_ASSERTIONS_MODEL); OntModel tboxAssertions = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); if (tboxAssertionsDB != null) { long startTime = System.currentTimeMillis(); System.out.println("Copying cached tbox assertions into memory"); tboxAssertions.add(tboxAssertionsDB); System.out.println( (System.currentTimeMillis() - startTime) / 1000 + " seconds to load tbox assertions"); } tboxAssertions.getBaseModel().register(new ModelSynchronizer(tboxAssertionsDB)); baseOms.setTBoxModel(tboxAssertions); } catch (Throwable e) { log.error("Unable to load tbox assertion cache from DB", e); throw new RuntimeException(e); } // TBox inferences try { Model tboxInferencesDB = dataset.getNamedModel(JENA_TBOX_INF_MODEL); OntModel tboxInferences = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); if (tboxInferencesDB != null) { long startTime = System.currentTimeMillis(); System.out.println("Copying cached tbox inferences into memory"); tboxInferences.add(tboxInferencesDB); System.out.println( (System.currentTimeMillis() - startTime) / 1000 + " seconds to load tbox inferences"); } tboxInferences.getBaseModel().register(new ModelSynchronizer(tboxInferencesDB)); inferenceOms.setTBoxModel(tboxInferences); } catch (Throwable e) { log.error("Unable to load tbox inference cache from DB", e); throw new RuntimeException(e); } // union ABox Model m = ModelFactory.createUnion(baseOms.getABoxModel(), inferenceOms.getABoxModel()); m = ModelFactory.createModelForGraph(new SpecialBulkUpdateHandlerGraph(m.getGraph(), baseOms.getABoxModel().getGraph().getBulkUpdateHandler())); OntModel unionABoxModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC, m); unionOms.setABoxModel(unionABoxModel); // union TBox m = ModelFactory.createUnion(baseOms.getTBoxModel(), inferenceOms.getTBoxModel()); m = ModelFactory.createModelForGraph(new SpecialBulkUpdateHandlerGraph(m.getGraph(), baseOms.getTBoxModel().getGraph().getBulkUpdateHandler())); OntModel unionTBoxModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC, m); unionOms.setTBoxModel(unionTBoxModel); // Application metadata model is cached in memory. try { Model applicationMetadataModelDB = dataset.getNamedModel(JENA_APPLICATION_METADATA_MODEL); OntModel applicationMetadataModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); long startTime = System.currentTimeMillis(); System.out.println("Copying cached application metadata model into memory"); applicationMetadataModel.add(applicationMetadataModelDB); System.out.println( (System.currentTimeMillis() - startTime) / 1000 + " seconds to load application metadata model " + "assertions of size " + applicationMetadataModel.size()); applicationMetadataModel.getBaseModel().register(new ModelSynchronizer(applicationMetadataModelDB)); if (applicationMetadataModel.size() == 0 /* isFirstStartup() */) { JenaDataSourceSetupBase.thisIsFirstStartup(); applicationMetadataModel.add(InitialJenaModelUtils.loadInitialModel(ctx, getDefaultNamespace(ctx))); } baseOms.setApplicationMetadataModel(applicationMetadataModel); inferenceOms.setApplicationMetadataModel(baseOms.getApplicationMetadataModel()); unionOms.setApplicationMetadataModel(baseOms.getApplicationMetadataModel()); } catch (Throwable e) { log.error("Unable to load application metadata model cache from DB", e); throw new RuntimeException(e); } checkForNamespaceMismatch(baseOms.getApplicationMetadataModel(), ctx); if (isFirstStartup()) { loadDataFromFilesystem(baseOms, ctx); } log.info("Setting up union models and DAO factories"); // create TBox + ABox union models and set up webapp DAO factories Model baseDynamicUnion = ModelFactory.createUnion(baseOms.getABoxModel(), baseOms.getTBoxModel()); baseDynamicUnion = ModelFactory.createModelForGraph(new SpecialBulkUpdateHandlerGraph( baseDynamicUnion.getGraph(), baseOms.getABoxModel().getGraph().getBulkUpdateHandler())); OntModel baseUnion = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, baseDynamicUnion); baseOms.setFullModel(baseUnion); ModelContext.setBaseOntModel(baseOms.getFullModel(), ctx); WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); config.setDefaultNamespace(getDefaultNamespace(ctx)); WebappDaoFactory baseWadf = new WebappDaoFactorySDB(rdfService, baseOms, config, WebappDaoFactorySDB.SDBDatasetMode.ASSERTIONS_ONLY); ctx.setAttribute("assertionsWebappDaoFactory", baseWadf); OntModel inferenceUnion = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, ModelFactory.createUnion(inferenceOms.getABoxModel(), inferenceOms.getTBoxModel())); inferenceOms.setFullModel(inferenceUnion); ModelContext.setInferenceOntModel(inferenceOms.getFullModel(), ctx); WebappDaoFactory infWadf = new WebappDaoFactorySDB(rdfService, inferenceOms, config, WebappDaoFactorySDB.SDBDatasetMode.INFERENCES_ONLY); ctx.setAttribute("deductionsWebappDaoFactory", infWadf); OntModel masterUnion = ModelFactory.createOntologyModel(DB_ONT_MODEL_SPEC, dataset.getDefaultModel()); unionOms.setFullModel(masterUnion); ctx.setAttribute("jenaOntModel", masterUnion); WebappDaoFactory wadf = new WebappDaoFactorySDB(rdfService, unionOms, config); ctx.setAttribute("webappDaoFactory", wadf); ModelContext.setOntModelSelector(unionOms, ctx); ModelContext.setUnionOntModelSelector(unionOms, ctx); // assertions and inferences ModelContext.setBaseOntModelSelector(baseOms, ctx); // assertions ModelContext.setInferenceOntModelSelector(inferenceOms, ctx); // inferences ctx.setAttribute("defaultNamespace", getDefaultNamespace(ctx)); makeModelMakerFromConnectionProperties(TripleStoreType.RDB, ctx); VitroJenaModelMaker vjmm = getVitroJenaModelMaker(); setVitroJenaModelMaker(vjmm, ctx); makeModelMakerFromConnectionProperties(TripleStoreType.SDB, ctx); RDFServiceModelMaker vsmm = new RDFServiceModelMaker(rdfServiceFactory); setVitroJenaSDBModelMaker(vsmm, ctx); //bdc34: I have no reason for vsmm vs vjmm. //I don't know what are the implications of this choice. setVitroModelSource(new VitroModelSource(vsmm, ctx), ctx); log.info("Model makers set up"); } /** * If we find a "portal1" portal (and we should), its URI should use the * default namespace. */ private void checkForNamespaceMismatch(OntModel model, ServletContext ctx) { String expectedNamespace = getDefaultNamespace(ctx); List<Resource> portals = getPortal1s(model); if (!portals.isEmpty() && noPortalForNamespace(portals, expectedNamespace)) { // There really should be only one portal 1, but if there happen to // be multiple, just arbitrarily pick the first in the list. Resource portal = portals.get(0); String oldNamespace = portal.getNameSpace(); renamePortal(portal, expectedNamespace, model); StartupStatus ss = StartupStatus.getBean(ctx); ss.warning(this, "\nThe default namespace has been changed \n" + "from " + oldNamespace + "\nto " + expectedNamespace + ".\n" + "The application will function normally, but " + "any individuals in the \n" + oldNamespace + " " + "namespace will need to have their URIs \n" + "changed in order to be served as linked data. " + "You can use the Ingest Tools \nto change the " + "URIs for a batch of resources."); } } private List<Resource> getPortal1s(Model model) { List<Resource> portals = new ArrayList<Resource>(); try { model.enterCriticalSection(Lock.READ); ResIterator portalIt = model.listResourcesWithProperty(RDF.type, PORTAL); while (portalIt.hasNext()) { Resource portal = portalIt.nextResource(); if ("portal1".equals(portal.getLocalName())) { portals.add(portal); } } } finally { model.leaveCriticalSection(); } return portals; } private boolean noPortalForNamespace(List<Resource> portals, String expectedNamespace) { for (Resource portal : portals) { if (expectedNamespace.equals(portal.getNameSpace())) { return false; } } return true; } private void renamePortal(Resource portal, String namespace, Model model) { model.enterCriticalSection(Lock.WRITE); try { ResourceUtils.renameResource(portal, namespace + portal.getLocalName()); } finally { model.leaveCriticalSection(); } } /* ===================================================================== */ @Override public void contextDestroyed(ServletContextEvent sce) { // Nothing to do. } private boolean isEmpty(Model model) { ClosableIterator<Statement> closeIt = model.listStatements(null, RDF.type, ResourceFactory.createResource(VitroVocabulary.PORTAL)); try { if (closeIt.hasNext()) { return false; } else { return true; } } finally { closeIt.close(); } } private void loadDataFromFilesystem(OntModelSelector baseOms, ServletContext ctx) { Long startTime = System.currentTimeMillis(); log.info("Initializing models from RDF files"); readOntologyFilesInPathSet(USER_ABOX_PATH, ctx, baseOms.getABoxModel()); readOntologyFilesInPathSet(USER_TBOX_PATH, ctx, baseOms.getTBoxModel()); readOntologyFilesInPathSet(USER_APPMETA_PATH, ctx, baseOms.getApplicationMetadataModel()); log.debug(((System.currentTimeMillis() - startTime) / 1000) + " seconds to read RDF files "); } }