diff --git a/bundles/io.github.linkedfactory.service/plugin.xml b/bundles/io.github.linkedfactory.service/plugin.xml
new file mode 100644
index 00000000..65a626bb
--- /dev/null
+++ b/bundles/io.github.linkedfactory.service/plugin.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/io.github.linkedfactory.service/src/main/java/io/github/linkedfactory/service/config/ConfigModule.java b/bundles/io.github.linkedfactory.service/src/main/java/io/github/linkedfactory/service/config/ConfigModule.java
new file mode 100644
index 00000000..a22c03dc
--- /dev/null
+++ b/bundles/io.github.linkedfactory.service/src/main/java/io/github/linkedfactory/service/config/ConfigModule.java
@@ -0,0 +1,11 @@
+package io.github.linkedfactory.service.config;
+
+import net.enilink.komma.core.KommaModule;
+
+public class ConfigModule extends KommaModule {
+ {
+ // specify dummy type to make KOMMA happy
+ addConcept(IKvinFactory.class, "plugin://io.github.linkedfactory.service/data/Kvin");
+ addBehaviour(KvinLevelDbFactory.class);
+ }
+}
diff --git a/bundles/io.github.linkedfactory.service/src/main/java/io/github/linkedfactory/service/config/IKvinFactory.java b/bundles/io.github.linkedfactory.service/src/main/java/io/github/linkedfactory/service/config/IKvinFactory.java
new file mode 100644
index 00000000..92323aa0
--- /dev/null
+++ b/bundles/io.github.linkedfactory.service/src/main/java/io/github/linkedfactory/service/config/IKvinFactory.java
@@ -0,0 +1,14 @@
+package io.github.linkedfactory.service.config;
+
+import io.github.linkedfactory.core.kvin.Kvin;
+
+/**
+ * Factory for creating {@link Kvin} instances.
+ */
+public interface IKvinFactory {
+ /**
+ * Creates a {@link Kvin} instance
+ * @return an instance of a {@link Kvin} store
+ */
+ Kvin create();
+}
diff --git a/bundles/io.github.linkedfactory.service/src/main/java/io/github/linkedfactory/service/config/KvinLevelDbFactory.java b/bundles/io.github.linkedfactory.service/src/main/java/io/github/linkedfactory/service/config/KvinLevelDbFactory.java
new file mode 100644
index 00000000..44e62977
--- /dev/null
+++ b/bundles/io.github.linkedfactory.service/src/main/java/io/github/linkedfactory/service/config/KvinLevelDbFactory.java
@@ -0,0 +1,41 @@
+package io.github.linkedfactory.service.config;
+
+import io.github.linkedfactory.core.kvin.Kvin;
+import io.github.linkedfactory.core.kvin.leveldb.KvinLevelDb;
+import net.enilink.composition.annotations.Iri;
+import org.eclipse.core.runtime.Platform;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.net.URISyntaxException;
+
+@Iri("plugin://io.github.linkedfactory.service/data/KvinLevelDb")
+public abstract class KvinLevelDbFactory implements IKvinFactory {
+ private static final Logger log = LoggerFactory.getLogger(KvinLevelDbFactory.class);
+
+ public static String TYPE = "plugin://io.github.linkedfactory.service/data/KvinLevelDb";
+
+ @Override
+ public Kvin create() {
+ String dirName = getDirName();
+ if (dirName == null) {
+ dirName = "linkedfactory-valuestore";
+ }
+ File valueStorePath;
+ if (new File(dirName).isAbsolute()) {
+ valueStorePath = new File(dirName);
+ } else {
+ try {
+ valueStorePath = new File(new File(Platform.getInstanceLocation().getURL().toURI()), dirName);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ log.info("Using store path: {}", valueStorePath);
+ return new KvinLevelDb(valueStorePath);
+ }
+
+ @Iri("plugin://io.github.linkedfactory.service/data/dirName")
+ public abstract String getDirName();
+}
diff --git a/bundles/io.github.linkedfactory.service/src/main/resources/OSGI-INF/io.github.linkedfactory.service-default.ttl b/bundles/io.github.linkedfactory.service/src/main/resources/OSGI-INF/io.github.linkedfactory.service-default.ttl
index c684f9fa..37408ae7 100644
--- a/bundles/io.github.linkedfactory.service/src/main/resources/OSGI-INF/io.github.linkedfactory.service-default.ttl
+++ b/bundles/io.github.linkedfactory.service/src/main/resources/OSGI-INF/io.github.linkedfactory.service-default.ttl
@@ -5,5 +5,5 @@
# <> [ 10 ] ; true .
@base .
- ;
- "linkedfactory-valuestore" .
+<> .
+<> [ a ; "linkedfactory-valuestore" ] .
diff --git a/bundles/io.github.linkedfactory.service/src/main/scala/io/github/linkedfactory/service/Data.scala b/bundles/io.github.linkedfactory.service/src/main/scala/io/github/linkedfactory/service/Data.scala
index 00ce61b5..14f8c6a9 100644
--- a/bundles/io.github.linkedfactory.service/src/main/scala/io/github/linkedfactory/service/Data.scala
+++ b/bundles/io.github.linkedfactory.service/src/main/scala/io/github/linkedfactory/service/Data.scala
@@ -17,6 +17,7 @@ package io.github.linkedfactory.service
import com.google.common.cache.CacheBuilder
import io.github.linkedfactory.core.kvin.{Kvin, KvinListener}
+import io.github.linkedfactory.service.config.{IKvinFactory, KvinLevelDbFactory}
import io.github.linkedfactory.service.model.ssn._
import io.github.linkedfactory.service.util.ResourceHelpers.withTransaction
import net.enilink.komma.core._
@@ -30,6 +31,7 @@ import net.liftweb.common.Box
import net.liftweb.http.{RequestVar, S}
import org.eclipse.core.runtime.Platform
import org.osgi.framework.FrameworkUtil
+import org.slf4j.LoggerFactory
import java.security.PrivilegedExceptionAction
import java.text.SimpleDateFormat
@@ -39,10 +41,12 @@ import scala.jdk.CollectionConverters._
import scala.reflect.{ClassTag, classTag}
object Data {
+ val log = LoggerFactory.getLogger(getClass)
+
val NAMESPACE = "http://linkedfactory.github.io/vocab#"
val PROPERTY_CONTAINS = URIs.createURI(NAMESPACE + "contains")
- val cfgURI = URIs.createURI("plugin://de.fraunhofer.iwu.linkedfactory.service/data/")
+ val cfgUri = URIs.createURI("plugin://io.github.linkedfactory.service/data/")
val dateFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss")
val bundleContext = Option(FrameworkUtil.getBundle(getClass)).map(_.getBundleContext).getOrElse(null)
@@ -54,14 +58,16 @@ object Data {
private var _modelURI: URI = _
if (bundleContext != null) {
- // get configuration settings from plugin config model
+ // configure default model
Globals.withPluginConfig { pcModel => {
- val cfg = pcModel.getManager.find(cfgURI.appendLocalPart("store")).asInstanceOf[IResource]
- _modelURI = cfg.getSingle(cfgURI.appendLocalPart("model")) match {
+ val defaultModel = pcModel.getManager.find(cfgUri, classOf[IResource])
+ .getSingle(cfgUri.appendLocalPart("defaultModel"));
+ _modelURI = defaultModel match {
case r: IReference if r.getURI != null => r.getURI
case s: String => URIs.createURI(s)
case _ => URIs.createURI("http://linkedfactory.github.io/data/")
}
+ log.info("Using default data model: {}", _modelURI)
}
}
}
@@ -75,10 +81,11 @@ object Data {
.build[URI, Any]()
val modelURI = _modelURI
+
// caches currentModel for each request
object modelForRequest extends RequestVar[Box[IModel]](currentModel)
- def getKvin() : Option[Kvin] = {
+ def getKvin(): Option[Kvin] = {
Option(bundleContext).flatMap(ctx =>
Option(ctx.getServiceReference(classOf[Kvin])).map(ref => ctx.getService(ref)))
}
diff --git a/bundles/io.github.linkedfactory.service/src/main/scala/io/github/linkedfactory/service/KvinManager.java b/bundles/io.github.linkedfactory.service/src/main/scala/io/github/linkedfactory/service/KvinManager.java
index 2918ec25..f4c22561 100644
--- a/bundles/io.github.linkedfactory.service/src/main/scala/io/github/linkedfactory/service/KvinManager.java
+++ b/bundles/io.github.linkedfactory.service/src/main/scala/io/github/linkedfactory/service/KvinManager.java
@@ -1,28 +1,30 @@
package io.github.linkedfactory.service;
import io.github.linkedfactory.core.kvin.Kvin;
-import io.github.linkedfactory.core.kvin.leveldb.KvinLevelDb;
+import io.github.linkedfactory.service.config.IKvinFactory;
+import io.github.linkedfactory.service.config.KvinLevelDbFactory;
import net.enilink.komma.core.URI;
import net.enilink.komma.core.URIs;
+import net.enilink.komma.em.concepts.IClass;
import net.enilink.komma.em.concepts.IResource;
import net.enilink.platform.core.PluginConfigModel;
-
-import java.io.File;
-import java.net.URISyntaxException;
-import java.util.Hashtable;
-
-import org.eclipse.core.runtime.Platform;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Hashtable;
@Component
public class KvinManager {
- static final URI cfgUri = URIs.createURI("plugin://de.fraunhofer.iwu.linkedfactory.service/data/");
+ static final Logger log = LoggerFactory.getLogger(KvinManager.class);
+
+ static final URI cfgUri = URIs.createURI("plugin://io.github.linkedfactory.service/data/");
PluginConfigModel configModel;
ServiceRegistration kvinServiceRegistration;
Kvin kvin;
@@ -36,30 +38,36 @@ void setConfigModel(PluginConfigModel configModel) {
void activate(ComponentContext ctx) {
try {
configModel.begin();
- IResource cfg = configModel.getManager().find(cfgUri.appendLocalPart("store"), IResource.class);
- Object type = cfg.getSingle(cfgUri.appendLocalPart("type"));
- if (type == null || "KvinLevelDb".equals(type)) {
- String dirName = (String) cfg.getSingle(cfgUri.appendLocalPart("dirName"));
- if (dirName == null) {
- dirName = "linkedfactory-valuestore";
- }
- File valueStorePath;
- if (new File(dirName).isAbsolute()) {
- valueStorePath = new File(dirName);
+ Object cfg = configModel.getManager().find(cfgUri, IResource.class)
+ .getSingle(cfgUri.appendLocalPart("store"));
+
+ if (! (cfg instanceof IResource)) {
+ log.error("Kvin store is not properly configured in: {}", cfgUri);
+ return;
+ }
+
+ IResource cfgResource = (IResource) cfg;
+ IKvinFactory factory;
+ if (!(cfg instanceof IKvinFactory)) {
+ if (cfgResource.getRdfTypes().isEmpty()) {
+ // fallback to KvinLevelDb
+ log.info("Using default KvinLevelDb as type is not specified in config: {}", cfgUri);
+ cfgResource.getRdfTypes().add(configModel.getManager()
+ .find(URIs.createURI(KvinLevelDbFactory.TYPE), IClass.class));
+ factory = cfgResource.as(IKvinFactory.class);
} else {
- try {
- valueStorePath = new File(new File(Platform.getInstanceLocation().getURL().toURI()), dirName);
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
- }
- try {
- kvin = new KvinLevelDb(valueStorePath);
- kvinServiceRegistration = ctx.getBundleContext().registerService(Kvin.class, kvin, new Hashtable<>());
- System.out.println("Value store: using LF w/ path=" + valueStorePath);
- } catch (Throwable throwable) {
- System.err.println("Value store: FAILURE for LF w/ path=" + valueStorePath + ": " + throwable.getMessage());
+ log.error("Invalid Kvin configurations with types: {}", cfgResource.getRdfTypes());
+ return;
}
+ } else {
+ factory = (IKvinFactory) cfg;
+ }
+
+ try {
+ kvin = factory.create();
+ kvinServiceRegistration = ctx.getBundleContext().registerService(Kvin.class, kvin, new Hashtable<>());
+ } catch (Throwable throwable) {
+ log.error("Failure while creating Kvin store", throwable);
}
} finally {
configModel.end();