Skip to content

Commit

Permalink
feat: overhauled ontology imports
Browse files Browse the repository at this point in the history
  • Loading branch information
jenspots committed May 28, 2024
1 parent 2bf6fcf commit 74f9eb7
Show file tree
Hide file tree
Showing 35 changed files with 128 additions and 133 deletions.
3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ repositories {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")

// Reflections
implementation("org.reflections:reflections:0.10.2")

// Guava
implementation("com.google.guava:guava:33.2.0-jre")

Expand Down
30 changes: 21 additions & 9 deletions src/main/kotlin/parser/Parser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@ import kotlinx.coroutines.channels.Channel
import org.apache.jena.rdf.model.RDFNode
import technology.idlab.bridge.*
import technology.idlab.extensions.*
import technology.idlab.extensions.loadIntoJVM
import technology.idlab.extensions.query
import technology.idlab.extensions.readModelRecursively
import technology.idlab.extensions.validate
import technology.idlab.logging.Log
import technology.idlab.runner.Processor
import technology.idlab.runner.ProcessorDefinition

class Parser(file: File) {
/** An RDF model of the configuration file. */
private val model = file.readModelRecursively().validate()
/** RDF model which imports the base pipeline ontology. */
private val model =
this::class
.java
.getResource("/pipeline.ttl")
.let { it ?: Log.shared.fatal("Pipeline file not found") }
.toURI()
.let { File(it) }
.readModelRecursively()

/** Class references to the different processors. */
private val processors: MutableMap<String, Class<*>> = mutableMapOf()
Expand All @@ -33,14 +39,20 @@ class Parser(file: File) {

/** Parse the model for processor declarations and save results as a field. */
init {
model.query("/queries/processors.sparql") {
val uri = it["processor"].toString()
val path = it["file"].toString().drop(7)
val sourceFile = File(path)
processors[uri] = sourceFile.loadIntoJVM()
ProcessorDefinition.scan().forEach {
// Save the processor class and URI to the map.
processors[it.uri] = it.clazz

// Load the ontology file into the model.
model.read(it.ontology.inputStream(), null, "TTL")
}
}

/** Parse the pipeline. */
init {
model.read(file.inputStream(), null, "TTL").validate()
}

/** Parse the shape for each processor. */
init {
processors.forEach { processor ->
Expand Down
34 changes: 34 additions & 0 deletions src/main/kotlin/runner/ProcessorDefinition.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package technology.idlab.runner

import java.io.File
import technology.idlab.logging.Log
import technology.idlab.util.classesWithAnnotation

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class ProcessorDefinition(val resource: String) {
data class Config(val clazz: Class<out Processor>, val ontology: File, val uri: String)

companion object {
fun scan(): List<Config> {
return classesWithAnnotation(ProcessorDefinition::class.java)
.map {
try {
it.asSubclass(Processor::class.java)
} catch (e: ClassCastException) {
Log.shared.fatal("Class $it is not a Processor")
}
}
.map {
val annotation = it.getAnnotation(ProcessorDefinition::class.java)

val resource =
it.getResource(annotation.resource)
?: Log.shared.fatal("Resource ${annotation.resource} not found")

Config(it, File(resource.toURI()), "https://w3id.org/conn/jvm#${it.simpleName}")
}
}
}
}
2 changes: 2 additions & 0 deletions src/main/kotlin/std/FileReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package technology.idlab.std
import java.io.File
import technology.idlab.bridge.Writer
import technology.idlab.runner.Processor
import technology.idlab.runner.ProcessorDefinition

@ProcessorDefinition("/std/file_reader.ttl")
class FileReader(args: Map<String, Any>) : Processor(args) {
/** Arguments */
private val path: String = this.getArgument("path")
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/std/FileWriter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package technology.idlab.std
import java.io.File
import technology.idlab.bridge.Reader
import technology.idlab.runner.Processor
import technology.idlab.runner.ProcessorDefinition

@ProcessorDefinition("/std/file_writer.ttl")
class FileWriter(args: Map<String, Any>) : Processor(args) {
/** Processor default values. */
private val overwriteDefault = true
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/std/HttpFetch.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import io.ktor.http.*
import kotlinx.coroutines.runBlocking
import technology.idlab.bridge.Writer
import technology.idlab.runner.Processor
import technology.idlab.runner.ProcessorDefinition

@ProcessorDefinition("/std/http_fetch.ttl")
class HttpFetch(args: Map<String, Any>) : Processor(args) {
/** Meta configuration. */
private var engine: HttpClientEngine = CIO.create()
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/std/RDFValidator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import technology.idlab.bridge.Writer
import technology.idlab.extensions.readModelRecursively
import technology.idlab.logging.Log
import technology.idlab.runner.Processor
import technology.idlab.runner.ProcessorDefinition

@ProcessorDefinition("/std/rdf_validator.ttl")
class RDFValidator(args: Map<String, Any>) : Processor(args) {
/** Default values. */
private val errorIsFatalDefault = false
Expand Down
File renamed without changes.
19 changes: 19 additions & 0 deletions src/main/kotlin/util/Reflect.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package technology.idlab.util

import org.reflections.Reflections
import org.reflections.scanners.Scanners
import org.reflections.util.ConfigurationBuilder

internal fun classesWithAnnotation(annotation: Class<out Annotation>): Set<Class<*>> {
// Get a list of all classes with type annotations.
val config =
ConfigurationBuilder()
.forPackages("") // Root package, adjust if needed
.addScanners(Scanners.TypesAnnotated)

// Initialize a Reflections client.
val reflections = Reflections(config)

// Filter based on JVMRunnerProcessor
return reflections.getTypesAnnotatedWith(annotation)
}
20 changes: 2 additions & 18 deletions src/main/resources/pipeline.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,12 @@
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix owl: <http://www.w3.org/2002/07/owl#>.

# Include the Standard Processor Library
<> owl:imports
<./std/file_reader.ttl>,
<./std/file_writer.ttl>,
<./std/http_fetch.ttl>,
<./std/rdf_validator.ttl>.

# Definition of a Processor.
[]
a sh:NodeShape;
sh:targetClass jvm:Processor;
sh:property [
sh:path jvm:file;
sh:minCount 1;
sh:maxCount 1;
], [
sh:path jvm:language;
sh:in( "Java" "Kotlin" );
sh:datatype xsd:string;
sh:minCount 1;
sh:maxCount 1;
].
sh:closed true;
sh:ignoredProperties ( rdf:type ).

# A bridge takes in a reader and writer.
[]
Expand Down
34 changes: 0 additions & 34 deletions src/main/resources/queries/processors.sparql

This file was deleted.

6 changes: 1 addition & 5 deletions src/main/resources/std/file_reader.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.

<> owl:imports <../pipeline.ttl>.

jvm:FileReader a jvm:Processor;
jvm:file <../../../classes/kotlin/main/technology/idlab/std/FileReader.class>;
jvm:language "Kotlin".
jvm:FileReader a jvm:Processor.

[] a sh:NodeShape;
sh:targetClass jvm:FileReader;
Expand Down
6 changes: 1 addition & 5 deletions src/main/resources/std/file_writer.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.

<> owl:imports <../pipeline.ttl>.

jvm:FileWriter a jvm:Processor;
jvm:file <../../../classes/kotlin/main/technology/idlab/std/FileWriter.class>;
jvm:language "Kotlin".
jvm:FileWriter a jvm:Processor.

[] a sh:NodeShape;
sh:targetClass jvm:FileWriter;
Expand Down
6 changes: 1 addition & 5 deletions src/main/resources/std/http_fetch.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.

<> owl:imports <../pipeline.ttl>.

jvm:HttpFetch a jvm:Processor;
jvm:file <../../../classes/kotlin/main/technology/idlab/std//HttpFetch.class>;
jvm:language "Kotlin".
jvm:HttpFetch a jvm:Processor.

[] a sh:NodeShape;
sh:targetClass jvm:HttpFetch;
Expand Down
6 changes: 1 addition & 5 deletions src/main/resources/std/rdf_validator.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.

<> owl:imports <../pipeline.ttl>.

jvm:RDFValidator a jvm:Processor;
jvm:file <../../../classes/kotlin/main/technology/idlab/std/RDFValidator.class>;
jvm:language "Kotlin".
jvm:RDFValidator a jvm:Processor.

[] a sh:NodeShape;
sh:targetClass jvm:RDFValidator;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package processors;

import java.util.List;
import java.util.Map;
import technology.idlab.bridge.*;
import technology.idlab.runner.Processor;
import technology.idlab.runner.ProcessorDefinition;

@ProcessorDefinition(resource = "/processors/filter.ttl")
public class Filter extends Processor {
// Parameters
private final List<Integer> whitelist;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package processors;

import java.util.Date;
import java.util.Map;
import technology.idlab.bridge.*;
import technology.idlab.runner.Processor;
import technology.idlab.runner.ProcessorDefinition;

@ProcessorDefinition(resource = "/processors/literals.ttl")
public class Literals extends Processor {
// Parameters
private final boolean _bool;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package processors;

import java.util.Map;
import java.util.Optional;
import technology.idlab.runner.Processor;
import technology.idlab.runner.ProcessorDefinition;

@ProcessorDefinition(resource = "/processors/optionals.ttl")
public class Optionals extends Processor {
// Parameters
public final String required;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package processors;

import java.util.Map;
import technology.idlab.bridge.Writer;
import technology.idlab.runner.Processor;
import technology.idlab.runner.ProcessorDefinition;

@ProcessorDefinition(resource = "/processors/range.ttl")
public class Range extends Processor {
// Parameters
private final int start;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package processors;

import java.util.Map;
import technology.idlab.bridge.Reader;
import technology.idlab.runner.Processor;
import technology.idlab.runner.ProcessorDefinition;

@ProcessorDefinition(resource = "/processors/reporter.ttl")
public class Reporter extends Processor {
private final Reader reader;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package processors;

import java.util.Map;
import technology.idlab.bridge.Reader;
import technology.idlab.bridge.Writer;
import technology.idlab.runner.Processor;
import technology.idlab.runner.ProcessorDefinition;

@ProcessorDefinition(resource = "/processors/square.ttl")
public class Square extends Processor {
// Channels
private final Reader reader;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package processors

import technology.idlab.bridge.*
import technology.idlab.runner.Processor
import technology.idlab.runner.ProcessorDefinition

@ProcessorDefinition("/processors/negator.ttl")
class Negator(args: Map<String, Any>) : Processor(args) {
private val input: Reader = this.getArgument("input")
private val output: Writer = this.getArgument("output")
Expand Down
4 changes: 2 additions & 2 deletions src/test/kotlin/std/RDFValidatorTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import technology.idlab.std.RDFValidator

/** Ontology location. */
private val ontology =
Thread.currentThread().contextClassLoader.getResource("pipeline.ttl")!!.let { File(it.file) }
File(Thread.currentThread().contextClassLoader.getResource("pipeline.ttl")!!.file)

/** Textual representation of a valid SHACL file. */
private const val validShape =
Expand Down Expand Up @@ -56,7 +56,7 @@ private const val validInput =
@prefix ex: <http://example.org#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:ValidPoint
ex:ValidPoint
a ex:Point;
ex:x "1"^^xsd:int;
ex:y "2"^^xsd:int.
Expand Down
5 changes: 0 additions & 5 deletions src/test/resources/pipelines/filter.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix owl: <http://www.w3.org/2002/07/owl#>.

# Include processor definitions.
<> owl:imports
<../pipeline.ttl>,
<../processors/filter.ttl>.

# Range -> Filter
<reader> a jvm:MemoryChannelReader.
<writer> a jvm:MemoryChannelWriter.
Expand Down
Loading

0 comments on commit 74f9eb7

Please sign in to comment.