package net.enilink.komma.model; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Properties; import org.eclipse.core.runtime.Platform; import org.eclipse.rdf4j.repository.Repository; import org.eclipse.rdf4j.repository.RepositoryConnection; import org.eclipse.rdf4j.repository.RepositoryException; import org.eclipse.rdf4j.repository.sail.SailRepository; import org.eclipse.rdf4j.rio.RDFFormat; import org.eclipse.rdf4j.rio.RDFParseException; import org.eclipse.rdf4j.rio.Rio; import org.eclipse.rdf4j.sail.NotifyingSail; import org.eclipse.rdf4j.sail.inferencer.fc.ForwardChainingRDFSInferencer; import org.eclipse.rdf4j.sail.memory.MemoryStore; import org.osgi.framework.Bundle; import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.Provides; import com.google.inject.Singleton; import net.enilink.komma.core.IProvider; import net.enilink.komma.core.IUnitOfWork; import net.enilink.komma.core.KommaException; import net.enilink.komma.core.KommaModule; import net.enilink.komma.dm.IDataManager; import net.enilink.komma.em.EagerCachingEntityManagerModule; import net.enilink.komma.em.EntityManagerFactoryModule; import net.enilink.komma.em.ThreadLocalDataManager; import net.enilink.komma.em.util.KommaUtil; import net.enilink.komma.em.util.UnitOfWork; import net.enilink.komma.rdf4j.RDF4JModule; public class ModelSetModule extends AbstractModule { private KommaModule parentModule; public ModelSetModule(KommaModule module) { this.parentModule = module; } @Override protected void configure() { bind(UnitOfWork.class).in(Singleton.class); bind(IUnitOfWork.class).to(UnitOfWork.class); } @Provides @Singleton public IModelSetFactory provideModelSetFactory(Injector injector) { KommaModule module = new KommaModule(getClass().getClassLoader()); if (parentModule != null) { module.includeModule(parentModule); } // for (URL libraryUrl : KommaUtil.getConceptLibraries( // Platform.getBundle(KommaConcepts.PLUGIN_ID)).andThen( // KommaUtil.getBundleMetaInfLocations(KommaConcepts.PLUGIN_ID))) { // module.addJarFileUrl(libraryUrl); // } // module.addDataset( // getResource(ModelCore.PLUGIN_ID, // "META-INF/ontologies/models.owl"), // "http://enilink.net/vocab/komma/models#"); module.includeModule(KommaUtil.getCoreModule()); ModelSetFactory factory = injector.createChildInjector( createFactoryModules(module)) .getInstance(ModelSetFactory.class); return factory; } protected List<? extends Module> createFactoryModules( KommaModule kommaModule) { return Arrays.<Module> asList(new AbstractModule() { @Override protected void configure() { bind(IDataManager.class).to(ThreadLocalDataManager.class).in( Singleton.class); } @Singleton @Provides Repository provideRepository() { return createMetaDataRepository(); } }, new RDF4JModule(), new EntityManagerFactoryModule(kommaModule, getLocaleProvider(), getEntityManagerModule())); } protected IProvider<Locale> getLocaleProvider() { return null; } protected Module getEntityManagerModule() { return new EagerCachingEntityManagerModule(); } /** * Initializes meta data repository with internal ontologies */ protected Repository createMetaDataRepository() { try { NotifyingSail sailStack = new MemoryStore(); sailStack = new ForwardChainingRDFSInferencer(sailStack); Repository repository = new SailRepository(sailStack); repository.initialize(); Collection<URL> conceptLibraries = KommaUtil.getConceptLibraries( ModelPlugin.PLUGIN_ID).toList(); URLClassLoader cl = new URLClassLoader( conceptLibraries.toArray(new URL[conceptLibraries.size()])); for (String owl : loadOntologyList(cl)) { URL url = cl.getResource(owl); loadOntology(repository, url); } return repository; } catch (Exception e) { throw new KommaException(e); } } private RDFFormat formatForFileName(String filename) { Optional<RDFFormat> format = Rio.getWriterFormatForFileName(filename); if (format.isPresent()) return format.get(); if (filename.endsWith(".owl")) return RDFFormat.RDFXML; throw new IllegalArgumentException("Unknow RDF format for " + filename); } protected URL getResource(String bundleName, String path) { Bundle bundle = null; if (ModelPlugin.IS_ECLIPSE_RUNNING) { bundle = Platform.getBundle(bundleName); } if (bundle != null) { return bundle.getEntry(path); } else { return getClass().getClassLoader().getResource(path); } } private void loadOntology(Repository repository, URL url) throws RepositoryException, IOException, RDFParseException { String filename = url.toString(); RDFFormat format = formatForFileName(filename); RepositoryConnection conn = repository.getConnection(); try { conn.add(url, "", format); } finally { conn.close(); } } @SuppressWarnings("unchecked") private Collection<String> loadOntologyList(ClassLoader cl) throws IOException { Properties ontologies = new Properties(); String name = "META-INF/org.openrdf.ontologies"; Enumeration<URL> resources = cl.getResources(name); while (resources.hasMoreElements()) { URL url = resources.nextElement(); ontologies.load(url.openStream()); } Collection<?> list = ontologies.keySet(); return (Collection<String>) list; } }