Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add factory for creating Kvin instances based on RDF configurations #13

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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