Skip to content

Commit

Permalink
Merge pull request #13 from linkedfactory/kvin-config
Browse files Browse the repository at this point in the history
Add factory for creating Kvin instances based on RDF configurations
  • Loading branch information
kenwenzel authored Feb 19, 2024
2 parents a11a689 + cf3b27b commit 886e2c7
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 37 deletions.
9 changes: 9 additions & 0 deletions bundles/io.github.linkedfactory.service/plugin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension point="net.enilink.komma.model.modules">
<module class="io.github.linkedfactory.service.config.ConfigModule"
uri="plugin://io.github.linkedfactory.service/">
</module>
</extension>
</plugin>
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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();
}
Original file line number Diff line number Diff line change
@@ -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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
# <> <mockdata> [ <machines> 10 ] ; <mocktracker> true .

@base <plugin://io.github.linkedfactory.service/data/> .
<store> <model> <http://linkedfactory.github.io/data/> ;
<dirName> "linkedfactory-valuestore" .
<> <defaultModel> <http://linkedfactory.github.io/data/> .
<> <store> [ a <KvinLevelDb> ; <dirName> "linkedfactory-valuestore" ] .
Original file line number Diff line number Diff line change
Expand Up @@ -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._
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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)
}
}
}
Expand All @@ -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)))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Kvin> kvinServiceRegistration;
Kvin kvin;
Expand All @@ -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();
Expand Down

0 comments on commit 886e2c7

Please sign in to comment.