From 54af39b976d9dc0e6843f187f9de124ce0d5af01 Mon Sep 17 00:00:00 2001 From: Vincent Emonet Date: Fri, 13 Mar 2020 20:35:54 +0100 Subject: [PATCH 001/169] define io.rml.framework.Main mainClass in pom.xml to avoid needing to provide it when running the job with Apache Flink UI --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index cf210afc..a336a723 100644 --- a/pom.xml +++ b/pom.xml @@ -383,6 +383,10 @@ SOFTWARE. to use the transformer to include those files in the fat-jar. --> + + io.rml.framework.Main + From 1a8502af86bf7a519687d31c81f60d5a3c6575ec Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 26 May 2020 19:23:58 +0200 Subject: [PATCH 002/169] wip: integration function-feature code [local] build successful. output generation tests: all 3 passed. Note: **no** fno-testcases were executed, yet. --- .../core/function/TransformationLoader.scala | 103 ++++++++++++++++ .../core/function/TransformationUtils.scala | 73 +++++++++++ .../model/DynamicMethodTransformation.scala | 81 ++++++++++++ .../core/function/model/Parameter.scala | 115 ++++++++++++++++++ .../core/function/model/Transformation.scala | 28 +++++ .../model/TransientTransformation.scala | 36 ++++++ .../model/std/StdRandomTransformation.scala | 21 ++++ .../std/StdUpperCaseTransformation.scala | 19 +++ .../std/StdTransformationLoader.scala | 66 ++++++++++ .../core/model/rdf/RDFResource.scala | 3 + .../core/model/rdf/jena/JenaResource.scala | 10 +- .../io/rml/framework/core/util/JenaUtil.scala | 9 ++ .../io/rml/framework/core/util/Util.scala | 8 +- .../core/vocabulary/Namespaces.scala | 5 +- .../framework/core/vocabulary/RMLVoc.scala | 43 +++++++ .../framework/flink/sink/FlinkResource.scala | 4 +- 16 files changed, 620 insertions(+), 4 deletions(-) create mode 100644 src/main/scala/io/rml/framework/core/function/TransformationLoader.scala create mode 100644 src/main/scala/io/rml/framework/core/function/TransformationUtils.scala create mode 100644 src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala create mode 100644 src/main/scala/io/rml/framework/core/function/model/Parameter.scala create mode 100644 src/main/scala/io/rml/framework/core/function/model/Transformation.scala create mode 100644 src/main/scala/io/rml/framework/core/function/model/TransientTransformation.scala create mode 100644 src/main/scala/io/rml/framework/core/function/model/std/StdRandomTransformation.scala create mode 100644 src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseTransformation.scala create mode 100644 src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala diff --git a/src/main/scala/io/rml/framework/core/function/TransformationLoader.scala b/src/main/scala/io/rml/framework/core/function/TransformationLoader.scala new file mode 100644 index 00000000..551e785b --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/TransformationLoader.scala @@ -0,0 +1,103 @@ +package io.rml.framework.core.function + +import java.io.File + +import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.function.model.{DynamicMethodTransformation, Parameter, Transformation, TransientTransformation} +import io.rml.framework.core.function.std.StdTransformationLoader +import io.rml.framework.core.internal.Logging +import io.rml.framework.core.model.Uri +import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode} +import io.rml.framework.core.util.Turtle + +import scala.collection.immutable.{Map => ImmutableMap} +import scala.collection.mutable.{Map => MutableMap} + +abstract class TransformationLoader extends Logging { + /** + * Map string value of classes to library path + */ + protected val classLibraryMap: MutableMap[String, String] = MutableMap() + + + /** + * Map names of [[Transformation]] to concrete [[Transformation]] object + */ + protected val transformationMap: MutableMap[Uri, Transformation] = MutableMap() + + + def getClassLibraryMap: ImmutableMap[String, String] = { + classLibraryMap.toMap + } + + def getTransformationMap: ImmutableMap[Uri, Transformation] = { + transformationMap.toMap + } + + def parseTransformations(file: File): TransformationLoader = { + + //TODO: passing hardcoding Turtle-format. + // HELP: shouldn't we derive the format from the file itself? + val graph = RDFGraph.fromFile(file, RMLEnvironment.getGeneratorBaseIRI(),Turtle) + + parseTransformations(graph) + this + } + + /** + * Given the [[Uri]] representation of the transformation, the [[TransformationLoader]] + * will search for the transformation in the [[transformationMap]] and dynamically load + * the transformation. + * + * @param uri Uri representing a transformation + * @return [[Option]] of dynamically loaded transformation + */ + def loadTransformation(uri: Uri): Option[Transformation] = { + + val optTransformation = transformationMap.get(uri) + + if (optTransformation.isDefined) { + val trans = optTransformation.get + + logInfo(s"Dynamically loading transformation: $uri, ${trans.toString}" ) + + trans match { + case transient: TransientTransformation => + val loadedTrans = transient.initialize() + transformationMap.put(uri, loadedTrans) + Some(loadedTrans) + case loadedTrans: DynamicMethodTransformation => Some(loadedTrans) + case _ => None + } + + } else { + None + } + } + + /** + * Parse transformations from the [[RDFGraph]] of the whole function mapping file. + * + * @param graph [[RDFGraph]] representing the whole function mapping file + * @return [[TransformationLoader]] + */ + def parseTransformations(graph: RDFGraph): TransformationLoader + + + /** + * Parse [[Parameter]] from the given [[RDFNode]] which represents the parameter + * + * @param rdfNode [[RDFNode]] containing the mapping information of the parameter + * @param pos [[Int]] integer position of the parameter + * @return + */ + def parseParameter(rdfNode: RDFNode, pos: Int): Parameter +} + + +object TransformationLoader { + + def apply(): TransformationLoader = StdTransformationLoader() +} + + diff --git a/src/main/scala/io/rml/framework/core/function/TransformationUtils.scala b/src/main/scala/io/rml/framework/core/function/TransformationUtils.scala new file mode 100644 index 00000000..036fb452 --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/TransformationUtils.scala @@ -0,0 +1,73 @@ +package io.rml.framework.core.function + +import java.io.File +import java.net.MalformedURLException + +import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.function.model.Parameter +import io.rml.framework.core.internal.Logging +import io.rml.framework.core.model.{Entity, Literal, Uri} +import io.rml.framework.core.vocabulary.RMLVoc +import io.rml.framework.shared.RMLException + +import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader + +object TransformationUtils extends Logging { + + + /** * + * TODO: IMPLEMENT THIS THE SCALA WAY SINCE TYPE ERASURE WILL CAUSE PROBLEM WITH REFLECTIONS IN SCALA + * + */ + /** + * See [[http://stackoverflow.com/questions/3216780/problem-reloading-a-jar-using-urlclassloader?lq=1]] + * for problems relating to unclosed dirty jar file handle if there ever was a need to reload the jar file + * at runtime. + * + * See [[http://stackoverflow.com/questions/8867766/forName()scala-dynamic-object-class-loading]] + * for loading in scala object using reflection + * + * See [[https://medium.com/@giposse/scala-reflection-d835832ed13a]] for a better scala reflection tutorial? + * + * @param jarFile + * @param className + * @return + */ + def loadClassFromJar(jarFile: File, className: String): Class[_] = { + logInfo(s"Loading $className from jar file $jarFile") + try { + val classloader = new URLClassLoader(List(jarFile.toURI.toURL), RMLEnvironment.getClass.getClassLoader) + logInfo(s"Class loader ${classloader.getParent}") + Class.forName(className, true, classloader) + } catch { + case e@(_: MalformedURLException | _: ClassNotFoundException) => + logError(e.getMessage) + throw e + } + } + + def typeCastDataType(output: Entity, dataType: Option[Uri]): Option[Entity] = { + if(dataType.isDefined){ + val typeClass = getTypeClass(dataType.get) + val castedValue = Parameter(typeClass, output.toString).getValue + + castedValue.map(e => Literal(e.toString)) + }else{ + Some(output) + } + } + + def getTypeClass(uri: Uri): Class[_] = { + uri match { + + case Uri(RMLVoc.Type.XSD_POSITIVE_INTEGER) => classOf[Int] + case Uri(RMLVoc.Type.XSD_INTEGER) => classOf[Int] + case Uri(RMLVoc.Type.XSD_STRING) => classOf[String] + case Uri(RMLVoc.Type.XSD_DOUBLE) => classOf[Double] + case Uri(RMLVoc.Type.RDF_LIST) => classOf[List[_]] + case _ => throw new RMLException(s"Type $uri not supported for parameter") + } + } + + +} diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala new file mode 100644 index 00000000..14ad6c44 --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala @@ -0,0 +1,81 @@ +package io.rml.framework.core.function.model + +import java.io.{File, IOException, ObjectInputStream, ObjectOutputStream} +import java.lang.reflect.Method + +import io.rml.framework.core.function.TransformationUtils +import io.rml.framework.core.model.{Entity, Literal, Uri} + + +/** + * A dynamic transformer which will use the functions of a class specified in an external jar + * The information needed to do reflection is contained inside the variable 'transientTransformation' of type [[TransientTransformation]] + * + * @param identifier [[String]] used to identify this DynamicTransformation + * @param metaData contains information required for method reflection + */ +case class DynamicMethodTransformation(identifier: String, metaData: TransientTransformation) extends Transformation { + + @transient + private var optMethod: Option[Method] = None + + @throws(classOf[IOException]) + private def writeObject(out: ObjectOutputStream): Unit = { + out.defaultWriteObject() + } + + override def initialize(): Transformation = { + if(optMethod.isEmpty) { + val jarFile = getClass.getClassLoader.getResource(metaData.source.toString).getFile + + val classOfMethod = TransformationUtils.loadClassFromJar(new File(jarFile), metaData.className) + val method = classOfMethod.getDeclaredMethod(metaData.methodName, metaData.inputParam.map(_.paramType): _*) + optMethod = Some(method) + } + this + + } + @throws(classOf[IOException]) + @throws(classOf[ClassNotFoundException]) + private def readObject(in: ObjectInputStream): Unit = { + in.defaultReadObject() + optMethod = None + initialize() + + } + + override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { + if (optMethod.isEmpty) { + throw new IllegalStateException(s"DynamicTransformation doesn't have the reflected method yet: ${this.identifier}") + } + + val inputParams = metaData.inputParam + // casted to List[AnyRef] since method.invoke(...) only accepts reference type but not primitive type of Scala + val paramsOrdered = inputParams + .flatMap(param => { + val value = arguments.get(param.paramUri) + value match { + case Some(string) => param.getValue(string) + case _ => None + } + }) + .map(_.asInstanceOf[AnyRef]) + + val outputParams = metaData.outputParam + + if (paramsOrdered.size == inputParams.size) { + val definiteMethod = optMethod.get + val output = definiteMethod.invoke(null, paramsOrdered: _*) + + val result = outputParams.flatMap(elem => elem.getValue(output))map(elem => Literal(elem.toString)) + + Some(result) + } else { + None + } + } + + override def getMethod: Option[Method] = { + optMethod + } +} diff --git a/src/main/scala/io/rml/framework/core/function/model/Parameter.scala b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala new file mode 100644 index 00000000..b8b6279a --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala @@ -0,0 +1,115 @@ +package io.rml.framework.core.function.model + +import io.rml.framework.core.model.{Node, Uri} + +import scala.util.parsing.json.JSON + +/** + * Case classes which could be useful in pattern matching empty parameter values + */ + +case class EmptyParameter(paramType: Class[_], paramUri: Uri, position: Int) extends Parameter { + override val paraValue: Option[String] = None + +} + +case class DefinedParameter(paramType: Class[_] = classOf[String], paramUri: Uri, paraValue: Option[String], position: Int) extends Parameter + + +abstract class Parameter extends Node { + /** + * Models the parameters used by the functions. + * + * `paramType` type of the parameter + * `paramUri` Uri representation of the parameter (as defined in functions.ttl) + * `paraValue` [[String]] representation of the parameter + * `position` [[Int]] position of the parameter in the argument of the function needed for reflection + * + */ + val paramType: Class[_] + val paramUri: Uri + val paraValue: Option[String] + val position: Int + + override def identifier: String = paramUri.toString + " " + paraValue.getOrElse("None") + + def getValue: Option[Any] = { + getValue(paraValue.getOrElse(throw new IllegalStateException(s"${this}'s value option is empty."))) + } + + /** + * Get the parameter value and cast it according to the given + * [[paramType]]. + * + * @return value of the parameter of type specified by [[paramType]] + */ + + def getValue(paraValue: Any): Option[Any] = { + val ScalaString = classOf[String].getName + val IntegerString = classOf[Int].getName + val DoubleString = classOf[Double].getName + val ListString = classOf[List[_]].getName + val ArrayString = classOf[Array[_]].getName + try { + paramType.getName match { + case ScalaString | "java.lang.String" => Some(paraValue.toString) + case IntegerString | "int" => Some(paraValue.toString.toInt) + case DoubleString | "double" => Some(paraValue.toString.toDouble) + case ListString | ArrayString | "java.util.List" => + + val parsedListEither = JSON.parseFull(paraValue.toString).toRight("Value can't be parsed as List") + + parsedListEither match { + case Right(parsed) => + parsed match { + case value: List[_] => + Some(value) + case _ => + None + } + case Left(exMessage) => throw new IllegalArgumentException(exMessage) + } + case _ => None + + } + }catch { + case _: Throwable => None + } + } + + +} + +/** + * OBJECT IMPLEMENTATION OF PARAMETER HERE + */ + +object Parameter { + /** + * Implicit default ordering which will be used to order lists/sequences of [[Parameter]] + * + * @tparam A subclasses of [[Parameter]] + */ + implicit def orderingByPosition[A <: Parameter]: Ordering[A] = { + Ordering.by(elem => elem.position) + } + + def apply(paramType: Class[_], paramUri: Uri, paraValue: String, position: Int): Parameter = { + DefinedParameter(paramType, paramUri, Some(paraValue), position) + } + + def apply(paramType:Class[_], paraValue:String): Parameter ={ + DefinedParameter(paramType, Uri(""),Some(paraValue), 0) + } + + + def apply(paramType: Class[_], paramUri: Uri, position: Int): Parameter = { + EmptyParameter(paramType, paramUri, position) + } + + def apply(paramUri: Uri, paraValue: String, position: Int): Parameter = { + DefinedParameter(paramUri = paramUri, paraValue = Some(paraValue), position = position) + } + +} + diff --git a/src/main/scala/io/rml/framework/core/function/model/Transformation.scala b/src/main/scala/io/rml/framework/core/function/model/Transformation.scala new file mode 100644 index 00000000..d4443fbe --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/model/Transformation.scala @@ -0,0 +1,28 @@ +package io.rml.framework.core.function.model + +import java.lang.reflect.Method + +import io.rml.framework.core.model.{Entity, Node, Uri} + +trait Transformation extends Node { + + + def name: Uri = Uri(identifier) + + def getMethod: Option[Method] + + //TODO: Doesn't support output of objects yet ! + // it currently only support string representable outputs! + def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] + + def initialize(): Transformation = this + +} + +object Transformation{ + + def apply(identifier:String, transientTransformation: TransientTransformation): Transformation={ + DynamicMethodTransformation(identifier, transientTransformation) + + } +} diff --git a/src/main/scala/io/rml/framework/core/function/model/TransientTransformation.scala b/src/main/scala/io/rml/framework/core/function/model/TransientTransformation.scala new file mode 100644 index 00000000..a84ecba1 --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/model/TransientTransformation.scala @@ -0,0 +1,36 @@ +package io.rml.framework.core.function.model + +import java.lang.reflect.Method + +import io.rml.framework.core.model.{Entity, Uri} + +/** + * A case class which is made to hold the string values of class and method names + * of a [[Transformation]] so that it can be initialized lazily later when needed in the rml mapping file + * + * @param source string path of the source + * @param className class name containing the [[Transformation]] + * @param methodName method name of the [[Transformation]] + * @param inputParam [[List]] of input parameters for the [[Transformation]] + * @param outputParam [[List]] of expected output parameters from the [[Transformation]] + */ +case class TransientTransformation(source: String, className: String, methodName: String, inputParam: List[Parameter], outputParam: List[Parameter]) extends + Transformation { + + override def initialize(): Transformation = { + Transformation(identifier, this) + } + + override def getMethod: Option[Method] = None + + override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = None + + /** + * Used as an id for each inheriting objects for debugging ( maybe equivalence checking? e.g. in TermMap and TripleMap). + * + * @return + */ + override def identifier: String = s"($source, $className, $methodName, $inputParam, $outputParam)" + + +} diff --git a/src/main/scala/io/rml/framework/core/function/model/std/StdRandomTransformation.scala b/src/main/scala/io/rml/framework/core/function/model/std/StdRandomTransformation.scala new file mode 100644 index 00000000..38ba6e31 --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/model/std/StdRandomTransformation.scala @@ -0,0 +1,21 @@ +package io.rml.framework.core.function.model.std + +import java.lang.reflect.Method + +import io.rml.framework.core.function.model.Transformation +import io.rml.framework.core.model.{Entity, Literal, Uri} +import io.rml.framework.core.vocabulary.RMLVoc + +import scala.util.Random + +case class StdRandomTransformation(identifier:String = RMLVoc.Property.GREL_RANDOM) extends Transformation{ + private val random = new Random() + + override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { + Some(List(Literal(random.nextString(10)))) + } + + override def getMethod: Option[Method] = { + None + } +} diff --git a/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseTransformation.scala b/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseTransformation.scala new file mode 100644 index 00000000..e2d1bd87 --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseTransformation.scala @@ -0,0 +1,19 @@ +package io.rml.framework.core.function.model.std + +import java.lang.reflect.Method + +import io.rml.framework.core.function.model.Transformation +import io.rml.framework.core.model.{Entity, Literal, Uri} +import io.rml.framework.core.vocabulary.{Namespaces, RMLVoc} + +case class StdUpperCaseTransformation(identifier: String = RMLVoc.Property.GREL_UPPERCASE) extends Transformation { + override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { + val parameter = arguments.get(Uri(Namespaces("grel", "valueParameter"))) + + parameter.map(string => List(Literal(string))) + } + + override def getMethod: Option[Method] = { + None + } +} diff --git a/src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala b/src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala new file mode 100644 index 00000000..5cd32ff2 --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala @@ -0,0 +1,66 @@ +package io.rml.framework.core.function.std + +import io.rml.framework.core.function.model.{Parameter, TransientTransformation} +import io.rml.framework.core.function.{TransformationLoader, TransformationUtils} +import io.rml.framework.core.model.Uri +import io.rml.framework.core.model.rdf.jena.JenaResource +import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode, RDFResource} +import io.rml.framework.core.util.{JenaUtil, Util} +import io.rml.framework.core.vocabulary.RMLVoc + +case class StdTransformationLoader() extends TransformationLoader { + + + override def parseTransformations(graph: RDFGraph): TransformationLoader = { + val transformationMaps = graph.filterProperties(Uri(RMLVoc.Property.LIB_PROVIDED_BY)) + + + for (map <- transformationMaps) { + + val providedByTermMap = map.listProperties(RMLVoc.Property.LIB_PROVIDED_BY).head.asInstanceOf[RDFResource] + + val libPath = providedByTermMap.listProperties(RMLVoc.Property.LIB_LOCAL_LIBRARY).flatMap(Util.getLiteral).headOption + val classNames = providedByTermMap.listProperties(RMLVoc.Property.LIB_CLASS).flatMap(Util.getLiteral) + val methodNames = providedByTermMap.listProperties(RMLVoc.Property.LIB_METHOD).flatMap(Util.getLiteral) + + if (libPath.nonEmpty && classNames.nonEmpty && methodNames.nonEmpty) { + + val classNameLit = classNames.head + val methodNameLit = methodNames.head + classLibraryMap.put(classNameLit.toString.trim, libPath.get.toString.trim) + + val inputParams = parseParameterList(map, RMLVoc.Property.FNO_EXPECTS).sorted + + + val outputParams = parseParameterList(map, RMLVoc.Property.FNO_RETURNS).sorted + + + val transformation = TransientTransformation(libPath.get.toString.trim, classNameLit.toString.trim, + methodNameLit.toString.trim, + inputParams, + outputParams + ) + + transformationMap.put(map.uri, transformation) + } + } + + this + } + + def parseParameterList(resource: RDFResource, property: String): List[Parameter] = { + JenaUtil + .parseListNodes(resource, property) + .map { case (node, pos) => parseParameter(node, pos) } + + } + + override def parseParameter(inputNode: RDFNode, pos: Int): Parameter = { + val inputResource = inputNode.asInstanceOf[JenaResource] + val paramType = inputResource.listProperties(RMLVoc.Property.FNO_TYPE).head.toString + val paramUri = inputResource.listProperties(RMLVoc.Property.FNO_PREDICATE).head.toString + val typeClass = TransformationUtils.getTypeClass(Uri(paramType)) + Parameter(typeClass, Uri(paramUri), pos) + } +} + diff --git a/src/main/scala/io/rml/framework/core/model/rdf/RDFResource.scala b/src/main/scala/io/rml/framework/core/model/rdf/RDFResource.scala index db427f92..d9784ce9 100644 --- a/src/main/scala/io/rml/framework/core/model/rdf/RDFResource.scala +++ b/src/main/scala/io/rml/framework/core/model/rdf/RDFResource.scala @@ -43,6 +43,9 @@ trait RDFResource extends RDFNode { def getType: Option[Uri] + + def getList: List[RDFNode] + /** * * @param property diff --git a/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala b/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala index 86ea3db6..de57a63b 100644 --- a/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala +++ b/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala @@ -29,7 +29,7 @@ import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.{RDFLiteral, RDFNode, RDFResource} import io.rml.framework.core.vocabulary.RDFVoc import org.apache.commons.lang3.builder.HashCodeBuilder -import org.apache.jena.rdf.model.Resource +import org.apache.jena.rdf.model.{RDFList, Resource} import scala.collection.JavaConverters._ @@ -127,7 +127,15 @@ class JenaResource(val resource: Resource) extends RDFResource { Some(types.head.asInstanceOf[RDFResource].uri) } + override def getList: List[RDFNode] = { + try { + val list = resource.as(classOf[RDFList]).asJavaList() + list.asScala.toList.map(JenaNode(_)) + } catch { + case _: Exception => List(JenaNode(resource)) + } + } } object JenaResource { diff --git a/src/main/scala/io/rml/framework/core/util/JenaUtil.scala b/src/main/scala/io/rml/framework/core/util/JenaUtil.scala index a0f7396e..e02bf4c8 100644 --- a/src/main/scala/io/rml/framework/core/util/JenaUtil.scala +++ b/src/main/scala/io/rml/framework/core/util/JenaUtil.scala @@ -28,6 +28,7 @@ package io.rml.framework.core.util import java.io.ByteArrayOutputStream import java.nio.charset.StandardCharsets +import io.rml.framework.core.model.rdf.{RDFNode, RDFResource} import org.apache.jena.query.{Dataset, DatasetFactory} import org.apache.jena.rdf.model.Model import org.apache.jena.riot.{Lang, RDFFormat, RDFParser} @@ -46,6 +47,14 @@ object JenaUtil { } } + def parseListNodes(rdf: RDFResource, property:String): List[(RDFNode, Int)] = { + rdf.listProperties(property) + .head + .asInstanceOf[RDFResource] + .getList + .zipWithIndex + } + def toRDFFormat(format: Format): RDFFormat = { format match { case Turtle => RDFFormat.TURTLE diff --git a/src/main/scala/io/rml/framework/core/util/Util.scala b/src/main/scala/io/rml/framework/core/util/Util.scala index 016098a3..780279fa 100644 --- a/src/main/scala/io/rml/framework/core/util/Util.scala +++ b/src/main/scala/io/rml/framework/core/util/Util.scala @@ -31,7 +31,7 @@ import java.nio.file.{Files, Paths} import java.util.regex.Pattern import io.rml.framework.core.extractors.MappingReader -import io.rml.framework.core.model.FormattedRMLMapping +import io.rml.framework.core.model.{FormattedRMLMapping, Literal, Node} import io.rml.framework.shared.ReadException import scala.collection.mutable.ListBuffer @@ -45,6 +45,12 @@ object Util { private val baseDirectiveCapture = "@base <([^<>]*)>.*".r + def getLiteral(node: Node):Option[Literal]= { + node match{ + case lit:Literal => Some(lit) + case _ => None + } + } /** * Check if conforming to https://tools.ietf.org/html/bcp47#section-2.2.9 diff --git a/src/main/scala/io/rml/framework/core/vocabulary/Namespaces.scala b/src/main/scala/io/rml/framework/core/vocabulary/Namespaces.scala index a7ce752c..79485e58 100644 --- a/src/main/scala/io/rml/framework/core/vocabulary/Namespaces.scala +++ b/src/main/scala/io/rml/framework/core/vocabulary/Namespaces.scala @@ -38,7 +38,10 @@ object Namespaces { "rml" -> "http://semweb.mmlab.be/ns/rml#", "rmls" -> "http://semweb.mmlab.be/ns/rmls#", "fnml" -> "http://semweb.mmlab.be/ns/fnml#", - "fno" -> "http://w3id.org/function/ontology#" + "fno" -> "http://w3id.org/function/ontology#", + "grel" -> "http://users.ugent.be/~bjdmeest/function/grel.ttl#", + "lib" -> "http://example.com/library#", + "xsd" -> "http://www.w3.org/2001/XMLSchema#" ) /** diff --git a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala index 2b7eb90d..25db748c 100644 --- a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala +++ b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala @@ -30,6 +30,15 @@ package io.rml.framework.core.vocabulary */ object RMLVoc { + object Type { + val XSD_STRING = Namespaces("xsd", "string") + val XSD_INTEGER = Namespaces("xsd", "integer") + val XSD_DOUBLE = Namespaces("xsd", "decimal") + val RDF_LIST = Namespaces("rdf", "List") + val XSD_POSITIVE_INTEGER = Namespaces("xsd", "positiveInteger") + + } + object Property { /////////////////////////////////////////////////////////////////////////// @@ -84,6 +93,13 @@ object RMLVoc { val KAFKAVERSION= Namespaces("rmls", "kafkaVersion") + /////////////////////////////////////////////////////////////////////////// + // GREL + /////////////////////////////////////////////////////////////////////////// + val GREL_RANDOM = Namespaces("grel", "random") + val GREL_UPPERCASE = Namespaces("grel", "toUpperCase") + + /////////////////////////////////////////////////////////////////////////// // FNML /////////////////////////////////////////////////////////////////////////// @@ -95,6 +111,22 @@ object RMLVoc { /////////////////////////////////////////////////////////////////////////// val EXECUTES = Namespaces("fno", "executes") + val FNO_SOLVES = Namespaces("fno", "solves") + val FNO_IMPLEMENTS = Namespaces("fno", "implements") + val FNO_PREDICATE = Namespaces("fno", "predicate") + val FNO_EXPECTS = Namespaces("fno", "expects") + val FNO_RETURNS = Namespaces("fno", "returns") + val FNO_TYPE = Namespaces("fno", "type") + + + /////////////////////////////////////////////////////////////////////////// + // LIB + /////////////////////////////////////////////////////////////////////////// + + val LIB_PROVIDED_BY = Namespaces("lib", "providedBy") + val LIB_CLASS = Namespaces("lib", "class") + val LIB_METHOD = Namespaces("lib", "method") + val LIB_LOCAL_LIBRARY = Namespaces("lib", "localLibrary") } @@ -132,6 +164,17 @@ object RMLVoc { val FUNCTIONTERMMAP = Namespaces("fnml", "FunctionTermMap") + /////////////////////////////////////////////////////////////////////////// + // FNO + /////////////////////////////////////////////////////////////////////////// + val FNO_FUNCTION = Namespaces("fno", "Function") + val FNO_PARAMETER = Namespaces("fno", "Parameter") + val FNO_EXECUTION = Namespaces("fno", "Execution") + val FNO_OUTPUT = Namespaces("fno", "Output") + val FNO_ALGORITHM = Namespaces("fno", "Algorithm") + val FNO_PROBLEM = Namespaces("fno", "Problem") + + } } diff --git a/src/main/scala/io/rml/framework/flink/sink/FlinkResource.scala b/src/main/scala/io/rml/framework/flink/sink/FlinkResource.scala index cfc4fe09..a6e7aa4a 100644 --- a/src/main/scala/io/rml/framework/flink/sink/FlinkResource.scala +++ b/src/main/scala/io/rml/framework/flink/sink/FlinkResource.scala @@ -24,7 +24,7 @@ **/ package io.rml.framework.flink.sink -import io.rml.framework.core.model.rdf.{RDFLiteral, RDFResource} +import io.rml.framework.core.model.rdf.{RDFLiteral, RDFNode, RDFResource} class FlinkResource extends RDFResource { /** @@ -65,4 +65,6 @@ class FlinkResource extends RDFResource { override def uri = ??? override def getType = ??? + + override def getList: List[RDFNode] = ??? } From 96b95ef7230ce28483aa6c8970adceef11722485 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 27 May 2020 18:10:49 +0200 Subject: [PATCH 003/169] wip: integration function feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Applied adjustments to function_map_dev_gdm according to the code at branch function_map_gdm. So the RMLException might be gone, but we’re still stuck with the output generation test failures. I think the the triplesmaps aren’t extracted correctly yet (no functionmap is being extracted/detected) --- src/main/scala/io/rml/framework/Main.scala | 3 +- .../extractors/FunctionMapExtractor.scala | 111 +++++++++++++----- .../core/extractors/ObjectMapExtractor.scala | 4 +- .../extractors/PredicateMapExtractor.scala | 3 +- .../core/extractors/ResourceExtractor.scala | 4 +- .../std/StdFunctionMapExtractor.scala | 55 +++++++++ .../std/StdObjectMapExtractor.scala | 39 ++++-- .../std/StdPredicateMapExtractor.scala | 7 +- .../std/StdPredicateObjectMapExtractor.scala | 11 +- .../std/StdSubjectMapExtractor.scala | 6 +- .../std/StdTriplesMapExtractor.scala | 1 + .../rml/framework/core/internal/Logging.scala | 2 +- .../core/model/FormattedRMLMapping.scala | 4 +- .../framework/core/model/FunctionMap.scala | 3 +- .../rml/framework/core/model/ObjectMap.scala | 2 + .../framework/core/model/PredicateMap.scala | 2 + .../core/model/PredicateObjectMap.scala | 6 +- .../rml/framework/core/model/SubjectMap.scala | 3 +- .../core/model/rdf/RDFResource.scala | 3 +- .../core/model/rdf/jena/JenaResource.scala | 35 ++++-- .../core/model/std/StdObjectMap.scala | 1 + .../core/model/std/StdPredicateMap.scala | 1 + .../model/std/StdPredicateObjectMap.scala | 1 - .../core/model/std/StdSubjectMap.scala | 1 + .../FunctionMapGeneratorAssembler.scala | 83 +++++++++++-- .../PredicateObjectGeneratorAssembler.scala | 14 +-- .../engine/statement/StatementEngine.scala | 2 +- .../statement/StatementsAssembler.scala | 6 +- .../RMLFNOTC0000-CSV/mapping.ttl | 36 ++++++ .../fno-testcases/RMLFNOTC0000-CSV/output.ttl | 1 + .../RMLFNOTC0001-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0001-CSV/output.ttl | 1 + .../RMLFNOTC0002-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0002-CSV/output.ttl | 1 + .../RMLFNOTC0003-CSV/mapping.ttl | 42 +++++++ .../fno-testcases/RMLFNOTC0003-CSV/output.ttl | 1 + .../RMLFNOTC0004-CSV/mapping.ttl | 40 +++++++ .../fno-testcases/RMLFNOTC0004-CSV/output.ttl | 1 + .../RMLFNOTC0005-CSV/mapping.ttl | 38 ++++++ .../fno-testcases/RMLFNOTC0005-CSV/output.ttl | 1 + .../RMLFNOTC0005-CSV/student.csv | 2 + .../RMLFNOTC0006-CSV/mapping.ttl | 41 +++++++ .../fno-testcases/RMLFNOTC0006-CSV/output.nq | 1 + .../RMLFNOTC0007-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0007-CSV/output.ttl | 0 .../RMLFNOTC0008-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0008-CSV/output.ttl | 1 + .../RMLFNOTC0011-CSV/mapping.ttl | 40 +++++++ .../fno-testcases/RMLFNOTC0011-CSV/output.ttl | 0 .../RMLFNOTC0012-CSV/mapping.ttl | 36 ++++++ .../fno-testcases/RMLFNOTC0012-CSV/output.ttl | 0 .../RMLFNOTC0013-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0013-CSV/output.ttl | 1 + .../RMLFNOTC0014-CSV/mapping.ttl | 38 ++++++ .../fno-testcases/RMLFNOTC0014-CSV/output.ttl | 1 + .../RMLFNOTC0015-CSV/mapping.ttl | 40 +++++++ .../fno-testcases/RMLFNOTC0015-CSV/output.ttl | 1 + .../RMLFNOTC0016-CSV/mapping.ttl | 41 +++++++ .../fno-testcases/RMLFNOTC0016-CSV/output.nq | 1 + .../fno-testcases/RMLFNOTC0018-CSV/data.csv | 2 + .../RMLFNOTC0018-CSV/mapping.ttl | 52 ++++++++ .../fno-testcases/RMLFNOTC0018-CSV/output.ttl | 1 + .../RMLFNOTC0021-JSON/books.json | 8 ++ .../RMLFNOTC0021-JSON/mapping.ttl | 33 ++++++ .../RMLFNOTC0021-JSON/output.ttl | 7 ++ src/test/resources/fno-testcases/student.csv | 2 + .../RMLFNOTC0000-CSV/mapping.ttl | 36 ++++++ .../RMLFNOTC0000-CSV/mapping_explicit.ttl | 37 ++++++ .../fno-testcases/RMLFNOTC0000-CSV/output.ttl | 1 + .../RMLFNOTC0001-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0001-CSV/output.ttl | 1 + .../RMLFNOTC0002-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0002-CSV/output.ttl | 1 + .../RMLFNOTC0003-CSV/mapping.ttl | 42 +++++++ .../fno-testcases/RMLFNOTC0003-CSV/output.ttl | 1 + .../RMLFNOTC0004-CSV/mapping.ttl | 40 +++++++ .../fno-testcases/RMLFNOTC0004-CSV/output.ttl | 1 + .../RMLFNOTC0005-CSV/mapping.ttl | 38 ++++++ .../fno-testcases/RMLFNOTC0005-CSV/output.ttl | 1 + .../RMLFNOTC0005-CSV/student.csv | 2 + .../RMLFNOTC0006-CSV/mapping.ttl | 41 +++++++ .../fno-testcases/RMLFNOTC0006-CSV/output.nq | 1 + .../RMLFNOTC0007-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0007-CSV/output.ttl | 0 .../RMLFNOTC0008-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0008-CSV/output.ttl | 1 + .../RMLFNOTC0011-CSV/mapping.ttl | 40 +++++++ .../fno-testcases/RMLFNOTC0011-CSV/output.ttl | 0 .../RMLFNOTC0012-CSV/mapping.ttl | 36 ++++++ .../fno-testcases/RMLFNOTC0012-CSV/output.ttl | 0 .../RMLFNOTC0013-CSV/mapping.ttl | 39 ++++++ .../fno-testcases/RMLFNOTC0013-CSV/output.ttl | 1 + .../RMLFNOTC0014-CSV/mapping.ttl | 38 ++++++ .../fno-testcases/RMLFNOTC0014-CSV/output.ttl | 1 + .../RMLFNOTC0015-CSV/mapping.ttl | 40 +++++++ .../fno-testcases/RMLFNOTC0015-CSV/output.ttl | 1 + .../RMLFNOTC0016-CSV/mapping.ttl | 41 +++++++ .../fno-testcases/RMLFNOTC0016-CSV/output.nq | 1 + .../fno-testcases/RMLFNOTC0018-CSV/data.csv | 2 + .../RMLFNOTC0018-CSV/mapping.ttl | 52 ++++++++ .../fno-testcases/RMLFNOTC0018-CSV/output.ttl | 1 + .../RMLFNOTC0021-JSON/books.json | 8 ++ .../RMLFNOTC0021-JSON/mapping.ttl | 33 ++++++ .../RMLFNOTC0021-JSON/output.ttl | 7 ++ .../sandbox/fno-testcases/student.csv | 2 + .../rml/framework/OutputGenerationTest.scala | 23 +++- .../scala/io/rml/framework/SandboxTests.scala | 88 ++++++++++++++ 107 files changed, 1876 insertions(+), 97 deletions(-) create mode 100644 src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0000-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0007-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0012-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0014-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0015-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0016-CSV/output.nq create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0018-CSV/data.csv create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0021-JSON/books.json create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl create mode 100644 src/test/resources/fno-testcases/student.csv create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/output.nq create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/output.nq create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/data.csv create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/books.json create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/output.ttl create mode 100644 src/test/resources/sandbox/fno-testcases/student.csv create mode 100644 src/test/scala/io/rml/framework/SandboxTests.scala diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index 2163d029..20008055 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -374,6 +374,7 @@ object Main extends Logging { senv: StreamExecutionEnvironment, postProcessor: PostProcessor): DataSet[String] = { + this.logInfo("createDataSetFromFormattedMapping(...)") require(!postProcessor.isInstanceOf[AtMostOneProcessor], "Bulk output and JSON-LD output are not supported in the static version") /** @@ -419,7 +420,7 @@ object Main extends Logging { (implicit env: ExecutionEnvironment, senv: StreamExecutionEnvironment, postProcessor: PostProcessor): DataSet[String] = { - + this.logInfo("createStandardTriplesMapPipeline(standard triples maps..)") // group triple maps by logical sources val grouped = standardTriplesMaps.groupBy(triplesMap => triplesMap.logicalSource) diff --git a/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala index 90b84472..28cd98ff 100644 --- a/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala @@ -24,47 +24,98 @@ **/ package io.rml.framework.core.extractors +import io.rml.framework.core.extractors.std.{StdFunctionMapExtractor, TermMapExtractor} import io.rml.framework.core.model.rdf.{RDFLiteral, RDFResource} import io.rml.framework.core.model.{FunctionMap, Uri} import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.shared.RMLException -case class FunctionMapExtractor() extends ResourceExtractor[List[FunctionMap]] { +trait FunctionMapExtractor extends TermMapExtractor[List[FunctionMap]] { + /** + * Extract. + * + * @param node Node to extract from. + * @return + */ + override def extract(node: RDFResource): List[FunctionMap] - lazy val triplesMapExtractor: TriplesMapExtractor = TriplesMapExtractor() - /** - * Extract. - * - * @param node Node to extract from. - * @return - */ - override def extract(node: RDFResource): List[FunctionMap] = { - val properties = node.listProperties(RMLVoc.Property.OBJECTMAP) - properties.flatMap { - case literal: RDFLiteral => - throw new RMLException(literal.toString + - ": A literal cannot be converted to a predicate object map") - case resource: RDFResource => - resource.getType match { - case Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)) => Some(extractFunctionMap(resource)) - case _ => None - } + def loadFunctionsIntoEnvironment():Unit +} - } - } - private def extractFunctionMap(resource: RDFResource): FunctionMap = { - val functionValues = resource.listProperties(RMLVoc.Property.FUNCTIONVALUE) - require(functionValues.size == 1, "Only 1 function value allowed.") - require(functionValues.head.isInstanceOf[RDFResource], "FunctionValue must be a resource.") +object FunctionMapExtractor { - val functionValue = functionValues.head.asInstanceOf[RDFResource] - val triplesMap = triplesMapExtractor.extractTriplesMapProperties(functionValue) - require(triplesMap.isDefined) - FunctionMap(functionValue.uri.toString, triplesMap.get) - } + def apply(logicalSourceExtractor: LogicalSourceExtractor = LogicalSourceExtractor(), + subjectMapExtractor: SubjectMapExtractor = SubjectMapExtractor()):FunctionMapExtractor = { + + new StdFunctionMapExtractor(subjectMapExtractor, logicalSourceExtractor) + } } + +//case class FunctionMapExtractor() extends ResourceExtractor[List[FunctionMap]] { +// +// lazy val triplesMapExtractor: TriplesMapExtractor = TriplesMapExtractor() +// +// /** +// * Extract. +// * +// * @param node Node to extract from. +// * @return +// */ +// override def extract(node: RDFResource): List[FunctionMap] = { +// +// +// val properties = node.listProperties(RMLVoc.Property.OBJECTMAP) // : Seq[RDFNode] +// +// +// /** +// * Note: object-maps pointing to a resource with type fnml:FunctionTermMap are matched as FunctionTermMaps. +// * However, it's not always the case that resource are explicitely defined as " a fnml:FunctionTermMap". +// * Therefore, a resource should also be considered a FunctionTermMap when it points to a +// * resource with a fnml:functionValue property. +// * +// * TODO: what's the type of properties element when not explicitly defining functiontermmap type +// * --> it turns out that resource.getType is None when not explicitely defining the function term map type +// */ +// +// properties.flatMap { +// case literal: RDFLiteral => +// throw new RMLException(literal.toString + +// ": A literal cannot be converted to a predicate object map") +// +// case resource: RDFResource => +// resource.getType match { +// case Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)) => Some(extractFunctionMap(resource)) +// case _ => { +// // if resource hasn't a type specified, check whether it has the function value property +// val functionValueProperties = resource.listProperties(Uri(RMLVoc.Property.FUNCTIONVALUE).toString) +// if(functionValueProperties.nonEmpty) +// Some(extractFunctionMap(resource)) +// else +// None +// } +// } +// } +// } +// +// private def extractFunctionMap(resource: RDFResource): FunctionMap = { +// logInfo("%s extractFunctionMap ".format(this.getClass.getName)) +// val functionValues = resource.listProperties(RMLVoc.Property.FUNCTIONVALUE) +// +// // TODO: [SUGGESTION] extract function map requirement checking into private method to separate extraction from +// // validating the spec-rules -- thoughts? +// require(functionValues.size == 1, "Only 1 function value allowed.") +// require(functionValues.head.isInstanceOf[RDFResource], "FunctionValue must be a resource.") +// +// val functionValue = functionValues.head.asInstanceOf[RDFResource] +// val triplesMap = triplesMapExtractor.extractTriplesMapProperties(functionValue) +// require(triplesMap.isDefined) +// //FunctionMap(functionValue.uri.toString, triplesMap.get) +// throw new NotImplementedError() +// } +// +//} diff --git a/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala index 2f3e0871..8ebbe5b9 100644 --- a/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala @@ -30,5 +30,7 @@ import io.rml.framework.core.model.ObjectMap trait ObjectMapExtractor extends TermMapExtractor[List[ObjectMap]] object ObjectMapExtractor { - def apply(): ObjectMapExtractor = new StdObjectMapExtractor +// def apply(): ObjectMapExtractor = new StdObjectMapExtractor +def apply(functionMapExtractor: FunctionMapExtractor = FunctionMapExtractor()): ObjectMapExtractor = + new StdObjectMapExtractor(functionMapExtractor) } diff --git a/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala index 93e07d40..fab6fd3a 100644 --- a/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala @@ -31,7 +31,8 @@ import io.rml.framework.core.model.PredicateMap trait PredicateMapExtractor extends TermMapExtractor[List[PredicateMap]] object PredicateMapExtractor { - def apply(): PredicateMapExtractor = new StdPredicateMapExtractor() + def apply(functionMapExtractor: FunctionMapExtractor = FunctionMapExtractor()): PredicateMapExtractor = new StdPredicateMapExtractor(functionMapExtractor) + //def apply(): PredicateMapExtractor = new StdPredicateMapExtractor() } diff --git a/src/main/scala/io/rml/framework/core/extractors/ResourceExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/ResourceExtractor.scala index 2ffee8d4..4f36198a 100644 --- a/src/main/scala/io/rml/framework/core/extractors/ResourceExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/ResourceExtractor.scala @@ -26,5 +26,5 @@ package io.rml.framework.core.extractors import io.rml.framework.core.model.rdf.RDFResource - -trait ResourceExtractor[T] extends Extractor[RDFResource, T] +import io.rml.framework.core.internal.Logging +trait ResourceExtractor[T] extends Extractor[RDFResource, T] with Logging diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala new file mode 100644 index 00000000..a2df75ad --- /dev/null +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala @@ -0,0 +1,55 @@ +package io.rml.framework.core.extractors.std + +import io.rml.framework.core.extractors.{FunctionMapExtractor, LogicalSourceExtractor, PredicateObjectMapExtractor, SubjectMapExtractor} +import io.rml.framework.core.model.FunctionMap +import io.rml.framework.core.model.rdf.RDFResource +import io.rml.framework.core.vocabulary.RMLVoc + +class StdFunctionMapExtractor(subjectMapExtractor: SubjectMapExtractor, + logicalSourceExtractor: LogicalSourceExtractor) extends FunctionMapExtractor { + + /** + * Lazy val to prevent circular reference and stack overflow when instantiating the class + */ + lazy val pomExtractor = PredicateObjectMapExtractor() + + + /** + * Extract. + * + * @param node Node to extract from. + * @return + */ + override def extract(node: RDFResource): List[FunctionMap] = { + this.logInfo("%s extract(node)".format(this.getClass.getName)) + extractFunctionMap("", node) + } + + + /** + * Extracts function term map in the mapping file and + * load the function specified into the static RMLEnvironment class + * + * @param resource + * @return + */ + private def extractFunctionMap(fnParentMap: String, resource: RDFResource): List[FunctionMap] = { + val functionValues = resource.listProperties(RMLVoc.Property.FUNCTIONVALUE) + + require(functionValues.size <= 1, "At most only 1 function value allowed.") + val result = functionValues.map(node => { + val functionValue = node.asInstanceOf[RDFResource] + + val poms = pomExtractor.extract(functionValue) + + FunctionMap(fnParentMap, functionValue.uri.toString, poms) + //throw new NotImplementedError() + }) + + result + } + + override def loadFunctionsIntoEnvironment(): Unit = { + throw new NotImplementedError() + } +} diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala index 0cfeb4b2..8d49b761 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala @@ -25,14 +25,14 @@ package io.rml.framework.core.extractors.std -import io.rml.framework.core.extractors.{JoinConditionExtractor, ObjectMapExtractor, TriplesMapExtractor} +import io.rml.framework.core.extractors.{FunctionMapExtractor, JoinConditionExtractor, ObjectMapExtractor, TriplesMapExtractor} import io.rml.framework.core.model._ import io.rml.framework.core.model.rdf.{RDFLiteral, RDFResource} import io.rml.framework.core.util.Util import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.shared.RMLException -class StdObjectMapExtractor extends ObjectMapExtractor { +class StdObjectMapExtractor(stdFunctionMapExtractor: FunctionMapExtractor) extends ObjectMapExtractor { /** * Extract. * @@ -69,6 +69,7 @@ class StdObjectMapExtractor extends ObjectMapExtractor { * @return */ private def extractObjectMaps(resource: RDFResource): List[ObjectMap] = { + this.logInfo("%s extractObjectMaps(resource)".format(this.getClass.getName)) val property = RMLVoc.Property.OBJECTMAP val properties = resource.listProperties(property) @@ -76,11 +77,24 @@ class StdObjectMapExtractor extends ObjectMapExtractor { properties.flatMap { case literal: RDFLiteral => throw new RMLException(literal.toString + ": Cannot convert literal to predicate map.") - case resource: RDFResource => resource.getType match { - case Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)) => None // TODO: rethink this - case _ => Some(extractObjectMap(resource)) + case resource: RDFResource => Some(extractObjectMap(resource)) } - } + + +// //case resource: RDFResource => Some(extractObjectMap(resource)) +// case resource: RDFResource => { +// // if resource hasn't a type specified, check whether it has the function value property +// val functionValueProperties = resource.listProperties(Uri(RMLVoc.Property.FUNCTIONVALUE).toString) +// if(functionValueProperties.nonEmpty | resource.getType.eq(Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)))) +// None +// else +// Some(extractObjectMap(resource)) +// } +// // case resource.getType match { +// // case Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)) => None // TODO: rethink this +// // case _ => Some(extractObjectMap(resource)) +// // } +// } } @@ -102,8 +116,8 @@ class StdObjectMapExtractor extends ObjectMapExtractor { val joinCondition = extractJoinCondition(resource) val language = extractLanguage(resource) val datatype = extractDatatype(resource) - - ObjectMap(resource.uri.toString, constant, reference, template, termType, datatype, language, parentTriplesMap, joinCondition) + val functionMap = stdFunctionMapExtractor.extract(resource) + ObjectMap(resource.uri.toString, functionMap, constant, reference, template, termType, datatype, language, parentTriplesMap, joinCondition) } def extractDatatype(resource: RDFResource): Option[Uri] = { @@ -137,10 +151,15 @@ class StdObjectMapExtractor extends ObjectMapExtractor { } else { // if this is a reference-based term map or contains an referenceFormulation or has a datatype property the + // or has a functionValue property or a template without term type, the // term type is a literal - val elements = resource.listProperties(RMLVoc.Property.REFERENCE) ++ + val elements = + resource.listProperties(RMLVoc.Property.REFERENCE) ++ resource.listProperties(RMLVoc.Property.REFERENCEFORMULATION) ++ - resource.listProperties(RMLVoc.Property.DATATYPE) + resource.listProperties(RMLVoc.Property.DATATYPE) ++ + resource.listProperties(RMLVoc.Property.FUNCTIONVALUE) ++ + resource.listProperties(RMLVoc.Property.TEMPLATE) + if (elements.nonEmpty) Some(Uri(RMLVoc.Class.LITERAL)) else Some(Uri(RMLVoc.Class.IRI)) } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala index e3858736..d1fef25b 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala @@ -25,13 +25,13 @@ package io.rml.framework.core.extractors.std -import io.rml.framework.core.extractors.PredicateMapExtractor +import io.rml.framework.core.extractors.{FunctionMapExtractor, PredicateMapExtractor} import io.rml.framework.core.model.rdf.{RDFLiteral, RDFResource} import io.rml.framework.core.model.{PredicateMap, Uri} import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.shared.RMLException -class StdPredicateMapExtractor extends PredicateMapExtractor { +class StdPredicateMapExtractor(functionMapExtractor: FunctionMapExtractor) extends PredicateMapExtractor { /** * Extract. * @@ -91,7 +91,8 @@ class StdPredicateMapExtractor extends PredicateMapExtractor { val template = extractTemplate(resource) val constant = extractConstant(resource) val reference = extractReference(resource) - PredicateMap(resource.uri.toString, constant, reference, template, termType) + val functionMap = functionMapExtractor.extract(resource) + PredicateMap(resource.uri.toString, functionMap, constant, reference, template, termType) } } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala index bb53ae6f..aa88ae4b 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala @@ -73,11 +73,20 @@ class StdPredicateObjectMapExtractor(predicateMapExtractor: PredicateMapExtracto * @return */ private def extractPredicateObjectMap(resource: RDFResource): PredicateObjectMap = { + this.logInfo("%s extractPredicateObjectMap : extracting object maps".format(this.getClass.getName)) val objectMaps = objectMapExtractor.extract(resource) + + this.logInfo("%s extractPredicateObjectMap : extracting function maps".format(this.getClass.getName)) val functionMaps = functionMapExtractor.extract(resource) + + this.logInfo("%s extractPredicateObjectMap : extracting predicate maps".format(this.getClass.getName)) val predicateMaps = predicateMapExtractor.extract(resource) + + this.logInfo("%s extractPredicateObjectMap : extracting graph map".format(this.getClass.getName)) val graphMap = graphMapExtractor.extract(resource) - PredicateObjectMap(resource.uri.toString, objectMaps, functionMaps, predicateMaps, graphMap) + + this.logInfo("%s extractPredicateObjectMap : returning resulting PredicateObjectMap".format(this.getClass.getName)) + PredicateObjectMap(resource.uri.toString, objectMaps, predicateMaps, graphMap) } } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdSubjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdSubjectMapExtractor.scala index aa185db9..58f8f377 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdSubjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdSubjectMapExtractor.scala @@ -25,7 +25,7 @@ package io.rml.framework.core.extractors.std -import io.rml.framework.core.extractors.{GraphMapExtractor, SubjectMapExtractor} +import io.rml.framework.core.extractors.{FunctionMapExtractor, GraphMapExtractor, SubjectMapExtractor} import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.rdf.{RDFLiteral, RDFResource} import io.rml.framework.core.model.{Literal, SubjectMap, Uri} @@ -83,6 +83,8 @@ class StdSubjectMapExtractor(graphMapExtractor: GraphMapExtractor) extends Subje val termType = extractTermType(resource) val graphMap = graphMapExtractor.extract(resource) + val functionMap = FunctionMapExtractor().extract(resource) + logDebug(resource.uri + ": Extracted from subject map" + ": reference -> " + reference + ", constant -> " + constant + @@ -91,7 +93,7 @@ class StdSubjectMapExtractor(graphMapExtractor: GraphMapExtractor) extends Subje ", graphMap -> " + graphMap + ", class -> " + _class) - SubjectMap(resource.uri.toString, _class, constant, reference, template, termType, graphMap) + SubjectMap(resource.uri.toString, _class, functionMap, constant, reference, template, termType, graphMap) } override def extractTermType(resource: RDFResource): Option[Uri] = { diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala index c0046f66..fa8ad98e 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala @@ -66,6 +66,7 @@ class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, */ private def filterTriplesMaps(graph: RDFGraph): List[RDFResource] = { + // filter all triple map resources from the graph val typeUri = Uri(RMLVoc.Class.TRIPLESMAP) val triplesMapResources = (graph.filterResources(typeUri) ++ diff --git a/src/main/scala/io/rml/framework/core/internal/Logging.scala b/src/main/scala/io/rml/framework/core/internal/Logging.scala index 5bdf4038..097ca8a7 100644 --- a/src/main/scala/io/rml/framework/core/internal/Logging.scala +++ b/src/main/scala/io/rml/framework/core/internal/Logging.scala @@ -45,7 +45,7 @@ trait Logging { def logWarning(log: String): Unit = logger.warn(log) - def isDebugEnabled: Boolean = logger.isDebugEnabled + def isDebugEnabled: Boolean = logger.isDebugEnabled() def isWarnEnabled: Boolean = logger.isWarnEnabled() diff --git a/src/main/scala/io/rml/framework/core/model/FormattedRMLMapping.scala b/src/main/scala/io/rml/framework/core/model/FormattedRMLMapping.scala index 1fcbb3f1..03f0c6a5 100644 --- a/src/main/scala/io/rml/framework/core/model/FormattedRMLMapping.scala +++ b/src/main/scala/io/rml/framework/core/model/FormattedRMLMapping.scala @@ -135,7 +135,7 @@ object FormattedRMLMapping { // create new poms from these grouped poms by parent triple maps .flatMap(item => { - item._2.map(item => PredicateObjectMap(item._1.identifier, List(item._2), item._1.functionMaps, item._1.predicateMaps, item._1.graphMap)) + item._2.map(item => PredicateObjectMap(item._1.identifier, List(item._2), item._1.predicateMaps, item._1.graphMap)) }) // every new pom will have exactly one parent triple map, create a JoinedTriplesMap from these poms newPoms.map(pom => { @@ -157,7 +157,7 @@ object FormattedRMLMapping { .filter(item => item._1.isEmpty) .flatMap(item => { item._2.map(item => { - PredicateObjectMap(item._1.identifier, List(item._2), item._1.functionMaps, item._1.predicateMaps,item._1.graphMap) + PredicateObjectMap(item._1.identifier, List(item._2), item._1.predicateMaps,item._1.graphMap) }) }) TriplesMap(newPoms.toList, triplesMap.logicalSource, triplesMap.subjectMap, triplesMap.identifier) diff --git a/src/main/scala/io/rml/framework/core/model/FunctionMap.scala b/src/main/scala/io/rml/framework/core/model/FunctionMap.scala index 8e510845..e2fa8550 100644 --- a/src/main/scala/io/rml/framework/core/model/FunctionMap.scala +++ b/src/main/scala/io/rml/framework/core/model/FunctionMap.scala @@ -24,7 +24,8 @@ **/ package io.rml.framework.core.model -case class FunctionMap(identifier: String, functionValue: TriplesMap) extends TermMap { +case class FunctionMap(parentMap : String, identifier: String, functionValue: List[PredicateObjectMap]) extends TermMap { + /** * diff --git a/src/main/scala/io/rml/framework/core/model/ObjectMap.scala b/src/main/scala/io/rml/framework/core/model/ObjectMap.scala index 4c5b981d..6bc5726f 100644 --- a/src/main/scala/io/rml/framework/core/model/ObjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/ObjectMap.scala @@ -46,6 +46,7 @@ case class JoinCondition(child: Literal, parent: Literal) // TODO: make this a t object ObjectMap { def apply(identifier: String, + functionMap: List[FunctionMap] = List(), constant: Option[Entity] = None, reference: Option[Literal] = None, template: Option[Literal] = None, @@ -56,6 +57,7 @@ object ObjectMap { joinCondition: Option[JoinCondition] = None): ObjectMap = StdObjectMap(identifier, + functionMap, constant, reference, template, diff --git a/src/main/scala/io/rml/framework/core/model/PredicateMap.scala b/src/main/scala/io/rml/framework/core/model/PredicateMap.scala index 14a4cb5b..6fd3e323 100644 --- a/src/main/scala/io/rml/framework/core/model/PredicateMap.scala +++ b/src/main/scala/io/rml/framework/core/model/PredicateMap.scala @@ -39,12 +39,14 @@ trait PredicateMap extends TermMap object PredicateMap { def apply(identifier: String, + functionMap: List[FunctionMap] = List(), constant: Option[Entity] = None, reference: Option[Literal] = None, template: Option[Literal] = None, termType: Option[Uri] = None): PredicateMap = StdPredicateMap(identifier, + functionMap, constant, reference, template, diff --git a/src/main/scala/io/rml/framework/core/model/PredicateObjectMap.scala b/src/main/scala/io/rml/framework/core/model/PredicateObjectMap.scala index 3ff332a4..6c1e3109 100644 --- a/src/main/scala/io/rml/framework/core/model/PredicateObjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/PredicateObjectMap.scala @@ -43,7 +43,7 @@ import io.rml.framework.core.model.std.StdPredicateObjectMap trait PredicateObjectMap extends Node { def objectMaps: List[ObjectMap] - def functionMaps: List[FunctionMap] + //def functionMaps: List[FunctionMap] def predicateMaps: List[PredicateMap] @@ -51,7 +51,7 @@ trait PredicateObjectMap extends Node { } object PredicateObjectMap { - def apply(identifier: String, objectMaps: List[ObjectMap], functionMaps: List[FunctionMap], predicateMaps: List[PredicateMap], graphMap: Option[GraphMap]): PredicateObjectMap = { - StdPredicateObjectMap(identifier, objectMaps, functionMaps, predicateMaps, graphMap) + def apply(identifier: String, objectMaps: List[ObjectMap], predicateMaps: List[PredicateMap], graphMap: Option[GraphMap]): PredicateObjectMap = { + StdPredicateObjectMap(identifier, objectMaps, predicateMaps, graphMap) } } diff --git a/src/main/scala/io/rml/framework/core/model/SubjectMap.scala b/src/main/scala/io/rml/framework/core/model/SubjectMap.scala index 9cbc4342..14e66360 100644 --- a/src/main/scala/io/rml/framework/core/model/SubjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/SubjectMap.scala @@ -59,13 +59,14 @@ object SubjectMap { */ def apply(identifier: String, `class`: List[Uri], + functionMap: List[FunctionMap], constant: Option[Entity], reference: Option[Literal], template: Option[Literal], termType: Option[Uri], graphMap: Option[GraphMap]): SubjectMap = { - StdSubjectMap(identifier, `class`, constant, reference, template, termType, graphMap) + StdSubjectMap(identifier, `class`, functionMap, constant, reference, template, termType, graphMap) } } diff --git a/src/main/scala/io/rml/framework/core/model/rdf/RDFResource.scala b/src/main/scala/io/rml/framework/core/model/rdf/RDFResource.scala index d9784ce9..efcff62e 100644 --- a/src/main/scala/io/rml/framework/core/model/rdf/RDFResource.scala +++ b/src/main/scala/io/rml/framework/core/model/rdf/RDFResource.scala @@ -26,12 +26,13 @@ package io.rml.framework.core.model.rdf import io.rml.framework.core.model.Uri +import io.rml.framework.core.internal.Logging /** * This trait represents a resource that is able to query an underlying RDF model. * Different third-party libraries can be used by implementing implicits. */ -trait RDFResource extends RDFNode { +trait RDFResource extends RDFNode with Logging { def uri: Uri diff --git a/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala b/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala index de57a63b..1a47ecd8 100644 --- a/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala +++ b/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala @@ -27,7 +27,7 @@ package io.rml.framework.core.model.rdf.jena import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.{RDFLiteral, RDFNode, RDFResource} -import io.rml.framework.core.vocabulary.RDFVoc +import io.rml.framework.core.vocabulary.{RDFVoc, RMLVoc} import org.apache.commons.lang3.builder.HashCodeBuilder import org.apache.jena.rdf.model.{RDFList, Resource} @@ -117,14 +117,31 @@ class JenaResource(val resource: Resource) extends RDFResource { override def getType: Option[Uri] = { val types: Seq[RDFNode] = listProperties(RDFVoc.Property.TYPE) - // check if there are type statements, or else return None - if (types.size != 1) return None - // if there is a type statement, make sure this is a Resource and that there is only one in total - require(types.head.isInstanceOf[RDFResource], "Type must be a resource.") - - // TODO: what if there are multiple types? - - Some(types.head.asInstanceOf[RDFResource].uri) + types.size match { + case 0 => { + // no type defined + this.logWarning("No rdf:type defined for resource.") + None + } + case 1 => { + require(types.head.isInstanceOf[RDFResource], "Type must be a resource.") + Some(types.head.asInstanceOf[RDFResource].uri) + } + case _ => { + // multiple types defined... + // TODO: what if there are multiple types? + this.logWarning("Multiple rdf:types defined for resource.") + None + } + } +// // check if there are type statements, or else return None +// if (types.size != 1) return None +// // if there is a type statement, make sure this is a Resource and that there is only one in total +// require(types.head.isInstanceOf[RDFResource], "Type must be a resource.") +// +// // TODO: what if there are multiple types? +// +// Some(types.head.asInstanceOf[RDFResource].uri) } override def getList: List[RDFNode] = { diff --git a/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala b/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala index 01c35f4f..f58979e8 100644 --- a/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala @@ -27,6 +27,7 @@ package io.rml.framework.core.model.std import io.rml.framework.core.model._ case class StdObjectMap(identifier: String, + functionMap: List[FunctionMap], constant: Option[Entity], reference: Option[Literal], template: Option[Literal], diff --git a/src/main/scala/io/rml/framework/core/model/std/StdPredicateMap.scala b/src/main/scala/io/rml/framework/core/model/std/StdPredicateMap.scala index 35b7742a..ee987950 100644 --- a/src/main/scala/io/rml/framework/core/model/std/StdPredicateMap.scala +++ b/src/main/scala/io/rml/framework/core/model/std/StdPredicateMap.scala @@ -28,6 +28,7 @@ package io.rml.framework.core.model.std import io.rml.framework.core.model._ case class StdPredicateMap(identifier: String, + functionMap: List[FunctionMap], constant: Option[Entity], reference: Option[Literal], template: Option[Literal], diff --git a/src/main/scala/io/rml/framework/core/model/std/StdPredicateObjectMap.scala b/src/main/scala/io/rml/framework/core/model/std/StdPredicateObjectMap.scala index 56529ae7..7352e23c 100644 --- a/src/main/scala/io/rml/framework/core/model/std/StdPredicateObjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/std/StdPredicateObjectMap.scala @@ -29,7 +29,6 @@ import io.rml.framework.core.model._ case class StdPredicateObjectMap(identifier: String, objectMaps: List[ObjectMap], - functionMaps: List[FunctionMap], predicateMaps: List[PredicateMap], graphMap: Option[GraphMap]) diff --git a/src/main/scala/io/rml/framework/core/model/std/StdSubjectMap.scala b/src/main/scala/io/rml/framework/core/model/std/StdSubjectMap.scala index d00c5a86..63498a01 100644 --- a/src/main/scala/io/rml/framework/core/model/std/StdSubjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/std/StdSubjectMap.scala @@ -29,6 +29,7 @@ import io.rml.framework.core.model._ case class StdSubjectMap(identifier: String, `class`: List[Uri], + functionMap:List[FunctionMap], constant: Option[Entity], reference: Option[Literal], template: Option[Literal], diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index d4fb282c..501780d7 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -29,6 +29,7 @@ import io.rml.framework.core.model._ import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item import io.rml.framework.flink.sink.FlinkRDFQuad +import io.rml.framework.flink.source.EmptyItem case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { @@ -36,27 +37,87 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { require(termMap.isInstanceOf[FunctionMap], "Wrong TermMap instance.") val functionMap = termMap.asInstanceOf[FunctionMap] - val functionEngine = StatementEngine.fromTriplesMaps(List(functionMap.functionValue)) + val pomAssembler = PredicateObjectGeneratorAssembler() + + val assembledPom = functionMap.functionValue + .flatMap(pomAssembler.assemble) + .map { + case (predicateGen, objGen, _) => (predicateGen, objGen) + } + + val function = parseFunction(assembledPom) + + createAssemblerFunction(function, assembledPom) + } + + private def parseFunction(assembledPom: + List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): + FunctionMap = { + + val placeHolder: List[FlinkRDFQuad] = generateFunctionTriples(new EmptyItem(), assembledPom) + val functionName = Uri(placeHolder + .filter( quad => quad.predicate.value == Uri(RMLVoc.Property.EXECUTES)) + .head + .`object` + .value + .toString) + + throw new NotImplementedError() +// val transformationMapping = TransformationMapping +// .getOpt +// .getOrElse( throw new IllegalStateException("Transformation mapping hasn't been read/init yet")) +// +// transformationMapping +// .transformationLoader +// .loadTransformation(functionName) +// .getOrElse(throw new IllegalStateException(s"Function $functionName doesn't exist")) + } + + /** + * Generates an assembler function which takes in [[Item]] and generate + * entities using the function specified by the function map + * + * @param assembledPom List of predicate object generator functions + * @return anon function taking in [[Item]] and returns entities using the function + */ + private def createAssemblerFunction(function: FunctionMap, assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Item => Option[Iterable[Entity]] = { (item: Item) => { - val triples: List[FlinkRDFQuad] = functionEngine.process(item) - val parameters: Map[Uri, String] = triples.filter(triple => triple.predicate.uri != Uri(RMLVoc.Property.EXECUTES)) + val triples: List[FlinkRDFQuad] = generateFunctionTriples(item, assembledPom) + val args: Map[Uri, String] = triples.filter(triple => triple.predicate.uri != Uri(RMLVoc.Property.EXECUTES)) .map(triple => { val parameterName = triple.predicate.uri val parameterValue = triple.`object`.value.toString parameterName -> parameterValue }) .toMap + throw new NotImplementedError() +// function.initialize() +// function.execute(args) + } + } - val name: Uri = Uri(triples.filter(triple => triple.predicate.uri == Uri(RMLVoc.Property.EXECUTES)) - .head.`object`.value - .toString) + /** + * Generate triples from which the the function can be derived from + * and applied to the the item + * + * @param item + * @return + */ + private def generateFunctionTriples(item: Item, assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): List[FlinkRDFQuad] = { - require(RMLEnvironment.hasTransformationRegistered(name), "Transformation " + name + " is not registered.") - RMLEnvironment.getTransformation(name).get.execute(Parameters(parameters)) + val result = for{ + (predicateGen, objGen) <- assembledPom + predicateIter <- predicateGen(item) + objIter <- objGen(item) + } yield for { + predicate <- predicateIter + obj <- objIter + quad <- Statement.generateQuad(Blank(), predicate, obj) + } yield quad + + + result.flatten - //TODO: PLACEHOLDER REMOVE THIS WHEN FUNCTION MAP IS IMPLEMENTED !!!!! - None // <---- REMOVE THIS!!!!!!!!!!!! - } } } diff --git a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala index 0f3b1ab3..91cc9c01 100644 --- a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala @@ -32,23 +32,21 @@ class PredicateObjectGeneratorAssembler(predicateGeneratorAssembler: PredicateGe objectGeneratorAssembler: ObjectGeneratorAssembler, functionMapGeneratorAssembler: FunctionMapGeneratorAssembler, graphGeneratorAssembler: GraphGeneratorAssembler) { - def assemble(predicateObjectMap: PredicateObjectMap) + : List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]], Item => Option[Iterable[Uri]])] = { + val graphStatement = graphGeneratorAssembler.assemble(predicateObjectMap.graphMap) predicateObjectMap.predicateMaps.flatMap(predicateMap => { predicateObjectMap.objectMaps.map(objectMap => { (predicateGeneratorAssembler.assemble(predicateMap), objectGeneratorAssembler.assemble(objectMap), - graphGeneratorAssembler.assemble(predicateObjectMap.graphMap)) - }) ++ - predicateObjectMap.functionMaps.map(fnMap => { - (predicateGeneratorAssembler.assemble(predicateMap), - functionMapGeneratorAssembler.assemble(fnMap), - graphGeneratorAssembler.assemble(predicateObjectMap.graphMap)) - }) + graphStatement) + }) + }) + } } diff --git a/src/main/scala/io/rml/framework/engine/statement/StatementEngine.scala b/src/main/scala/io/rml/framework/engine/statement/StatementEngine.scala index ab089c1f..f18ff881 100644 --- a/src/main/scala/io/rml/framework/engine/statement/StatementEngine.scala +++ b/src/main/scala/io/rml/framework/engine/statement/StatementEngine.scala @@ -76,7 +76,7 @@ object StatementEngine extends Logging { */ def fromTriplesMaps(triplesMaps: List[TriplesMap]): StatementEngine[Item] = { // assemble the statements - + this.logInfo("fromTriplesMaps(triplesMaps) - creating statement engine") //Group the triple maps with their iterator as the key val iteratorGroup = triplesMaps.groupBy(tm => { // here we require the triples map to have only one iterator diff --git a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala index 287eb92c..d829d572 100644 --- a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala @@ -28,13 +28,14 @@ package io.rml.framework.engine.statement import io.rml.framework.core.model._ import io.rml.framework.core.vocabulary.RDFVoc import io.rml.framework.flink.item.{Item, JoinedItem} - +import io.rml.framework.core.internal.Logging /** * Creates statements from triple maps. */ class StatementsAssembler(subjectAssembler: SubjectGeneratorAssembler = SubjectGeneratorAssembler(), predicateObjectAssembler: PredicateObjectGeneratorAssembler = PredicateObjectGeneratorAssembler(), - graphAssembler: GraphGeneratorAssembler = GraphGeneratorAssembler()) { + graphAssembler: GraphGeneratorAssembler = GraphGeneratorAssembler()) +extends Logging{ /** * Creates statements from a triple map. @@ -43,6 +44,7 @@ class StatementsAssembler(subjectAssembler: SubjectGeneratorAssembler = SubjectG * @return */ def assembleStatements(triplesMap: TriplesMap): List[(Item => Option[Iterable[TermNode]], Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]], Item => Option[Iterable[Uri]])] = { + this.logInfo("%s assembleStatements(triplesmaps)".format(this.getClass.getName)) val subjectGraphGenerator = graphAssembler.assemble(triplesMap.subjectMap.graphMap) diff --git a/src/test/resources/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl new file mode 100644 index 00000000..0c188516 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl @@ -0,0 +1,36 @@ +# Function on object, 0 parameters + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:random ] ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0000-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0000-CSV/output.ttl new file mode 100644 index 00000000..f8633b11 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0000-CSV/output.ttl @@ -0,0 +1 @@ + "random" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl new file mode 100644 index 00000000..e7a1c7bf --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl new file mode 100644 index 00000000..b0369690 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl @@ -0,0 +1 @@ + "VENUS" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl new file mode 100644 index 00000000..e2bd587c --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object, 1 constant parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:constant "name" ] ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl new file mode 100644 index 00000000..fb8edf94 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl @@ -0,0 +1 @@ + "NAME" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl new file mode 100644 index 00000000..06823449 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl @@ -0,0 +1,42 @@ +# Function on object, 2 parameters + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:escape ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Comment" ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:modeParameter ; + rr:objectMap [ rr:constant "html" ] ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl new file mode 100644 index 00000000..af03220c --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl @@ -0,0 +1 @@ + "A&B" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl new file mode 100644 index 00000000..fe1c29b7 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl @@ -0,0 +1,40 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicateMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ]; + rr:objectMap [ rr:constant foaf:name ; rr:termType rr:IRI ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl new file mode 100644 index 00000000..4aa4759e --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl @@ -0,0 +1 @@ + . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl new file mode 100644 index 00000000..e5714b73 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl @@ -0,0 +1,38 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/RMLFNOTC0005-CSV/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "url" ] ] + ] ; + rr:termType rr:IRI + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl new file mode 100644 index 00000000..80493637 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv new file mode 100644 index 00000000..c33048c8 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv @@ -0,0 +1,2 @@ +Id,Name,url +1,Venus,www.example.com diff --git a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl new file mode 100644 index 00000000..ba6f2fe3 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl @@ -0,0 +1,41 @@ +# Function on graph, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] ; + rr:graphMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq new file mode 100644 index 00000000..2258872a --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl new file mode 100644 index 00000000..2019aab7 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object, 1 false reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "WrongReference" ] ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl new file mode 100644 index 00000000..4dff2794 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object, 1 template parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:template "Name: {Name}" ] ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl new file mode 100644 index 00000000..9020be0f --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl @@ -0,0 +1 @@ + "NAME: VENUS" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl new file mode 100644 index 00000000..68ac38aa --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl @@ -0,0 +1,40 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:datatype xsd:positiveInteger + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl new file mode 100644 index 00000000..03a48120 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl @@ -0,0 +1,36 @@ +# Function on object returns null + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:generateNull ] ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0012-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0012-CSV/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl new file mode 100644 index 00000000..e0d25a62 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object returns empty string + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:constant "" ] ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl new file mode 100644 index 00000000..6629e021 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl @@ -0,0 +1 @@ + "" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl new file mode 100644 index 00000000..8e805fa2 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl @@ -0,0 +1,38 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0014-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0014-CSV/output.ttl new file mode 100644 index 00000000..037f691d --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0014-CSV/output.ttl @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl new file mode 100644 index 00000000..0c9872aa --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl @@ -0,0 +1,40 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicateMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ]; + rr:objectMap [ rr:constant foaf:name ; rr:termType rr:IRI ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0015-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0015-CSV/output.ttl new file mode 100644 index 00000000..4aa4759e --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0015-CSV/output.ttl @@ -0,0 +1 @@ + . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl new file mode 100644 index 00000000..142874f1 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl @@ -0,0 +1,41 @@ +# Function on graph, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] ; + rr:graphMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0016-CSV/output.nq b/src/test/resources/fno-testcases/RMLFNOTC0016-CSV/output.nq new file mode 100644 index 00000000..2258872a --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0016-CSV/output.nq @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/data.csv b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/data.csv new file mode 100644 index 00000000..12614593 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/data.csv @@ -0,0 +1,2 @@ +id,name +0,ben & pieter \ No newline at end of file diff --git a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl new file mode 100644 index 00000000..b1360640 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl @@ -0,0 +1,52 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/RMLFNOTC0018-CSV/data.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{id}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:escape ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "name" ] ] + ] + ] ; + ]; + rr:predicateObjectMap [ + rr:predicate grel:modeParameter ; + rr:objectMap [ rr:constant "html" ] ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl new file mode 100644 index 00000000..2296c1ec --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl @@ -0,0 +1 @@ + "BEN & PIETER" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/books.json b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/books.json new file mode 100644 index 00000000..9856321f --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/books.json @@ -0,0 +1,8 @@ +{ + "books": [ + {"title": "The adventure of young turtle", "authors": ["John"]}, + {"title": "The big rabbit's trip", "authors": ["Edward", "Steve"]}, + {"title": "A new horizon at the end of the night", "authors": []}, + {"title": "The past comes back in the future"} + ] +} diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl new file mode 100644 index 00000000..79dc1b02 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl @@ -0,0 +1,33 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/RMLFNOTC0021-JSON/books.json"; + rml:referenceFormulation ql:JSONPath; + rml:iterator "$.books[*]" + ]; + + rr:subjectMap [ + rr:template "http://example.com/book/{title}"; + rr:class ex:Book + ]; + + rr:predicateObjectMap [ + rr:predicate ex:writtenBy; + rr:objectMap [ + rml:reference "authors[*]" + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl new file mode 100644 index 00000000..445fac6f --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl @@ -0,0 +1,7 @@ + . + "John" . + . + "Edward" . + "Steve" . + . + . diff --git a/src/test/resources/fno-testcases/student.csv b/src/test/resources/fno-testcases/student.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/fno-testcases/student.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl new file mode 100644 index 00000000..0c188516 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl @@ -0,0 +1,36 @@ +# Function on object, 0 parameters + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:random ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl new file mode 100644 index 00000000..9314fa88 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl @@ -0,0 +1,37 @@ +# Function on object, 0 parameters + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + a fnml:FunctionTermMap ; + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:random ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/output.ttl new file mode 100644 index 00000000..f8633b11 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/output.ttl @@ -0,0 +1 @@ + "random" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl new file mode 100644 index 00000000..e7a1c7bf --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/output.ttl new file mode 100644 index 00000000..b0369690 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/output.ttl @@ -0,0 +1 @@ + "VENUS" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl new file mode 100644 index 00000000..e2bd587c --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object, 1 constant parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:constant "name" ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/output.ttl new file mode 100644 index 00000000..fb8edf94 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/output.ttl @@ -0,0 +1 @@ + "NAME" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl new file mode 100644 index 00000000..06823449 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl @@ -0,0 +1,42 @@ +# Function on object, 2 parameters + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:escape ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Comment" ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:modeParameter ; + rr:objectMap [ rr:constant "html" ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/output.ttl new file mode 100644 index 00000000..af03220c --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/output.ttl @@ -0,0 +1 @@ + "A&B" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl new file mode 100644 index 00000000..fe1c29b7 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl @@ -0,0 +1,40 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicateMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ]; + rr:objectMap [ rr:constant foaf:name ; rr:termType rr:IRI ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/output.ttl new file mode 100644 index 00000000..4aa4759e --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/output.ttl @@ -0,0 +1 @@ + . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl new file mode 100644 index 00000000..e5714b73 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl @@ -0,0 +1,38 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/RMLFNOTC0005-CSV/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "url" ] ] + ] ; + rr:termType rr:IRI + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/output.ttl new file mode 100644 index 00000000..80493637 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/output.ttl @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv new file mode 100644 index 00000000..c33048c8 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv @@ -0,0 +1,2 @@ +Id,Name,url +1,Venus,www.example.com diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl new file mode 100644 index 00000000..ba6f2fe3 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl @@ -0,0 +1,41 @@ +# Function on graph, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] ; + rr:graphMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/output.nq b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/output.nq new file mode 100644 index 00000000..2258872a --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/output.nq @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl new file mode 100644 index 00000000..2019aab7 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object, 1 false reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "WrongReference" ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl new file mode 100644 index 00000000..4dff2794 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object, 1 template parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:template "Name: {Name}" ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/output.ttl new file mode 100644 index 00000000..9020be0f --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/output.ttl @@ -0,0 +1 @@ + "NAME: VENUS" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl new file mode 100644 index 00000000..68ac38aa --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl @@ -0,0 +1,40 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:datatype xsd:positiveInteger + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl new file mode 100644 index 00000000..03a48120 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl @@ -0,0 +1,36 @@ +# Function on object returns null + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:generateNull ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl new file mode 100644 index 00000000..e0d25a62 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl @@ -0,0 +1,39 @@ +# Function on object returns empty string + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:constant "" ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/output.ttl new file mode 100644 index 00000000..6629e021 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/output.ttl @@ -0,0 +1 @@ + "" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl new file mode 100644 index 00000000..8e805fa2 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl @@ -0,0 +1,38 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/output.ttl new file mode 100644 index 00000000..037f691d --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/output.ttl @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl new file mode 100644 index 00000000..0c9872aa --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl @@ -0,0 +1,40 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicateMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ]; + rr:objectMap [ rr:constant foaf:name ; rr:termType rr:IRI ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/output.ttl new file mode 100644 index 00000000..4aa4759e --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/output.ttl @@ -0,0 +1 @@ + . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl new file mode 100644 index 00000000..142874f1 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl @@ -0,0 +1,41 @@ +# Function on graph, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] ; + rr:graphMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/output.nq b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/output.nq new file mode 100644 index 00000000..2258872a --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/output.nq @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/data.csv b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/data.csv new file mode 100644 index 00000000..12614593 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/data.csv @@ -0,0 +1,2 @@ +id,name +0,ben & pieter \ No newline at end of file diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl new file mode 100644 index 00000000..b1360640 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl @@ -0,0 +1,52 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/RMLFNOTC0018-CSV/data.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{id}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:escape ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "name" ] ] + ] + ] ; + ]; + rr:predicateObjectMap [ + rr:predicate grel:modeParameter ; + rr:objectMap [ rr:constant "html" ] ] + ] + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/output.ttl new file mode 100644 index 00000000..2296c1ec --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/output.ttl @@ -0,0 +1 @@ + "BEN & PIETER" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/books.json b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/books.json new file mode 100644 index 00000000..9856321f --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/books.json @@ -0,0 +1,8 @@ +{ + "books": [ + {"title": "The adventure of young turtle", "authors": ["John"]}, + {"title": "The big rabbit's trip", "authors": ["Edward", "Steve"]}, + {"title": "A new horizon at the end of the night", "authors": []}, + {"title": "The past comes back in the future"} + ] +} diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl new file mode 100644 index 00000000..79dc1b02 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl @@ -0,0 +1,33 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/RMLFNOTC0021-JSON/books.json"; + rml:referenceFormulation ql:JSONPath; + rml:iterator "$.books[*]" + ]; + + rr:subjectMap [ + rr:template "http://example.com/book/{title}"; + rr:class ex:Book + ]; + + rr:predicateObjectMap [ + rr:predicate ex:writtenBy; + rr:objectMap [ + rml:reference "authors[*]" + ] + ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/output.ttl new file mode 100644 index 00000000..445fac6f --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/output.ttl @@ -0,0 +1,7 @@ + . + "John" . + . + "Edward" . + "Steve" . + . + . diff --git a/src/test/resources/sandbox/fno-testcases/student.csv b/src/test/resources/sandbox/fno-testcases/student.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/student.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index a4f544e1..eeeff367 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -35,11 +35,22 @@ import scala.util.control.Exception class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { - val failing = Array( "negative_test_cases") - val passing = Array( - ("bugs","noopt"), - ("rml-testcases","noopt")) - val temp = Array(("rml-testcases/temp","noopt") ) + // dev note: + // Explicit type annotation allows to completely comment out the elements of the failing, passing or temp arrays + // without causing compilation failures. + // This is useful, for example, if you only want to check the tests that should pass. + + val failing : Array[String] = Array( +// "negative_test_cases" + ) + val passing : Array[Tuple2[String,String]] =Array( +// ("bugs","noopt"), + //("rml-testcases","noopt"), + ("fno-testcases", "noopt") + ) + val temp : Array[Tuple2[String,String]] = Array( + ("rml-testcases/temp","noopt") + ) "Valid mapping file" should behave like validMappingFile("rml-testcases") @@ -73,6 +84,7 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { val eitherGenerated = catcher.either(TripleGeneratorTestUtil.processFilesInTestFolder(testFolderPath)) + if (eitherGenerated.isRight & testFolderPath.contains("RMLTC")) { val (generatedOutput, format) = eitherGenerated.right.get.head Logger.logInfo(testFolderPath) @@ -90,6 +102,7 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { * @param testFolderPath */ def checkGeneratedOutput(testFolderPath: String)(implicit postProcessor: PostProcessor): Unit = { + Logger.logInfo("checkGeneratedOutput(%s)".format(testFolderPath)) val (expectedOutput, expectedOutputFormat) = ExpectedOutputTestUtil.processFilesInTestFolder(testFolderPath).head val tester = TripleGeneratorTestUtil(postProcessor) var (generatedOutput, generatedOutputFormat) = tester.processFilesInTestFolder(testFolderPath).head diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala new file mode 100644 index 00000000..297ddf83 --- /dev/null +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -0,0 +1,88 @@ +/** + * MIT License + * + * Copyright (C) 2017 - 2020 RDF Mapping Language (RML) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **/ +package io.rml.framework + +import java.io.File + +import io.rml.framework.Main +import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.util.Util +import io.rml.framework.engine.NopPostProcessor +import io.rml.framework.util.TestUtil +import io.rml.framework.util.logging.Logger +import org.apache.flink.api.scala.ExecutionEnvironment +import org.apache.flink.streaming.api.scala._ +import org.scalatest.{FunSuite, Matchers} + +class SandboxTests extends FunSuite with Matchers { + + private def executeTest(mappingFile: String): Unit = { + RMLEnvironment.setGeneratorBaseIRI(Some("http://example.org/base/")) + implicit val env = ExecutionEnvironment.getExecutionEnvironment + implicit val senv = StreamExecutionEnvironment.getExecutionEnvironment + implicit val postProcessor = new NopPostProcessor() + + val testDir = Util.getFile(new File(mappingFile).getParent) + val mappingFileAbs = new File(testDir, new File(mappingFile).getName) + + // read the mapping + val formattedMapping = Util.readMappingFile(mappingFileAbs.getAbsolutePath) + + // execute + val result = Main.createDataSetFromFormattedMapping(formattedMapping).collect() + + // get expected output + //val testDir = new File(mappingFile).getParentFile.getAbsoluteFile + val (expectedOutput, expectedOutputFormat) = TestUtil.getExpectedOutputs(testDir) + + val testOutcome = TestUtil.compareResults(s"StatementEngineTest: ${testDir}", result, expectedOutput, postProcessor.outputFormat, expectedOutputFormat) + testOutcome match { + case Left(e) => { + Logger.logError(e) + System.exit(1) + fail(e) + } + case Right(e) => { + Logger.logSuccess(e) + } + } + } + + + // + // sandbox/fno-testcases/RMLFNOTC0000-CSV + // mapping.ttl vs. mapping_explicit.ttl + // + + test("sandbox/fno-testcases/RMLFNOTC0000-CSV") { + executeTest("sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl") + } + + test("sandbox/fno-testcases/RMLFNOTC0000-CSV-explicit") { + executeTest("sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl") + } + + +} From be65708dfd80393654ce1b724247cd1239a79fb8 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 11:30:46 +0200 Subject: [PATCH 004/169] wip: integration function feature changes to - core/model - engine --- .../std/StdPredicateMapExtractor.scala | 2 ++ .../io/rml/framework/core/model/TermMap.scala | 2 ++ .../core/model/std/StdObjectMap.scala | 2 +- .../core/model/std/StdPredicateMap.scala | 2 +- .../core/model/std/StdSubjectMap.scala | 2 +- .../FunctionMapGeneratorAssembler.scala | 1 + .../statement/ObjectGeneratorAssembler.scala | 27 +++++++++++++++++-- .../PredicateObjectGeneratorAssembler.scala | 6 +++-- 8 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala index d1fef25b..cf525a07 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala @@ -31,6 +31,7 @@ import io.rml.framework.core.model.{PredicateMap, Uri} import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.shared.RMLException + class StdPredicateMapExtractor(functionMapExtractor: FunctionMapExtractor) extends PredicateMapExtractor { /** * Extract. @@ -92,6 +93,7 @@ class StdPredicateMapExtractor(functionMapExtractor: FunctionMapExtractor) exten val constant = extractConstant(resource) val reference = extractReference(resource) val functionMap = functionMapExtractor.extract(resource) + PredicateMap(resource.uri.toString, functionMap, constant, reference, template, termType) } diff --git a/src/main/scala/io/rml/framework/core/model/TermMap.scala b/src/main/scala/io/rml/framework/core/model/TermMap.scala index 9d47e11a..1d0f6785 100644 --- a/src/main/scala/io/rml/framework/core/model/TermMap.scala +++ b/src/main/scala/io/rml/framework/core/model/TermMap.scala @@ -44,6 +44,7 @@ package io.rml.framework.core.model */ trait TermMap extends Node { + def functionMap: List[FunctionMap]= List() /** * @@ -87,6 +88,7 @@ trait TermMap extends Node { */ def hasConstant: Boolean = constant.isDefined + def hasFunctionMap:Boolean = functionMap.nonEmpty /** * * @return diff --git a/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala b/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala index f58979e8..ac27b4ca 100644 --- a/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala @@ -27,7 +27,7 @@ package io.rml.framework.core.model.std import io.rml.framework.core.model._ case class StdObjectMap(identifier: String, - functionMap: List[FunctionMap], + override val functionMap: List[FunctionMap], constant: Option[Entity], reference: Option[Literal], template: Option[Literal], diff --git a/src/main/scala/io/rml/framework/core/model/std/StdPredicateMap.scala b/src/main/scala/io/rml/framework/core/model/std/StdPredicateMap.scala index ee987950..7a858b08 100644 --- a/src/main/scala/io/rml/framework/core/model/std/StdPredicateMap.scala +++ b/src/main/scala/io/rml/framework/core/model/std/StdPredicateMap.scala @@ -28,7 +28,7 @@ package io.rml.framework.core.model.std import io.rml.framework.core.model._ case class StdPredicateMap(identifier: String, - functionMap: List[FunctionMap], + override val functionMap: List[FunctionMap], constant: Option[Entity], reference: Option[Literal], template: Option[Literal], diff --git a/src/main/scala/io/rml/framework/core/model/std/StdSubjectMap.scala b/src/main/scala/io/rml/framework/core/model/std/StdSubjectMap.scala index 63498a01..9583aba0 100644 --- a/src/main/scala/io/rml/framework/core/model/std/StdSubjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/std/StdSubjectMap.scala @@ -29,7 +29,7 @@ import io.rml.framework.core.model._ case class StdSubjectMap(identifier: String, `class`: List[Uri], - functionMap:List[FunctionMap], + override val functionMap:List[FunctionMap], constant: Option[Entity], reference: Option[Literal], template: Option[Literal], diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index 501780d7..78bdd9b7 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -33,6 +33,7 @@ import io.rml.framework.flink.source.EmptyItem case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { + override def assemble(termMap: TermMap): (Item) => Option[Iterable[Entity]] = { require(termMap.isInstanceOf[FunctionMap], "Wrong TermMap instance.") diff --git a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala index 8b0c9d78..a3f4d7ee 100644 --- a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala @@ -25,7 +25,8 @@ package io.rml.framework.engine.statement -import io.rml.framework.core.model.{Entity, ObjectMap} +import io.rml.framework.core.model.{Entity, ObjectMap, Uri} +import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item class ObjectGeneratorAssembler extends TermMapGeneratorAssembler { @@ -35,10 +36,32 @@ class ObjectGeneratorAssembler extends TermMapGeneratorAssembler { // check if it has a parent triple map if (objectMap.parentTriplesMap.isDefined) { super.assemble(objectMap.parentTriplesMap.get.subjectMap) - } else super.assemble(objectMap) + } else if (objectMap.hasFunctionMap) { + val assembledFunction = FunctionMapGeneratorAssembler().assemble(objectMap.functionMap.head) + val termTypeString = objectMap.termType.map(_.toString).getOrElse("") + assembledFunction.andThen(item => { + if (item.isDefined) { + termTypeString match { + case RMLVoc.Class.IRI => item.map(iter => iter.map(elem => Uri(elem.toString))) + case _ => item.map(iter => iter.flatMap(elem => { + throw new NotImplementedError() +// val castedResult = TransformationUtils.typeCastDataType(elem, objectMap.datatype) +// castedResult.map(v => Literal(v.toString, objectMap.datatype, objectMap.language)) + })) + } + + } else { + None + } + }) + + } else { + super.assemble(objectMap) + } } + } object ObjectGeneratorAssembler { diff --git a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala index 91cc9c01..fb39a2d9 100644 --- a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala @@ -28,14 +28,16 @@ package io.rml.framework.engine.statement import io.rml.framework.core.model.{Entity, PredicateObjectMap, Uri} import io.rml.framework.flink.item.Item +import io.rml.framework.core.internal.Logging class PredicateObjectGeneratorAssembler(predicateGeneratorAssembler: PredicateGeneratorAssembler, objectGeneratorAssembler: ObjectGeneratorAssembler, functionMapGeneratorAssembler: FunctionMapGeneratorAssembler, - graphGeneratorAssembler: GraphGeneratorAssembler) { - def assemble(predicateObjectMap: PredicateObjectMap) + graphGeneratorAssembler: GraphGeneratorAssembler) extends Logging{ + def assemble(predicateObjectMap: PredicateObjectMap) : List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]], Item => Option[Iterable[Uri]])] = { + this.logInfo("%s assemble (predicateObjectMap)".format(this.getClass.getName)) val graphStatement = graphGeneratorAssembler.assemble(predicateObjectMap.graphMap) predicateObjectMap.predicateMaps.flatMap(predicateMap => { From ef526ee471394d6a84b8b426a488fcf5c58b3788 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 12:29:06 +0200 Subject: [PATCH 005/169] wip: function feature - cherry pick from feature/function_map_gdm cherry picked commit : refactoring + fix: function loader tests are now working (a891275978434a8645a99184b6aca57b50421d7b) Renamed transient transformation to transformation meta data, as its purpose is to only contain meta data of the function (e.g. function name, class name, jar, ..) --- .../core/function/TransformationLoader.scala | 26 +++++---- .../model/DynamicMethodTransformation.scala | 8 ++- .../core/function/model/Transformation.scala | 17 +++--- ...ion.scala => TransformationMetaData.scala} | 16 ++--- .../std/StdTransformationLoader.scala | 11 ++-- .../model/function/FunctionLoaderTest.scala | 58 +++++++++++++++++++ 6 files changed, 98 insertions(+), 38 deletions(-) rename src/main/scala/io/rml/framework/core/function/model/{TransientTransformation.scala => TransformationMetaData.scala} (62%) create mode 100644 src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala diff --git a/src/main/scala/io/rml/framework/core/function/TransformationLoader.scala b/src/main/scala/io/rml/framework/core/function/TransformationLoader.scala index 551e785b..abf66ab8 100644 --- a/src/main/scala/io/rml/framework/core/function/TransformationLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/TransformationLoader.scala @@ -3,7 +3,7 @@ package io.rml.framework.core.function import java.io.File import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.model.{DynamicMethodTransformation, Parameter, Transformation, TransientTransformation} +import io.rml.framework.core.function.model.{DynamicMethodTransformation, Parameter, Transformation, TransformationMetaData} import io.rml.framework.core.function.std.StdTransformationLoader import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.Uri @@ -23,16 +23,13 @@ abstract class TransformationLoader extends Logging { /** * Map names of [[Transformation]] to concrete [[Transformation]] object */ - protected val transformationMap: MutableMap[Uri, Transformation] = MutableMap() + protected val transformationMap: MutableMap[Uri, TransformationMetaData] = MutableMap() - def getClassLibraryMap: ImmutableMap[String, String] = { - classLibraryMap.toMap - } + def getClassLibraryMap: ImmutableMap[String, String] = classLibraryMap.toMap + + def getTransformationMap = transformationMap.toMap - def getTransformationMap: ImmutableMap[Uri, Transformation] = { - transformationMap.toMap - } def parseTransformations(file: File): TransformationLoader = { @@ -53,6 +50,7 @@ abstract class TransformationLoader extends Logging { * @return [[Option]] of dynamically loaded transformation */ def loadTransformation(uri: Uri): Option[Transformation] = { + logInfo(s"loadTransformation: ${uri.uri}") val optTransformation = transformationMap.get(uri) @@ -62,10 +60,14 @@ abstract class TransformationLoader extends Logging { logInfo(s"Dynamically loading transformation: $uri, ${trans.toString}" ) trans match { - case transient: TransientTransformation => - val loadedTrans = transient.initialize() - transformationMap.put(uri, loadedTrans) - Some(loadedTrans) + case transformationMetaData: TransformationMetaData => { + // val loadedTrans = transient.initialize() + // transformationMap.put(uri, loadedTrans) + // Some(loadedTrans) + + Some(Transformation(transformationMetaData.identifier, transformationMetaData)) + } + case loadedTrans: DynamicMethodTransformation => Some(loadedTrans) case _ => None } diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala index 14ad6c44..0783d002 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala @@ -9,12 +9,12 @@ import io.rml.framework.core.model.{Entity, Literal, Uri} /** * A dynamic transformer which will use the functions of a class specified in an external jar - * The information needed to do reflection is contained inside the variable 'transientTransformation' of type [[TransientTransformation]] + * The information needed to do reflection is contained inside the variable 'transientTransformation' of type [[TransformationMetaData]] * * @param identifier [[String]] used to identify this DynamicTransformation * @param metaData contains information required for method reflection */ -case class DynamicMethodTransformation(identifier: String, metaData: TransientTransformation) extends Transformation { +case class DynamicMethodTransformation(identifier: String, metaData: TransformationMetaData) extends Transformation { @transient private var optMethod: Option[Method] = None @@ -25,7 +25,10 @@ case class DynamicMethodTransformation(identifier: String, metaData: TransientTr } override def initialize(): Transformation = { + logInfo("intializing transformation (identifier: %s)".format(this.identifier)) + if(optMethod.isEmpty) { + logInfo("optMethod is empty -> loading method from jar %s".format(metaData.source)) val jarFile = getClass.getClassLoader.getResource(metaData.source.toString).getFile val classOfMethod = TransformationUtils.loadClassFromJar(new File(jarFile), metaData.className) @@ -45,6 +48,7 @@ case class DynamicMethodTransformation(identifier: String, metaData: TransientTr } override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { + logInfo("execute") if (optMethod.isEmpty) { throw new IllegalStateException(s"DynamicTransformation doesn't have the reflected method yet: ${this.identifier}") } diff --git a/src/main/scala/io/rml/framework/core/function/model/Transformation.scala b/src/main/scala/io/rml/framework/core/function/model/Transformation.scala index d4443fbe..aabc3083 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Transformation.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Transformation.scala @@ -3,8 +3,8 @@ package io.rml.framework.core.function.model import java.lang.reflect.Method import io.rml.framework.core.model.{Entity, Node, Uri} - -trait Transformation extends Node { +import io.rml.framework.core.internal.Logging +trait Transformation extends Node with Logging{ def name: Uri = Uri(identifier) @@ -15,14 +15,17 @@ trait Transformation extends Node { // it currently only support string representable outputs! def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] - def initialize(): Transformation = this + def initialize(): Transformation = { + logInfo("initializing transformation") + this + } } -object Transformation{ - - def apply(identifier:String, transientTransformation: TransientTransformation): Transformation={ - DynamicMethodTransformation(identifier, transientTransformation) +object Transformation extends Logging{ + def apply(identifier:String, transformationMetaData: TransformationMetaData): Transformation={ + logInfo("Companion: Transformation - apply(identifier, transformationMetaData)") + DynamicMethodTransformation(identifier, transformationMetaData) } } diff --git a/src/main/scala/io/rml/framework/core/function/model/TransientTransformation.scala b/src/main/scala/io/rml/framework/core/function/model/TransformationMetaData.scala similarity index 62% rename from src/main/scala/io/rml/framework/core/function/model/TransientTransformation.scala rename to src/main/scala/io/rml/framework/core/function/model/TransformationMetaData.scala index a84ecba1..fa906305 100644 --- a/src/main/scala/io/rml/framework/core/function/model/TransientTransformation.scala +++ b/src/main/scala/io/rml/framework/core/function/model/TransformationMetaData.scala @@ -7,30 +7,22 @@ import io.rml.framework.core.model.{Entity, Uri} /** * A case class which is made to hold the string values of class and method names * of a [[Transformation]] so that it can be initialized lazily later when needed in the rml mapping file - * + * [Dev note ~ SMO] Only contains string data like, function name, class name, source jar file name * @param source string path of the source * @param className class name containing the [[Transformation]] * @param methodName method name of the [[Transformation]] * @param inputParam [[List]] of input parameters for the [[Transformation]] * @param outputParam [[List]] of expected output parameters from the [[Transformation]] */ -case class TransientTransformation(source: String, className: String, methodName: String, inputParam: List[Parameter], outputParam: List[Parameter]) extends - Transformation { - - override def initialize(): Transformation = { - Transformation(identifier, this) - } - - override def getMethod: Option[Method] = None - - override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = None +case class TransformationMetaData(source: String, className: String, methodName: String, inputParam: List[Parameter], outputParam: List[Parameter]) extends { /** * Used as an id for each inheriting objects for debugging ( maybe equivalence checking? e.g. in TermMap and TripleMap). * * @return */ - override def identifier: String = s"($source, $className, $methodName, $inputParam, $outputParam)" + //override def identifier: String = s"($source, $className, $methodName, $inputParam, $outputParam)" + def identifier: String = s"($source, $className, $methodName, $inputParam, $outputParam)" } diff --git a/src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala b/src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala index 5cd32ff2..6956a3c1 100644 --- a/src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala @@ -1,6 +1,6 @@ package io.rml.framework.core.function.std -import io.rml.framework.core.function.model.{Parameter, TransientTransformation} +import io.rml.framework.core.function.model.{Parameter, TransformationMetaData} import io.rml.framework.core.function.{TransformationLoader, TransformationUtils} import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.jena.JenaResource @@ -13,7 +13,7 @@ case class StdTransformationLoader() extends TransformationLoader { override def parseTransformations(graph: RDFGraph): TransformationLoader = { val transformationMaps = graph.filterProperties(Uri(RMLVoc.Property.LIB_PROVIDED_BY)) - + logInfo("found %d transformation maps".format( transformationMaps.length)) for (map <- transformationMaps) { @@ -23,25 +23,26 @@ case class StdTransformationLoader() extends TransformationLoader { val classNames = providedByTermMap.listProperties(RMLVoc.Property.LIB_CLASS).flatMap(Util.getLiteral) val methodNames = providedByTermMap.listProperties(RMLVoc.Property.LIB_METHOD).flatMap(Util.getLiteral) + logInfo("\t" + "lib path: %s".format(libPath)) if (libPath.nonEmpty && classNames.nonEmpty && methodNames.nonEmpty) { val classNameLit = classNames.head val methodNameLit = methodNames.head classLibraryMap.put(classNameLit.toString.trim, libPath.get.toString.trim) - + logInfo("\t\t" + "class: %s - method: %s".format(classNameLit, methodNameLit)) val inputParams = parseParameterList(map, RMLVoc.Property.FNO_EXPECTS).sorted val outputParams = parseParameterList(map, RMLVoc.Property.FNO_RETURNS).sorted - val transformation = TransientTransformation(libPath.get.toString.trim, classNameLit.toString.trim, + val transformationMetaData = TransformationMetaData(libPath.get.toString.trim, classNameLit.toString.trim, methodNameLit.toString.trim, inputParams, outputParams ) - transformationMap.put(map.uri, transformation) + transformationMap.put(map.uri, transformationMetaData) } } diff --git a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala new file mode 100644 index 00000000..9949f8e6 --- /dev/null +++ b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala @@ -0,0 +1,58 @@ +package io.rml.framework.model.function + +import java.io.File + +import io.rml.framework.StaticTestSpec +import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.function.model.{DynamicMethodTransformation, Transformation} +import io.rml.framework.core.function.{TransformationLoader, TransformationUtils} +import io.rml.framework.core.model.Uri +import io.rml.framework.core.vocabulary.{Namespaces, RMLVoc} + +class FunctionLoaderTest extends StaticTestSpec { + val functionFile = new File(getClass.getClassLoader.getResource("functions.ttl").getFile) + + "Loading default grel functions classes" should "succeed without error" in { + + val filePath = RMLEnvironment.getClass.getClassLoader.getResource("GrelFunctions.jar").getFile + val cls = TransformationUtils.loadClassFromJar(new File(filePath), "GrelFunctions") + println(cls) + assert(cls.getDeclaredMethods.length > 0, "Declared methods must be more than 0 for now") + } + + "FunctionLoader" should "initialize the transformation lazily and correctly" in { + val loader = TransformationLoader().parseTransformations(functionFile) + val test = Uri("http://users.ugent.be/~bjdmeest/function/grel.ttl#toUpperCase") + val transformation = loader.loadTransformation(test) + + assume(transformation.isInstanceOf[Option[DynamicMethodTransformation]]) + } + + + "Dynamic Function" should "be loaded and executable" in { + val loader = TransformationLoader().parseTransformations(functionFile) + + val testValue = "qmlsdkfje sdfesdfFJ" + val functionUri = Uri(Namespaces("grel", "toUpperCase")) + + // map: uri -> trans. metadata + val transformationMap = loader.getTransformationMap + + // transformation meta data for given function uri + val transformationMetaData = transformationMap.getOrElse( + functionUri, + throw new Exception("Unable to find transformation meta data in transformation map")) + + + val transformation = Transformation(functionUri.identifier,transformationMetaData) + // initializedTransformation is a DynamicMethodTransformation + val initializedTransformation: Transformation = transformation.initialize() + + // bind value parameter to its actual value + val paramMap = Map(Uri(Namespaces("grel", "valueParameter")) -> testValue) + // execute transformation and obtain its results + val result = initializedTransformation.execute(paramMap).get.head + + assume(result.toString == testValue.toUpperCase()) + } +} From c5249c1d74e53dcba4bb50e67a84d6ff0b1c1944 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 12:34:31 +0200 Subject: [PATCH 006/169] wip: function feature - added function.ttl + GrelFunctions.jar to rsrcs --- src/main/resources/GrelFunctions.jar | Bin 0 -> 287602 bytes src/main/resources/functions.ttl | 288 +++++++++++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 src/main/resources/GrelFunctions.jar create mode 100644 src/main/resources/functions.ttl diff --git a/src/main/resources/GrelFunctions.jar b/src/main/resources/GrelFunctions.jar new file mode 100644 index 0000000000000000000000000000000000000000..9094cba8d5c1814ba09f143a5542fe5d30b9a497 GIT binary patch literal 287602 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 %UxyrTG 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

HL3n$rs6x%=&$Cwg?;qMEZZtUD+?zS^_NXzQDx( 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

|Kp?c>*zK^u$ zzrb=N0gxjnAcA#d*)n42E!#EZ%N*d@i=RTzu}+dj_QT{dytLaELmQDXZCCBK=<>cI z#<7BV0H~mH@+c=M1sRW32l9ukzdtd%{6Prgn9`DGc)djC>A7bzyAjOyoVjb?w&*Ki zWR9FJsfcr><|*YPt#mi|ZI@cBUJKj`pTUwg;TO@Adr*(`$$O#hp=frJXKz^np*-y_ zS)dFRhkQ9*Jcs@7>kwS*7PIy3)2AVxPoF6M2SNKk;be3=ypP(z{BQI9u~A<5&k(7f z3^h%iF|mL9R%u)7SXVVI|Hri4 zK3Apoi~C^0w+)aIyTN!r@i^&bHj&PKpr`+Gw>1=uvU9__WEHfWVoXS>a)jZPl~IT= zf0wr$Pg+0c1}NPF&CcV_9go?Si)V|)HXJ#At#dwd)K|JC=T%w@KDJZ6&uhn?C!Bc`P`xko`ZOO1x+_=? zwGu23RpgI4Mpcb1@Isp30p$qYl9iV#@<$)zs!kR>!IvK>^2Z)Ss|t$U0?Kpqz2N63 zm0ls{8I`)Cjx|8~!nf9{H3d&!%Ks?7V$Gj`euN%>QME64;x8A>^Fo{_QtFC6RsgLF z-VqKmx+I)a8?kulVx^pl+dC z^70x*-{@mO&|Bm&zUoH7(^p|)NvPmYaCjs?ZT9zke9%0VnaPC*Dk(m^yIYL<9G@Nnp;6eP0ZX#q@_TU0^XL6&f{ zsAj}tz_efowqBbco*-kCec~~(v`{9Zd_u#|y&^$ka9`jeQB#QN#56-{zvZKDX$E1! z4Utp=HG^yM48MrL<-?OiO+}#yTL@c-S%`)KD#bKIQAEQ?$xssD&frc^mEkOdz6Qw$ zeSyPAxGA-1Y`x(VjAN24#SlaXGPQ!7{c~i!j+O{`8!bbYQdS4W(7Jh z^m@V_km~+)An6r@!zR@YaG>rrg-a#X^{++Wk`AgssTOaA+0qU=L8+E#{cMQc8x6-v zvKr-p*lQQ0gK8(*O0e}ch!^!-q!oXQFvuJAj(9cHL9iDR4jFJNwisGVv_%pWib^Q# zfw9FLG=!QX(&>Lm(R+dV_VW^}mk4!T`~kg}7tT-o0kPKrb^XK5pw}DD zPr`#}iwKU0*eC1~wO0`JE%=hTml7@);1hCbA2f;DE%bo4MH^Iu`WAR;5M+vMD+tq!JU-2H89omk4ybdCm^Hn_f=qqd|I(`Eo zDk2Nw%v+8*%0dC?+cHo~;ky45+gxd(0OajQp`M5@$FZ|wZsZf+ z+(BXYr`uov_YmuHVu_n(5+L8T|k#v@GYaRZC-e$ zTJC37tu!u&e6;3TW7C)0CKXIZU^@Q^;RqTW5D8y!{6bJ>QQ%sD!QF&-jNi$@e}Z>h zQ9)~^p6Ws7ez)!EJUZkJpv&ddi0C_@P^sDxIm>s@G12A1jip4lbl1$`$CJwRZvdHV zmC+}~a%S%osa=uq#)2z*kY-!R@gnIX-5STw!-htNylsoPjOOy2aJp0x`1zN<fXE2@metve@fDcV?4VUjP2M43>4Gce?Uyd^kY5?5RVwo0Ny1YX*?Z>!9` zC+ApJcIPwQ8=%1Sz>HDQV+HG(R^s@n$Y8a;y~;W7aVY0+BZ?8xminPF^K_ z=PPfn&VFn;zHjZI+j+5F>Pz4l=dwi_rc|itSxFB#kezF>H9_2&wqV%N^_G=0nDmTb z+N5_*xSiDWg?`*NwYY!)mGo|$&F=Cl+{U+Nu%2jXy!J8E&SlL)VvM&oH=P?xDlK}L z%6Kd=8{Xb=5lya`*J@`lsH?9`5=1(4$&ZQX=W`{f%3I3aM&`KL{940atB3s8@lUWh zxyqGdsNZva;n7mO-0X^oc=2~YeOY0(C%UaU8DVx#6gfJb8}h))3ZTq|YWj4fI=hq- zouI^o9p`nC{Hmib+ zqzbHZu{JA&I}+(2T{U8NQO~ecF}R9;|}Lrek-+V?edhpWAAZMdX1sIa^rCF zWXmS)CdsXD{ligJKWrw*!#Nr#>m;2^>ZX-1hUf2(o}F(YpL%q=G%iNfXy+W2LGgWo zUVha-Bn4%^5a!PmwmmVwdQ@xIjJ@4+r`=lqmMA+ypSu~>eZ{!-89A)Jm{yQszCq!b zP@|ovX{Zfc-}Z!MamKB@ki|5(?(m>(fGmLjlHC@Jfv(2!G4 zJOo%uXMR-_IfIx6mpDWfqp4t;DKG~d;aDiRQDkV*uzp27mn{aHM@c5yHSZy)%qJ~R z0jn+hrCB9;(A;3lSSBZ0dA-=9b8I%oM50j>%J#9)$|WN;!E|Bdh0tUPtG~*V7-Bfi zl}%NDsum@Wn*AU^4)z?RDg4B?g23vn?p?`BV7^vfE}1@Yr;JsummdXPC`62Lei|01 zDu>r!xP@V@DEB-?C>^YsSBMhJ!P$YQmbvclP{ciAUC!VhN@w`-P^OXvT_{PsS5>xr z7(btY5G*sIRe1+guWTQTuo+FjE0k4t@iiwKXI)6^X|U2!$^TMm_2ozd5z|xHFSh{HHW~|;yGCzGisdz`~pHsAmf4bYq z%+>C9)-`VFp~TENS64FE<8~fAR|wbim|ZGYeF>+e^hk5(^rZ9)`T`d|YL#5vhM=Uf z$tW$6kvVVUnIC5J=Itpst}b2K0nGwasL?7O9B7`lzRM=gwsZ*_bVnIMr%grHXoX7O zrOeQ-*T~)Gl$A@FXX}&ZwD>xHO#7r9A{Do^X6kB7XQGdcDSeE`$67sKEf1*3eMQoP zlM;wRJE^5ILQsOUwEGpMcgu}90;@#+1C1eM)sJs%mwhE0E zq-E%5$C4B1<1R(cn71DvLp;-yDcwU#8?OcArcNA-(vlw`V>M1mWRbETb6U+A8J4Myo*q>vR{jP<>T`Dk|W92V$|g#m1mZfAPI(?U(on8B)& zZQc@}*=gmx|MUV3VAs`^C4;}Z(^BWa@OG#JnK75w&I*4b80wT**RQQfN0j;(wIpLG z#;0bi%YFuhh#33~u`v#(TP9o+GL5ikFJm?H(bDMPl+z)@ifnF><&?}@dwGhgl`Lhe z&6C+xv0@R|DDp*211Gx;6*QUKMgd8w2`jRC-HGv#o19LZw39ig-NvfO5Z#MJ#_h;0 zF_8uU^p(G=tMix&jq_C_$Pv8TSxKjvWlYI2wWZc8jhoZ~JI51I zKnbSg_(OH;3CX#d@kEbo`e9Y@S|3e>a}twFE1Dec5{8^kJQ8Yn%d7$~+7Tc5Sj{v_ zB*rfnHUha;G~2XcU%vPW2f%TPrPf)QNdxUPd*=CWcKNn9F`=AGiC#QIfToi%m_`V8 zr3f%S%@k?!9S^jY49=SdMrKcsQ*i%c6Cp=Dk23L0mTfb&!u;AsI#n0!P>KnXVcU`) z<7~JZRxQdhUAB{y&?_F^ljE@{E!brcsy_LuGEf>rP?%94D`etJ$;}u}p0vA6)4r%} z+ZNzn6b`K~zC2%+aZZ$2#NKu`VuNKtUN4@2CXRKao>$u^1u@)tw2)oFZ7Jsr099CX zeTfJrRl56p&sEY6jNq+H(VSVU#~X2MP!?FawbTDG?s0dkDqc{@l(H%!LSEdib>!wO zD@pF`aRd%F&X!ZJ+}^SFnH*`%+qa-PkMPMjvCYs>AJh=FK>O8iw*B}qA5 z!yAdl^A{E*N0Nt8SbbRNCmzICn_4r^`e#UL1kDM{7}6mUhijDSlH;F|dFK>%bzPIn z$JJ&JnPmvFD@rPsFJ5sf?X^dLHGX|Heum9u9U`b7^*7)gBK%;*-7ar_JU$n^hwl%s zIY)7i(llaAB>3-__{Z<&2nIX)dc3w~(Y1TitACFq3Em~YvS)VG{d$L--fm86^T;$p zed7rxkh(bV%2oPkt4P6&B-7^BAsonE?WJ&-pLt~|x4Utn_VRg$Ot?~bo46(2I8B*p z>1z-4yDt1J=gX8~5o1$s?*3*rMyP}||<<;zCeIJ=gd(R_Wgtd~bpAyv&sff)Go z1Tc|?Jd_Fayf3{FdC3{MfN-+>q0n$~^l~m|;5XJ0D&*u!GH*jVjwvnq_gu##H_khl zh0(!ax$`a!ulN|$G9?0z1S;y&d4Xks-JPlg#vauxI^$d1WWMS3qzdT2T|I-Jfq9px zfAQ^d;RL8^t;YyUf)$D2ssu3j=OwzYuIGFR71FMb&paBUN=7=JJvs{lqi*b3XAS^5 zzCEP3t~%bN=`#=wKP<&{Kv+x6e=^k4bBu6g2~}?%7?|^FEflGfGC~>F80+sNvd*N> z-_F+{?>;99eNy_qE=uyd;S1{y6|*KgXn^mccC52+4$T<*!{Jri>>%4-d$zMJ7#WTZ z?6ziN8`$)n-FER`+H2(fpSrv*N3nxIB^V zJ&GGJuA@jR(Xgaq8s%!R_?3qw(|X~&$T*b`5-`rLNmfnT#<08tm3^l>pRlYYP(t8WboH$MtIY8=klyXvEeZZJIEaz2Y=F^QSIKEr&Cj7n-Sz))ni-_~dT-h!hH ztdb-7MP*+^je%)mYSm)BBiiD!ho39Fi9`mMSG~e76)`%3E?y_lp3^tB{IYSS0 zi_Af1ORpA6JR8(p;U3fvWNpT$t{>M{KoefHdhz^FQ7DCjZI1lxP=bTRJNC#e8Wqyu zA-88Xn7^NuK+uG1PP`ID$HUQ(P`6MZ>{ujSdqMkTk=-^P_gec-YUEIORV`5Zw=fo` zp225bfcf-yphMZD`?LA}q5VPLYi&1xCtAF*6ndbONCn1#zCJQ)<7PueQii0-J45fDKLE_Om+ zWQ5_Rz9Y_~eKDafE*N?DM6X_g`O)ZysrnD~b@0hR>Eq|F5*E!YPG-SYjc@wlkDzMo zHnB&o(^~s9OeMtfk%>w5Kk$@-yhQGtyv9^P540FX!r#DlrAph3dg&{zs#ZvIS?c7B&O(57+~{I8VgG8 z7kOyYg#Lvwepzo3tkLiF&~*4yW8mr%zwV1Zx_RHpw#Y;FBD{SB>?Zvc#)}dk;zgK2 zkHNsnWwi(TI<|d}_qOdr#{=t&XeT03MC_*V6|N7UJ48Xw=sJBYWYSdOL7C?=`4rJ$ zRQNKA?_0N_ds}bXlkE-yNiv6{T`8BiYZ~i@9!BJ^GWi`cVI}IfJdQN9h~RC@rs<^m z0k1k4Tb79=Ql5U-eGvn?_VAqnOsfX!y$qGRFB{*q019{e&j6wG-L@iXtyDJhKjdZo z4AkwT-9FA1xy}X4+XKD_QibtHM`H*A6ylsBo6Jg!a9xpjc&-=QFn=4rBl*|CK+)ky zeDD0Mg_VRtWoyy8u{!sbKN6OTUIW(IsR0#5&}@90hqCf=(|5N-}H?%+0E+=K_UW)=y+8t&0$hRU5G*-YLLK8HG7w~GUC4s&TRVTktxI?<;q z6y->|%V42sNfw2YM~1PX99a$<0c65C|Kqaz5=p=AzJnRU~xdGR(&|w3=pbQ9}K<%hUhp!#G{8t z)$Wo3bi%(G4s!q~(Qz$@se$t3PDSJ^;itqbBMGx%S@I^0ciIVx`=BV76lJVpR zDBP)%b>s)A+__*J83tk}lK8q5UEr<}V27?P2wV&t)N#U%9}Q2^bb^l021?VnC4kj{ zBXn&UV0PdLeOn6H6-YzZmIM9*q@iCD+Z6|>rK|#X%>eTsaf=COJf4glxf6aoe9Ef) z?pFXheOn?}4@jZq#2N1$CfmHL5BQksb_D?U=;>C&kU&B*rzCRk@KaJ{>){^&WYl!C z;XWWC3Cmi7L^z+gNeFo?x@Q1bRwjq+8Y5mSg->o57a*Z?O&6bwl5RWf49uZaHXlX= z{*d0qk(H}A6A5%I-cK-m6={=Ld_F;6jyX=5p zbtf5Km4zyO(b;%ka{7?~dmyU0K+oolRkK{PF+;T7N;(4>s~0_Bl4-ZbSU7;F$u z*Rrbz@FV@usqqHB$?s~)tW#bi18C_Ue}Y4SF%7$nc&NKxqb}56P(vgu$c8;vcBD9Yn)-^2=z(AYYlyj%t*BNy9MGV#Y9T zWoAeN9Ooi4tV?JX2{UHICy{j0c&%o}G;WqqElvY2XA_2o^X{MfV8Su4Cy@-&ziGGE z(CiX-X8RAl8KlolqxaAp5_hHxli17OmU6ZH8C$uXJ~jAvU+#m2$6%fzvPeUj@Q)E4 zW4;ZZG8x1>8QL`1nu9%cRr)4HlPRFkd)C zjEUh(Swb-IaM^VnQ-6XeBGq8lIYW$((e0z#MNEjXF~YhFmXhFLjeLM8Ce=x6dJ-un zT}c!3?U{+UPOthKEF&?PHsJetHXhzg$^h(Q!rO4$op%JrXlP`#;i(VQDrI!wae{1! z?w&dV%Z+h72b7YwF!8Qq3lMlhG@$!_o{OhsUO7h0k69f&H8DVO-K8FrzYSKBurqJ& z!4SYH0A?nu|YR;{AiINZ?7>@Yk1QJ|3H?V+vc9z!SA0 z(${c4K9#9s4qKDJ6Sra1H-A1}gK6amu{x$RVM(p~@)%r^uD63&8`GJx2J#IY7yrar+T!)?J$kMW4%*e9iVwXLn zZ!`$6H)j0n`yjR6sxc$$P7%Xaokp6YcIwSy#TZwe_5Gst7*~_dMctotN2k>5Mf@?Y zE*bCB`!TMblgmY&F|L7=o5hteuHluU{`TLmrMc6T}E#4kuBIcc>3t;SPBrc^drROQSS=OEH?V|aZ?Dn5U8JoYG2S~rZ zd(^}JGI_x4Q{j7H?|WzBn-6?9efZLMM);Dl<&Na83F1OjP1v#|++|bz+&9Y)_RK?I z;_C~{f-5KPW90{@=Z%{5!5=edxM{4(>6Vvn3?s%sex57=MX8Ck~`R`LIu#mjp@|Es&(#QwP!gY z>)C$)OG>`^uqvk1-gm-5g~wke5xN}x@i|wS^2)gaukUXGjWVffoo6ijg(HMmif1gR zQ@CephI_haYNmUzr-qfP+P&a>C;6}gg1Lx+#79v=0Dz^?jVJJb_a`9W*%yS47)z#<707LX?C?! zMd(jp00#B1!ik zc@FYZVjXfD#RTvL=4*faiyvHd#j*A^(ns+t{=e4*{jY8EpPfFM-rsf9aNn~ti#X-% z{|qhIEwSo#G|A1T3~_vCDmvl$Go4cBhQIbRzNAI2nXP5in6dO{9z;P{uL%|Cki$@v zx4DTxjYkM~Q%4A>B!r?UgdsLCw11!Nok?!nJ}&4q$$js0;Qi7)^k|nO@ODZ1$x5sW z@wwJuAdseeFCf6aE>_8XKWZp;6R@|Qd?Z8 z0A+U{#>U>bL>A6ItAytj2tBs0Xej%Eu;y28AfTb*!NC_5q(jAI9YVCihE#7T;v7LAi&2`g_FvkL+mdEBu_-lzV-n znbd5L;HHOc^qT7jK0*DRp$oOnbHFmB>>UjL14Zr=)Gz3g9q^mpYedu;71BJ8ri2AD%?S&Gn5-@e3q zxMcoZzzIK`eySD3nl*-aWah`a4%IlB)&z%DTIq^3jzT+~L`%}0$M$PH_rb4S^%TJ3 zA?I{?bqKkM{*7q9yB&9>g}Tn*c;I}tM!!;QZC={&CSgWq1ETRu?Z+ra{*u6^VuSB{ zlXSPW=EI9{LAQ0YNEgJa#z!XsR;!Q|$NB97gKo*@BIrB#+8snNYJGL$k!}}F z7%tF~)O2KGjTJ+>X> z`W8NDOTCWM7NsR4mx1I*DU+UgBulYl!+(|cdoHO8w2nz}y==x$$i@?1L}uDBU?B$; zu&++j*`Q*9*Js$ZLR5_ib)!j_4B`n)8U&k3>rq(zmB2m3@G|GqN~$*&Cbep#9;Ks& zaArvkN9tB;&dILMU$tP~mWc+EjU$Z;XqV_2nO z+tN*Y7xI+VxR;Aqi1heE z&vbUP4zM5PR)sQ{ZgN~eEG@1D=;?DH@_ZS_^q#HoS|5c+>!zm{T3supQ9nOHyTrv& zwEbTkB?U6nuZUyPU!EgI*py4Af=0ZcPzzA<$*PzW8waIl@YIV!5*tI>EFSRAXKUlj zMir!duf?Z=&|BcgCW|ChV<`(zV>i%cZjP03Q3(r2`^Yy)HSl;gHN=`JbOA$2o)o6Q zKKciYz13mmCh>dw-Iauq0&#(f`F^PQ(r}*#cBP*y&=C@_TiZYlY|5=lBu#XWa7hal zk$cY(b|oqb1X=2P#V79m;)JUQ7i1LBk@;K>UFz~ zSeC6J$yvQzt?bNd7?wtO{Fjcad0XPl{Ayz1b}*EaD6G&UX>`E>Zn%#zWalLvX7I@5 z{#5yZ^n3(sqh_l4OKy%GhSQl^6-6`!qGX2KH%+TfEJk?dG>m@2=Fyv~Qe8}EHfD_^ zm1#;GT3|6vX9fsO;J948Be0TB?z4={^4OkC-tjw?z9oP@q{^||PnphoN3*y+1 z9Qd}bpUu(F^Q0$sHb0E>EnF~2jGbF`t|;Ad!M**La$eG(&?VUP8c}iE3L8$*mGM8G zg+EI(Ye&N}$WvB=%~&=zHh`u0}DJ0K3szq^H;+VWSb$o~%Of6bRXRnCqYOPDyu zxXj*1lctAXH4iZrOcreR%!qpn=~qT2<|GI3i<^UF+?vs{l9pBNgSb(sbKrofkDgO= zi_78=%CYG$5wwFxzpq8>+BNCs2n?5tl?p?3^6Rp3+8lbr5G9_F?ibC#tAOT67UBlC zZ^u#em`jXZ$MUzwQi;XlxPj3bg-bioRl9ZrHlIUDII;G{=tcb|TBA=u3RLL;U2!Oe z;k^EKm3rJ+6FFS_SO++z^d-r1y*QGfKiP&zE3|mr*nGxlCUeXBBDuX4`QN`(|3p`* z`>HX6eX91Ut0QBb6)YSwVH`znuy@kq+rkrW&KPkcT z>P0UZF;j$j$zsSTlB5)*-bKm{k^yL-H2~rxN~uF#N!0q(#8*rG#m!bI=x!wLaGqzu zkC0S2X2av%#tRi9C-ePSD-hnd=$h)UC=>*u`i9fQ5i7_>Gx{denQNfp=;2Q0fz>oR zPKpb0$0mE^`ZL5+?|79pWcSf^bY$$Mi{=Lf(>L6YoO#UaltlI~L5~Zx1ha8|-x(K7 zu00AXHctpsh3}`F;Bp=E3{onkO?6+pA=I&E!)P7;Fw67GA*pQ<%4oZT+7(B*Vl@fH zlJD5kS~n>BD3NW!d#@nkI9deSqiJMDS`%e&db`HWw%CB3PyQar`u#FcCo&##F(oPm zY4Q%$KWP{w{4GT5G=s~G*hl&?K^SM3;Z27qCsXv*{V`kf>kTfV56VgUJ9U_f>6_{`F1o>7_zK-jUYUQ}XL zo^|$Ypf`FPBNX8%KA4`ZA)bT7W`F}Bz!#%qi5r z*kUtUHcLx|5ap7(G2e&-f%ef{rLSAIzkfMIaT_WVCY90gD zX&=3X*&gU$w&^P|?2WrTQtS5#p!&U~uwgAa;W=f(Tt+K-A{fvC*nVJ5m~Oc_C?+=~ zLzum%0t)5HwNq~h!woLA%6U$COr13C2yGBbN*rZH`H?#mwu<3qRGwNHotUb-51r*j zc(xj4w$ZZpH+e^hwj!S{K&^<g}bq9nhQd%)91GDi+3vi+2GYXMV>fuwWLY5n;lW7P{5G&*PDI25_3Q|GNWNa z5sdTWi1LKLC^vRF3o`eJkBHOf5-LQcYP#Owkpayj-Gl^@(ZtkEr}m0pLOfWPf^fKs zBWr>qQ+v2d%i)aLp~za;9*THgGyQ8OPZpVOB!UA4?XRMmS)G2zX#3`5bb4*T% z^aS#v<>y5|Slgy(HPDex;9&$2lE03rL2zkIPgg^!j3HBuBWv%|zQ9{)T^1!1>SGx^ z7*5BUj(5}G;l&zx%D5W*)#u9O_6(hx(f3&Tq>eO7OgCtvOEY9?k+4I@R@z1-UL9U2 zDfPX+K7F+TayF?diI0~_X6b9}_4Mw1vMAg}G~@J#{F!4{vtfknCF87Dd)AsLYi!mU zZPhhJ)wQ-d{M*p)daFpxp9iQu$INq=w_=MNp7g)>^!&K_A0T!frO_SFe;@XPwkubG zC>v3Hdstb8s~JHY$i)xkow|~7#W9KR$NBu~1p~?fk-rYD@dB!{cb8!|aZ=1rF_fjX z>+~~sv&G_k2sYwef*0wZN8*1tA#tVwj;cx9x}OT3hah3x(4P@sf7~RbGl$oIu~P7DqY=aZXqx!^(KJE#Kgq8D4-w|% zL>c>8A(Wx_L<+~Vw42XK68Ujh%VfT3sZf9<8AO2cPf^QreDmaX=~J+q*A8z_`0vk- z`=TUf*=mxBAZmdzuff0XXA@EP_qjxZpSe7Ydiq0xVLdEJqU9iUMyP32M)IR@ZxS~POk>muq-S4U2%bbl?`L1zSDSPL&Y z0X14FXB-3NDKAM&>0eSvU-gGP`}Vo+mX(6PH=0!X^mZ7Xsb+->uM6t{l}yPTFhX-S z%9G3zajj@5g;7!{Kt8etE(vH94?(ZP#;WG0+Sq3~HpgA8<|Cwv$={E**CQDWebIFB zfL^PJq0XAwvk@8C13}S|)KjsE!`V!F4AUE>|q_SM*4 zS^BNV_eli>2EXoxpychj{rsPv-Ezmn0jl1M%cuN%$sXfLzx=zeWe_wLwL2krea_tC z4>-N!f}rWHt;)Nte#=a#wk=(|5tT8Dif|}(O3u*+BIypW`v#qSD-3cLb-rUCqN}-M zzDGQAoZEsM`Bosi+Fu1VU_47@uBk$l?l^YU<^_YJ673zq#mjJ467k1DAu`vpuDE~0 z5M>ZPR{}1DqR2t84!W`;;q71A?{VWCX&F8mB6mJKJN};tN8QlI)zsu4Am=|3j+&mc ziWtrhj&XPS431zcXmVTVghsX>KP^Pd$m#Krgl)9x!@Lq~5>*r?hO@Gmbjw)ZJ`wy9 zXG}9}y&6QsA%RZ+Jcw`hf;sUZIOl%4&3z-*JlB`w@odt75CZ%gX~%Lb z6lL(_GaZy8MbzgpM017!F*-2^Ec>vn@lV%=2)vX=8))hzQGcmm97v*Y*0K5qh}Thh zM}?F6y~xAVn1A8__C^w=x3eto9;r$(!=rr^gK>)?$zY96slvM}FK=nPc=~=T{xA_P zi1U(hqo|sLRmvvXpuieMfrx*s#$H$ys#Ly{5bi&k}w zVBkeLB)j5HGn_eB8-cmJh7NteO`QyKlkTuCw)#3H_J#OU*Pdl@#ZIX0g9f;KDPp^+pe|CQmhC2y29# zK9Z2|s&Y@g19mloTC4tKLq@%d%M#JWeC2FPU{z2N$+ShwX^`P^IEw;~t)7Mhd@7`e zK@X-6%I{DFfq?S7D1^T0_c9o0#+}vxngj%{1xOGzNR-s|obNvU?unUF<2ZKMrKe3*G-3WrkGr&Qz+bdLc!{X7fgaiw@Zv4euL_6G1|Js5<(NX{;8?x}WH!g-SNoD~-d z`j)Jc^POW&_=XS$@d!4o%GSuDJaEe+3uYMy^-f?Y#-&zJK-vvfVJ#R?-*Om*&iq>x z>N4z2lxTqOfyBRWs>?St_~pexxaa|9 zN)7u5KE}$0u93$4tH=C9Tr!zrDgO!7&y>=^GZ>+!#NuHtA}T_)z>ANc0eW&yF29Dp zdhYtXch?|VHVRTbR~uH`zi_1!r5yvHA_MK5-UHORm7)7y+_d*8k4b=;%G@W=I)kX{aAKhFue-tGF-fX<~P2i#_p|o61()9WiB)A{&(S zBaMK@?X3YN(Gm=NHdfOn7Lx_~`)yp)=vENtMyT}IwtNc(raSO~@4v>Umyv25yKxCe z!xoy^Xy+%l)0o7dkO^^0hOuOxmzIKlXfJ_p})-?c~0AU8GTv4b%I zmHJCj`^z7x>OA>QqVIM5?Z0&@Yd>==er`_t{pGsDPx?DBT0+hiwT1#J0o# z#gCCZ77su8G3^IG{&!9k|KP{}+$#SYAbWntn8$tZT3Q=3V58pI0wy5vvgE!H1^HgYhSeThMIEyQ^L(Twd;5AS7(6 zvOUXx?dD80O|<#+zUX-|{=Dw~(!Jx`FzM%V3jay1U?$jiv1a>cgoLi*B?ys&Z@(A8 z#k2qcR`13m%RJP>EsZm#wH8X^L9Ydo|4_|wF5H-5caxd&DQ#P)^U;?1iZjpnI}`2=tJTI6J-9AM5c_hc38v zRVsTWf~DU-nKmHv;-NJ_JNBZs{_IJi-*>|I41MvMAhqGJtx-8pll|}|mhoz*<;6o~ z;6fL;GGOw{9CBk@#cy+oNbLg~3wB&`tUGS&VKW$s+HV_Qv|VC%)@;|%yp?QU&&=E zetGPpy|JJ(0Wy^7Q4y!WnJ_W|>RJWS47QLdU4}yc-p>m2SFyhM!f`)klJr7xLFnE1yrkwFd*mJ zF+b$n01K3)w7Tkj%m1S69fL!QwzS>Y*|BZgwr$(CZQHi(>|n>XZQIUHzMRvi`}XNu z)!)5U>(}}$=6v2U-j{a8NYot|l8T&0iow}pLX!ucjIc!~E-QR7_16G9ETfre z{=`1zRVHV)!&-g%c%$s%4?iAjR>CtNQO5=zE~y}IpVU@5>K zH>w0tr8q$mYmNVG0z~GE95_etCYnr2$&}h$n1;s)NFI@9 zaYMS$d@p|8#dm7xv103I4>y-%M|S6}IgF3)8u|qQ4Zf(>`8dKq0P`jI*4x zB%Ia)>Ku1@eZXXTAt8K-2Z89?VvfgC%*?xKB;1oQ!d_k9(Xu!#6_(HhO2)VzS0GrN znZ&dtBRxgcP_>aTg^__OBPJBQUTT1ol#YkxZLEqPiLw=PQnpO;zo@bE4>bnEEt(o= z+5Vx%n*6>FmV`>}(gkM9+{~N)Rul`es^uviemFbH%CIa6B+N3#Q3{!(0eVQk+g0+- z%};fb&8-d=v$DZ#e@5LPYvfLO z1+64s6h^RJvPS|RVX59q)UGk8LeHx#8f1$pA`6dj z_F>e30=;5*4T|J8MdD5 zhcA){xHK4$zVVb)R;Z3RGXz`m>~9cGt}K*B(p8Y9S(5jQPbsU=3PNP_SwbZL24S&^ z7mqS9%C5^np2%d^tjH$muR*-e?`cvhgKfz4O;faTVT1q&f;ZSB3X6;sFwHc{sjWdK zKdLckd}&)STo+F;?e~KGCpE^TB_v|D zt(t`Xp~f-`!^Y?Hp7JXKN2$+per_aoQ_<7HU6~iEzGv}YAyut0uAtLW1D7ys8=UH8 z)&2+(A3_PML!1~H1UXBTyIfOSNt#IQ127Z3ly2?|%$B!Uh*B#4o5|tM=rskbYm1Wh zijfOIM3VvHcf$A`lXgKJ>%*jo@t%{1YRa5~Cn;EwDkFvk&kzf=k(fA}fUq~cqaj6L z+U&Es?O`wc$ID#=I@uwUl?devu8PJzkCj|YRb(=$m?f~S>q^ODV_T7H+`ojb$tEW> zL%$vou$BpSfx7k`JCrOwSx-Hh$W)koJsQTN zDO;tv5sY0l3)}E$3`3`a^4>;}^au8buCa>qz*hasfl${O?W=g(emqIn>*s55``z7!7l<8d zlSJE^cCOf?Esn$#s`bH38%}wp$xxZ@r8*QO@zaje=8CX%RY!}TH8;)sobW(L1c2^v zyJFcOmf3Dgv1Q7H83J~@fGXP&J@zS)BdQo=twkEz!A$lwUk6>x5mt(HHvL=nMV-U5 z65u!LMK%R##;)4MtVetuz&i$WPEomj{QmYi9ME);-40Y7=(Z7G_JAFF$dNk-mGAP) zk>MoF=t3iXp&~$rO2&WT*mF%ux1m9@vC3mp7K?$g&QFT2uhv6mQ9wK^UE21c?d886 zy(XgM)Cf-rC`+F@^24wf)P90s7glBO7ObG$yQm=o$J&RB{UBYD0QYEOJZZ>LL#ZZh zWbuf{Cx0sY5)uY}W>(CtZCz!@&jj?mGbV}-%kuQH@O_KOZ?kxkSSbeFqyT1AM^m8P zdJszD+lkjm68qni5c|VGYqXKY8P;pn1&O+(5_R##Y6&#DQVirfKit^$U)-4b*zZ~X z>jwVYE#lj2@cZw=?M`H!=I2a-g1rRc*9rEJb;5o)%(jB{e_~@1Eo@!!Ml8E)y9_k~b z5Z5KfIVA%rQ;C!-Y^v8r515P#H!H6U?PThD%jXu5>PTAC;kP$>P{`;Tc7>1-h!P-bo$M#>~Sf-0@ z{BruB?gt!G{sSBjjACP=Em1h^)h8<6qCM9SD8Gc^>Si9>GCOSuo$+I)DDf`L#>h?JL}J%*%x2|C&j@?t>5dXhz?$BslvD=@6=;?< z<4ZxpC)S`>fhZJK4{(!2zey64grpMF^^rKM?TB(7-}OLP$dB{V56;S1D6GeFRS$&K zKy#DB@>uNKGWwLuaK&dCDm(@7YA1L3p{Bpgoa#~^YL%PrqG~SkK~$V4z02$i)@=&Y zZ%Wf!3;l6~HYIP{w?1NJrrP*-Ze0BjZk+dxF&8uR^v4m?GH)<3G_v-++kV;U{<)xl z!_NXP_34Kj_oHi5kKC0f9T+ddInDteX6leD;|`)95jf89Myox`-(L1S=`x_+B6DY;o z2cgwP7uw!q#V-}tJK)aycLckezO$jYgK7ulKJFoTH@g%^YA`GKf_=|_a^tIiaO1vz za^uR2pqh-sb+6siw10AA%XS4f`d+Red=Gdyi4O0}RG%Y$zTaV%Q5MJ6XHXr7@3X7c z7XnIjv>d@1sz$Xg)aS6G)JenaI#aO3B`DTHg7q0AFo5`EHNXyiOxT}J=?n2E~+;O1`7FSIm3dZ9+P z-{}QTv98!n-YYcK-{=(*JPW~lTf;TjcF+p$_w^=+jFRC?yzw;9BE=Ko+RaHZ-9!+O zBK|Y}WJh@T;KGCP)W7I8b*FR;Zjqz!Y*OkdIADPr zrNjV#4NfR?L4*aau`jmuPHkSANjZTLd<032h8aQMGdKts+&#vLiH5U*C?JP>J`hz# zNhBYne|FK0LKb{ZyoPi6*p7v3wW_lmTbgGYJoP{$IhYH|mlQF&A6)P9r=TFjy7AY( z?tFrsH_PvFdr~e*>jA;FULvdsbp?a4-N|(zEVc&I15{hATkGlrhBTG~Gy(N@wXcuo zhD&>-O0+DRZ3!TtxAf@S>?TCEbV>!z-*)s-DR`M6oEf z-aWi&k&vCs0Ej5{{Uzn@CI6FZ<#k1y&bZ${w3x!}^7wiw04U8tB+WkMh5ST&Av-P8 zXnFZP{X3+e{e0=4v{-v2274%Jf!xl$j5qQi9nS2UsW;tnUum+$p()!^cLc{~d&yKP zqh|m=8i_X!o>~Tfb4mrv5AffKjZu|tKhKYKv;WUk{QpjD{wFI=QN3_NQbGQ<$#PyW zJ|ikgnFpdcnj^Jgq8u&inxINYZGodkamlhy3NdaY&WgMN-~E7v2*>Bm_dNwq4?wQg z#5OY)<$FUP>7$!wFN*aG_PpLAk;zIv54+@f*>t*o%h}=ZV%_=tdxi$^`8o)R=NYv( zXp7+Ui+fj?z%#=!4jOKs01Y>E68A5mpe!RaSAl+S1Vo{1`Rau8hwz~AU=DfMvH$e4 z0NFFq9)F?@4B7bXMX%~{s-q!9TsZr#FbyusU3&P42sgpL1bD7v;k57rbLR^Nc&>@n zV!+8N4>%4x@qWF3V{xMVk$POBcxA^j&MGzkDuKRgRxJsv29xKZx@1EhEo7dHuI5*k zKVgd1&xB(ZOJynM1&A^W$ji7;BOj?1f?rvJe2chMeuJ2QjSO6pgN6K3a;$Qfo`mz* zUxxYiAkXmrapdgh)Ol0krD6a(c{$33ADN83 zhYs8y;3GalC7K+J39X(H%UnxZmK5>?X0Mu`wp9tSQGgqgTpkv%X=*|-6!QTb#*IxzpeSW+ z)rF{%m{dt02RhyBVc5SlDZ>FqK<5`zTz@+PNfLEWFe5yXm|v%%@Du%;nlTO-vrq&% zwNL=SvPq8fX-j(HC1G1;ChH{G7=rhvLr0V$!f zgAHN3Kd6qv(7+~7wzwR33Nv@6t@}GlTx#SHahE@uNEh**Nf+V13gnN!H>BOJ3?S@x zOBKnF;ErG?;f^IHjGbZ+vqiX_V2@2k3?d*>mou+w%buN9-MKBRmCjh2P7h z!~}8sH%>JjdA_55As&__D~vXi9M>{TnR@a9IRzXXMW&ylS&}`DDA^S6?{ed2n8d13 z4E+Op`aPp&%m`TS1SX5XSLDh`Y}W8*+aKe`P)_ZZP{^$6n76QKE;XqjT1qmmWMD8n zyv{ZI!>qA72~*Z&nWYTi(M)ZWq-@*i+Ib2}r}oS`%{67wQ|N+Axu204<^e0V5s7M) zyUJit=A$AOF%wp&3mVCx1{Wj_YY?PfSyuS=`QQ%s^?vCL;zO(F27g$O`lqe?%xnuz zvksawkFXI1g4i3_Zd-J0&`z^KhVTF=zmqM-T%cpWcvD)SSD zsRqO<0NNT+DxKkC7UX;Y#AU-Am%k#7tqUF7UN}v|@~aoEG5x&P-GPPArB(2t&dhot zLcJ1`L#hc`d3qtx7~)d$(lbTL0}O#~*eL7)p7*u|fb~FS z5R(>AexX7-q6JzI)1HBrM7-w>fLI)#PpiSKzx;T>W$K_CS}?T8B{{HmP`&wTs98E+ z5TQgF@gv(E)4>y@furC6HxTNx>EvgDGzWNZJXWE_ye-6a-*X0BNlO_ftY|HgvxOm{ z`y%BraWRB6ZqUcQ#P(d(iW#yp^aMyGt|>i>9X801qnW_*=0v32fi}FuA3vkvePrj^ zQ~qKmJd>b&Q(gA2U^}HmP$>=2yYAWw>h$u;qQ2WjkYm+MQMY$$iW}K_CB>y?T9sd! z%NlKqf6!w;HnqeR)UI^fBR?HvZ&~hp^6H%!0qUVCZWyoJa9O6_C`90m-is~nf@ypS zx3Z1in^i8*VIR9n_J$}n7X@`uQIxQ(N+4LCUgB>5hHiJplX%iTKa5~8L$qo|L|RRo zmAu5?>aAW6?-5yP$c(H{ABFX#8TN@jCV9*cDv`FOH&Mfkv8|K%Hla4$MzT3O*8VH& z|Bc`4r}+JyV$hMiUOwU}w$A9&81=FJP519VqG^S9liVNafbvH=;QrsF19u}6duIzf zTRI_YJ6jV`0}JaP_3}So{s$w@Nt}?y5`Y)6dt(^{gaHY=g^+Mv6^#}yCWq?73L+tj z0wp!w!fhMInQ|`jAbx}84M9;vee?HLPCjoCfUqWLsHpr?$?2lC<@f#f3%GZvlQD9& z-e4h=2HXzE8Y$Hfg972v1evO+$0ZiRSy0^^1BXnI%m<;kaTH?qYYDXAQN<#K8FDG- z+U-uLJz)0Fh7@7R-yqFAdGm|{V&x9Wi3Mit(Nk?0AXU|l;RBJtl{*hY)Wn2H$h=O{ zdmRUgt^{Wuq|h!O>C_%>kBoYjHWYN44M9*xcW)|O_-y&%hTA64I2eTO%{C9-$Vs_Q zb|=k8Vax|@7fbL0-lI?^gQHvtBDvO-?xlC;IxkmeTsj83fl64bV7Zx2_PvRPpt8ig zc-Y($PKAOltYL6u{hj3c07UF*C-3n+(0lDBp;+i@W{n94+9fQu{EKR{1S1Y5w{!)e zkgAmfT55x}FXUR)+enPm7S5OyuhDh0)4{Yjs^g5!|=Zw_?rCZ7SsLLX8*S%Zpy#%sm-=8 zJs=J61BeGfj3pQ$6T$%p2nnKuNr6cLVZsf>NymDP!OTdlHPtpLTU9&v0-=`GBU3~K z$)PMY?X9Y6bdp=wudJ-Js%&~nb`<}7ci&7+NHHQ@z-@Os?R1~yI$eK%-f+O_eVnw( zA}Da=IVt@*;bfobQ`$7%^Jb&)PRQcc-aQt~Jul_*$aL4v9$xSWh3?MSKcSwZLNprs zMe8uXV2e3|#<5B@EVZRQ+=Qcjy(<-5&LQjB--oilR3e*8wX8?_T;qJpOdA8HWltg z2+qpy_87MCJU}u#=LPS*3a;N!(332abQj&^nDGx7#!L+cwyR&K!fWSwByV~L7;R`*7ZdKb}c2E#jL64$u%O z(ji@f3fqS)mAx86ei>=^2D*0N>(ft{|O9dg)!BzS>HY9jfTQL?gV)$-G16 zSwM-xP>6PMRzH0oZWxJhw^!Wi2+O8d*fMDZ0I+mJ@NQOCT487?#i zmvM;Ia&v(cB`!wUYL>Z2GW+=~*c)6%nBT@Ref72C_FjTJLq$8$_l~tIXu8~yTVf47 z(oPdn!nJ@aHc_Ch){w)Gc@{!9_;g#Jh&>~)-AfFt+uTGPU^9y^p#!F6(SV=(%DfGO zZGGLL8!Zk4H>ou4RuY3PyR0_}37(S;(=?-hAN)>I_;}d zql~4RM(9A|&5QP@q<9yE633ybS5Bd2ocAGondRW;p$c6lA0*)qAy)=G0f)P{!Gqjt z0}_lQ4s2pxMpu3B@w@Gi155*Jg8t)rd(xXsX!C(*gby;rWJ_RNEfNjt%%zP#YnVqn zL%8D?s24j5JLO1;jT|xH+}{mT@eRgPIcsvRlbo3+NO4{8p}aW~>jN@6YVqB5S=@qz z!pktIaOU&b?u)DVWand;%wNPHHh@t`*rCs2UhS3oY^L=EIb(mlpv2p?>s|An?VBlgj_s+KXTX#{13gze zL(Tys>Y5b!jO&%{hW25Yr>j84t><9`e-KeZDW6LFv7Dfue z3JO60P%Pn_1^?x%aFpin=9}@yShtvA|5SvVeAjk}Vpi<2VSMMfE>Kns_kDhQTGpYv z1f_O?yvxX^V0>qfN&I3Eb^lRmben40#gNic7Wd^gN)h0sdc5woin3d@uIdxBr*@w2 z439Dg{NWCZ(l70LIM-;tI{ua?rHAhGy)^u<6O7%LKVW0qU6LO$J*)(u>KoaoQoTCL zrF+}O!^u6epyJ}6p`x%y zK_w|IGUSpDT%CK)WmoOQeMucQ%NULE@)=ImZgmPo4krZ#N*1Nms|=!1wD)yjhp7}M z#YhYtyTkORo=kIfb5dKYga;X{3-Ke{_lVL(wxMNunK@oHWR~K`_u|3^$@T2RtOV;n z{1Ydcff3v4!d2>wLU-rx+>0m(Ru>8@5WTUyzk0`%R@xg&T5N{qtIjPo*DJF!E45mR z>QFZcu^UsN#Dvdqu4CM=P}$m;Szhaysbz&(4nW-b&k|x0^3)X5ZU4Zc!f>Eto?^Uc z0_HhrF}sMa*i%T7At;Vrkg$Ocpl8KQG0l^4QZjkNes#1Sccd)IEYVP9DwaJ}^e~pX zf$zu6smtq<-Wday9Gy_`$wWY5hS+Mq7`iG52}y=F7X~>sgaswgCiKT)=pq(%5HxC@ z#tt(J&ZE2gLLvKP0we9sBV58fh9Zp-<-JwNdIJ8q7LExCyJkwe&20@j!})5M!yZLu zWB9a2qrk>boX~Ix*g`KK;ubV752tkl z7vq*Z&iC;;zDt2m$l?vJTO5|GsqfKND*7GKt-J{L|n^UdI!pdlgIqb z0F^uLOIxVdpdcn)l4Pn-F)e=rxmsA!Lh z_8qTlJXQ}&jYX15x_E#yya8HO0sAYW1(tXDPGm5&GV&B^4(>a=FyRjIcQg=$D0&r`ujw?7@6Zhqm>CE}{a8GuI{WKnb{ zKWLUWYx%o6a<+8B~C^M=c@0 zeDnEys!#_+8h1e15nWz!lvbSlJAe$IER!S{+?ym=cNs(9FEUdp1dc|N-y&eBNPofX z{G#UkfTiUTF9J8}CA+530)6O&$o07&3>c7Lp(2X_xl6NpV!)Sa-uuALqIoSz0UywuDH*0-n>dd3%85G)(d_TY~M=Q9)E*a|zfqL`I1Qnz@2|l|#Ijw9T zN(1|Q>10p^p~lAs1@%x^Ib(;M4Nd>ykolmPh{1l@=v%odlq3Z>=AqBL2kGaC)7&J$ zg|gZu-il;T`Cv}51mIWLop?Oq`dh$MrI-4S#&~Z-{HW94eUxf^Y+YH3WOz@+g7(UUi)6om8>jPw(c zq1@x{%S1jK)E86wJ>pBMr|H~LV?FixkUP~ySe#%~mr#5OPn&lZxPD;WZ6fNu&^a4q&e;HBpY4o%^ zIP7xr;AC0-K8rRD=AZ2lZwDSc_{~D>MSa^Q+{N7*mqrsae^e`A`#L!(puw0d-^%&S zJd-W4iLTcKJpuqtlZl3$0u2hETq7yN1p^u!ZgTbsQd{+`!{PwNF~jHiKI{*Rx-wyG zqFA_%eR_xdWzp3G07j%{q*auwDfX=2?SrlZkv2cpHJw-(spfbfrq2g3A{${E>lqO# zgLOf3+Wj&;RAZ|**irx zpIYlY8qWyKHqj{LMfDX&eA|0@-`kvkYdFXlib(Km} zD>mWns7YI9Erp_EtijJj6D7@scE-g8o9Z^V@kr!z62iE7*E;y)K&Z?#|Knttm@P`q zc{b9KwNsjRns`niF-I&TK~f3p(@S}1d6!QJ^~@A3s0S5GM69@#`Q z7wp#`*|$_+W&hu3TDb*lsdn>(6HUz^f59dcEE~ARu2PK_BYamK`|*!5>h*$iVOOLZ z!7pI!gnu4qyYTH9lh$mRm07w|9``kon*}^-Jru7?TY|neYTKy(oh_i=&4|S#L z^EH0M(V*!W3Gn8poxrmQJepx%yC*=={1R-MP1WEnzpnL2W-b14f+laDIO$u3oETP7Q~b$WalYIwXQT4mxx2eMBpYx5l|WA+8R_kDB!= z80TBG{J;77^L`PRD!kg#?R$f584nI3Y>k|WFM*t6KyLHCCq+k$>0k0Kgt13iv`2mi zwh)r?7RI?me@d9ez;ard!)uTc6q4OWC1!l?Q@|;yd<`gTFp9{XLswOAdl$jg!b=Rb z5dIyGerhLj)tJ6foPNpiGl5V@nN3RebU&56Cx=Zg(-v7sIa02CwfNH*Xql37s8(D0 zb1G_~q;alkgu>ON>25&pm=<$!Xo4+A8R||Hb9uy@2Vdyh z{HC}&74&?E+q(A^ho`cVn|I+C&blGCF@MsGQ_5G+pQ%&UY^pYah>IF;tVS7?XNz?8 zUw<)A$wD!IB?&A6Ud8C|mA({^1h0nf?~u(bcAir%$%;&Y*QvDbUvrxiEEys1b#$O5 zGu8x@iSBeD_{;Ve?(q@d@(WGDNFYR8^gFBxh4pixo}hS#2$aGa9y3mHhKN6 zI*M3*d;_*77+4f z339;60&~%sk>D(*zv2Dy0a`kAEdh`}YiW<*N0lyRu@b(kD}?tQ2leDk~&( zg0&k9)Kgc9{7hYynu!XfjfvurCUaKRC5NkAd!8pqnmTUL8HX#$#GG7$Z{+g=DzW^s zBm#x&7P2G~44C-Z$8_Fg!>_ew^+l5Lhx{!x{?4+W$0G8c5QUs>PWs3MWU}py@rdhC zX?hmwh#Ke!1&X{*G3=hxg~AT~Q9<%y4b1Aw8RJ~LlNeEb@D~p#jAUIn2nl|-Az(~R zg06x&l=zi`1SV)XVNScY%^~7lkBpQ787_tDd zGk_;cX)Z!N<>|duU(sJjX!?^c0241V@zh3b(>5X5q)U(TxK)ZWXk}QD)yXC3bHdn* zs(9g(3W0<}7Z1N?TNCO(p|#(Ce5H9=kF1cMe5}d&84uOi%U<)aZ?7j3*IM9k_OW2` zfP_<2S3}sFa#HhK#~HUjmu$KTHewllxc!MmdAJ3DURYu)3VVt*ks2q5hE<9VF1%MBVRIA=UE1*K*A1)0MlLkfJWY^roAd7 zQ9Eb=4v8;lz@|^jQI7wq7Fg@$-HZLGMBYEWF#lW3+W(^#$eK7g8yH%f{D(4R6Tc-3 z!~h>s7ViHELGE`Bed%d{=P!kbgouI|uItXS*nylzV-a<4t@{eVo7_M{E|rh=VPYmb zlYRCwbAkpS-#$Jdf=dgDOla%bzL?F=1#x5g8p}LPTzF8Ch{yh8vcx|ZdHs7CT|>i2 zjFnN6IAMu7=&R4u!b^=y<<(nUrM2=q0_4YE`;7Xjxsfa_g1{a**as-(ha)HDXjmj= zitD~w-ezL1K`5^4Mr*p|SUB};x;>ruld=&7UD{N~zfD?|#54d^o-&KN_$j|X%c*ZA;^2d(E0-3;}Z0m^nqEjZK&jXa@H=CP9Bxt)B##>8Uf z(YoG|wcM}+}q1 z%1=fyXcF9#fi8ti5v10=pRv>dApf3&Xg8epZ5Fy_&(t~`8@GH zarg*H%jJa3Pcj7jge7J9tO<<+mk${MvfsM{Xx$CRgY*_0*s*x^!Yc*3o$v$_Gx?hi zCpS8gIMt{SR@nftKUZ0*bG zZ{ofgHUsf86Zy&1|L(;2(S@hii+1$*fcXcRpXv`aonFEkbpHvS@H=1RW1ab{B|w$1 zJ&<12FyCID&uho+XDHk^VsFoW*8M%r+E=T!Um51k(2McwpU}Vkci@bl@&i4fx14(m zk$7X5J0i1jN27AauNDB`0pG|9d`U5RAGgqWz7$+NiF+%UzD0XI%%5xp+l)>WM%JAf zO^R!iu-#aY&NKz3Tv-j)L`HUO!}q1&(|Cl;k301BHZP$voozZzE)%g&SnsR|fj({M zUNO@QL`?G>`X`DR2~?1OqQ_vKqcei#f7Ujq?V3l;6k%#M!e;tnqJAh7%*mU9TOV^+ z!^1&jquG_ndU<%t?E@QDRE7wkaOPU`s4Em1@kIW2&MR>=E^w&mwliJ1$jN z!d)oi)|O)`@Gmep<8!%1St7`dN`>^euGnexGsBK-n4MWbom1^#Thr*v`0^Eqo11Gm z$>LK9qbXtDw$X7b2V;=W8u7-W{=~hP!JJK8=_^#7FQ_7GrqOY@K~&9toiK->{$TTm z%mkz8;Md&tvLx+&F{9A2Z>ulew{?HysbFO!cneRc$+H$wu;pDN$D++44eFuP_`+Jc zQZFK`rkkpvFoo(8tzaM|+6_0H>ZXNN@C%xXaZyt}BEw#x(~Z`2X+d@)SJupJi_V-X zE5FQJEQz${Oqo=7<3{QpV?x0xQ2G;;TAPo4cH7^9-_{)~4X#`4RyI`mb`uy9N)+`v zAe_{SYtt9lk=Yi-D6^HrFDZrP?cGFaKOq-Z2jja}2bQY~5_O0{Y8Q1?Ln=t9bn8ae8#|wiLq{?{8^0$dlX*M&m zR#N|Y+)sR-_B>mTDttJq3YR{1@`iI8-n4_pev^4tW?i@AQu;wW>)3{jR4$#`V-l3X zM|45ohVSL;ei(c6Z&(r4TLb=>>&nq$BEKU|^ir^?4%2)2S@Wbac_>0M-VC-0uvtFi zV!wxkf=4GH@u{7tkBCG15wSk{g;4xnii?InM11S`kyUkfg~m$`hV- znTV~jnVO1kwFxnwlAo0v0NAeFfnAzD+Jjx%GwO>G0CO&uz^p1H7aY*z&fjT$PIEk) zk;*o#&|v!39l*W%f$exRTaUuQWmzw!*{Aw!pv*xU?)3EPIdV^uE#Hw6ZWmJuI%PPh zT#s&Oh5o3f)r=RcQ7#%u**FRqq>VH6gxFgNm-fbSgr*7Z5!x_Yqa7{WJs4arj!9x< zbQYX%w_GuwoS^n?u|e)$b1Nrcd`1D4Cf~R@Ph7=HuuJF4VP27kl%>ljj>CWv=r}hc z;LMdP6#|nQHI9Gfjb{KAj!7>M+jlH0VG<(Hs|!R0a!~htaXQtxaIaU+fS@dz)ytqY z5J^u7bNZttGy~B%&XgnV=Nu|zV-^SZEiz)k?@V)ONsoOaWYZLz;G0jIvsLYJ9^9Or ze{z>3%$!PPsVFLys9F$Id+s&8V#(Sre-BBoA8}UNQn+*?F}XYtCMQkUv!?ADkBAkb zNST!@#_mm`h--9L9!O5tk;eW~YjuojK0m5c3S5A_6jmJ_;b@o7IXD^nb5h}`Yvi3> zckO1`Q;IQsPYZpN(72GNC=HV?u8pV>yn6|_bJMIix)RoM>*vzf^Hs+Bikx9y; zTsf}9k_T$N`qK9W`#6Tgkq!UVZ_t>t7y@3DOs(r_M^o8IH&9CsCpx#QdDjxCmdp$^ zJHDP!aI{*+D1`yZazzhXP3U+dpppyp6VkZMsUO2sz4D>+bzfKi1K5U{yxYZbN&QOo zZ=Fd;fg8>FYG2*bMv(ecqqd{DoFDvT(1S>OLvU8Uvx(8@I5{R5#q*ky+fG$3FIlbBujqZa>L4S4hnw_`W&m$fcYow#|G;+0f> z1Jw(a*EdIa3i1^^DBz&n_qaTfeeeL$-2*!a3rj;5^J&t8Vz>dDBfYC>buZE&n!JKa zeMBKuLNNfkac7d5*0*YW_>VEB*+T2k5c+> zys#n>S6~^SJ*b5vT*?9Bs$FR;jy+rIUhP12Ih7%p-HL0pOe9HKAPM|U=e63#3vnHW z_B1XpKs0GqSe@`o!~Du@H$rB}-8zpmV0PDmI#%YOe^-RN`N0lzkE0~DVZk4+e(xKK zz#Cqs9S_Y2XzH@#=rvriehNWd(VnJpyngR@mFpBdu?D(kQAQ395oM# z+i4t~4$n?rnY(wa!;{70K9k88OzI>G^=nfqg-EHmClb+kLbE0TY-}L%7q#VvPvvw*|^NNuY^?JT7OP&I9fgf?%ol>mo&N}Z#;>9--00tiO;dE&YB|cNR zK^?<6vU6Rl7j05qvxlZEgin_cNciSQv8xZD==AeA28`r@rZo?OedKWkEcc~fu&*Q9 zV0STm4IPw`A)Gpn$c1fX9~0vQ&y7CDz;q8g2?b^Dm7*@rJ5m>>w8s~kmo6hpTVb@j z?bCv;rq1hV-TvCF(I4{h03@ZOmtnc#p@TTh6Zinh+%KD@5Ac+5Z_scS&wt;~w&aY< z?WF`8GD(b0ZFMlz+&Z#_>omKoq`VB5n$P6^IM}V~+#Iog11|qnyLW}rb&Ot{u0L>x zqKAcbdC$GV8$~Oa#&-F$_7X_viA&1%!axK;lXFO|mA>AlS+`c7#=bC+Q4f#Io!sOv8tNTFQ^m(m?{l$L2Igq|O?)juq z;otmNWniIB0Of#kg^u?ni~u3mvyyb3wwoOot7F&4vk~9ZrXq^ z#a4}vLBFD@BDRvutW^M&rIY|)$%A7|!!McWsz^UG6i*@W9bvnpA-J|F8Xz1cI4{DJ3P?B6e4BO#(S+CS4ED9``^EdReQT_TQ-c8>oV zrdOVF+7SNf-~YTKm$@XB?Sm}#=5&oPCl6sIX?D>(-)9dfhLnL4aZnZ;YGq7>0S(1s zv)vqzz(ND-hjB1_?dW~%#T&ZKElw~I!3~F#yV&~c)Ai!|a^vUw2J8<*662tZ*q$*A zzb(5*T#23P(J^d55~I>JP<7*|eo#NXhZ+X^D+_!3z&>jLb)Xe-Rd!bv=mt7Eqq2Zv z3U-N}rQ4^fkr>|=DmwY8)q=vtO31=>5j{H(Ui`XJrlml=viEnTEwizSUd2s?qmEq* z1R-0BtB@+*;*w9)>tUuOHJ6Obm4mAYgHP-|u1*FVO53(^5iBlWIR^v*%fWKg_9 zR;dLoSkTt^^Nd*4uEq+x$^^{dq9{VEV79WX%2k)jCXMu5`Lq`6&DEKu^Z7OhJ{#OZ zNFkD^-qKb#m2l-PC;@x8abw|YSMHkp~FSgd!2Pb2xKRrOS0qOP-dggs?$&|RK7O!F@P z6mg6wBjyfA_kP~lVH5Gi$B!fjTW}Bg>BZk79wW9>?FmiZ;c4`9>n7O$s{3hMUm@;_ zg+`<`ROmOEv~TYZ&;@@>XN!{DwuvYsK49i4Jjkad z2qa4wAdZondtePFgFlj7GonQGVQLmFDRa;KQnApPWmEG8QTRj=YO{dn_!-yxh43*p z%p=4g^}){)T^P)eO;Q5wo@z=A9&>Wb%~!Swo#v7B{A&k$`YS6} zkaa>ToT`i-e_??ikLT5qXI7pKuZgK{YJ?7n03!4^oO^pX&Vx;Ks2PGSaY%M0y0 z^n&I{6Z03M_fb>geRVN6)uU&yR>B`RdLJCi5Zqk*Px0BY0r^i6>h@O=N`g*lra#DM z`@*w*ZGW`qb!jcM3mGA@tmck71hf(2tSEyoxONnH#)pd7Dg?ci>AYsf-o9YOyjBQo zyxs$TEyopT%zIrrYTvO{FAk~4AI9r%0m^hr#)Z|NrGm|x1UmO1Y~28#)gs7%t?+b+ zq|r{t@w1LTk?G|1cxyYvQC&Mic9|I2enS6yxk4`to-zL^S0q2>>VFH1|9^wK|7!RB zS8un9jQvl^`da>WO(u0kEZYT9^u;L?j{gFXVW6><(%EE=XD*_5~`@H z`fsJHZeQt|YIZfY*1~p4#2=YRX|Rt!JvBhNG6L zff%Cr#JIvOHMe%mTIeXmm~4~BSDm>q*2eq1U&#(vyG$XoH$z*IeP<9{H5AS)CYqRE z4RdFOw@!jlU8^InYQaneDU`ss{>l2ec2@p;96H&T3Yk#W92FTQi`mvWo1fBUG-P?| zt!-6Tu~N~k5)kl@(sd?f01@Hpah`3_l2=#lXC`vAr(#8^T(J&oTZ*O*`4w{jdBCvVL>&JyQa5%Lv`ot4^l=c&*9RF66PuH?tS+u z#;hPO1`_(__l)5YHDY9X0t3Y7o9R$u?toQdS}Avw`VXNL`cPm**uA)*es}FYBzMI= zgd`H|e&o=7?2}~n8$R2AJ>u0IU8{3`$B1!}?JXOwWTJvoSUT)dZnB(Dvjv=xXXyDY zSRPUH?sPnE2phrZY7@9hvnLrvESA3qeI6=A&jY$%=TL=Dsf1}~@IA3=6I!BQ%vi5@ zBRJN;)seB#MI)0qTXOyjUEnwPeAOFBsUFEsq98pZ!dS%;!nWgo@S;OnBE?fTX z3*4UQB7|n~7HS7|REmEZ_0m^Klfb{R+=o;9+m$Pyy$wO-0Qzd<2vn_x%YQJ6u7%x2 zi#`b~uixk1{;KmeEEZ$q%GvbEM2i8i@@}D@+S}?bfeUXq_A;{h`?5b)mP1;W!P-!C zv9NE5HDtB~BKR_-oxy=WP6-<+Sb?kT@WV5N-ypIov<}{saz+Z}gk42Y|4crPqwtdQEs;WVS2!(-htYSD$fI!*Xy(3|sd*hwEH%u=yh^xyD1F?qKCKCmly$bw~P* zJ*K$Qz<@w>J!(jJsm^7ic#8B@iZ=sEZ-;8;fs)1$?pONEY6#0Z*Hacz}FQd`(h|Fiox>Za`Gcza?|4v)8JwB_XJ?iC``c^+5G z^C=B}o;pK)s^iKL^Nz(jKWHC!pce4CRAMomYp9ir)&-}-D*nth`#GC>MLcWlFjhd- z?hN4z;wVtn4PVmWsSOcJwd)AMZDl0;4fEge1;q%D{$KbK_`w(d|1Y(r=wj<^VPo?D zp_r7@x-#-t)%Jf;45?%RqLBNCV(@D~9Y$HdhNQ-bh^IH@#A>|{gGaQ1j-35Ndh2t zB@W0ctf{Z}h#6EE)ccfPYAb*`4I`)MNzM!y*6W(qsUxt^P4PWb#B0*q?4H~*%=9^R zH5jFNt!2tcpuGfsKMlLIl)1X4WKpf?{#OY9g_Je<^N1qI%=!|Xi}z$N-yXh-ZvI7elX1{Bcj z-as2a0AM$JCatPq_i*DvdaGtJW?s`G7)rLr1VwD7X+YX%Hs zyi`2n8B}+Zbuo^EYW>!{e@E1TLx5P<(F~rQ9|88Nz8m+@l*dLT3kv2+Az-zrXn9?Y zAt`gosxW_OGHg~VIsYTTnmU-UZt$Qt=zj#*MbEB$EdQ3No+@-?RgRvpsfryI%VWS$ zTI?fdkx~@pE=3fSG~O4k;{go>Xp|&+f8xhmM-UoA@<4IW`oBFijXvfd0R~w@lG$5< z_+tTuXj+56OFgujX(YsCbo9N==D)wGisPK}#Z~uLn|oledEJTm0Dg|9!TI=Q9|UHD zKpqQW(BXhV@Z5+QlE@v1p(>}d7;%nCir4bbD$;{0Nq4SU*8_b10~6u01%l6CbqQ|% z4=%1Ni@G0(O~fZNgv}2y$C{l)9tiJia1R%xavc!b&20VQ5tB@Wi+@o&feJ%%PRYG@ z9}k)0+NEW#*5!}yNi*&vS#_3x%)66Hd=I^epuzKC7#VjbvY zox!HsVEGCDF(?uhOf! zF-av*J;C1;;Wa$|U|76CD!eWGUkvLAO10^AF4DQM_+glkYupdRm~xtuN}`MXvG}en zrP>qT0)FMZ7Z&nRSja(6CfQTWHUBQ86D*oxhm5_3qkN@g_64iA{QydiQ!!=tWnAlx z&kd;dX*KT9W^{Hqwy{l*pj{H_i||x0AW+|ai8&LX*6kEP*(>l|!Xh(!GGm|VgvHRB ze|E0%{WFfS50Y4P+HmsN z<1cjsKLT3oTXKFM3P-hTK%z}8FduD1`}IF4X5Rl8konU&CI2y>W%>^kld%4;ww$$) zwSkk<{{UCAl8zjb05Xq|RCAS8*k#A89eA!d|-#Ep%5NS$%}`bFsO zB;G!-ov2>K?0_2LcQ9SoD_WErpQ4q9%mgWu+tn7w@kA?=o}cd>$UNr1uZkgutGX2vnG0)^|hd zM_tq&GPbunyzVZCwL%6WOwDDJ4M_F2kE=a2jztT!=UZ*m+7PFko`cVnAv2(F(_4wq z!OqeNmNt)?YIJXGvKUX>$`F~zd^JNyTk1Zkr)S7NY&rQZfeX z9Ry!Na8TTduT}2U*m&kyY$C))1eR9Pi=(g}{mwKh+;iNKLxeQ{o>`fqo(#F|-Q0qU z@B=e~>M_$BGF57Vv>=P^)8>k-^`{+EIQ3iFXm^_eOq7WM{??A{ah|D4CN?EzKp)c$j(H&}rTTd!o<}g{6@V zBqvk$ymc57!_bD(bLWz?{ROr=&|v1cg(`R<@Fnbl2AE>x`-Gx+HR>PGO)f!Q&VcBb z3$cg!B-t5xPEkf097VV_@g|1|MVk>Z_Rn5$>>`C?j8enjESW{*Sp0j~Q^3B=Ar6EO z`A{w5i`hX^c_1`NaqsOx_%X$mMqtzJ=1w?k+M%ps4f_O_!s1#*jm>-tnbG{4f_%EK zr3C^i;4A{%iCxvsEJ6U1be?SGTXaOOAZ6l$EjN6muW1}SSqMmnU=WYXw5JMF-~Zuk zV2HSxV*T^6SN&|;|Ec1Tur;!?v9~sHHW6?%bFne8b^afpe3sJx$}|d@v(-T>+Ys(> z?u9DCuOQUzA%{#~P-YI0iINjaOCj*Ga4n(q6W4nL4I>?5L(2IC{sQ&;dwbDP_J<0t zD>KdMh-=&JC^OBjo7Wd?M}Mlv0|^?<(1{`P)}7{G4Sl@G?0|xF`oBIBqQ>}aDsUCVJz_Cmu9Zqw;{kdt*uJ)Y ztd2HWw{kbJ{q3~1b?)Yg(!IAx(!xzbw`$5o56 zAhF~JvP>rISodhiKd(!cGmwl?XitJU0Go*N^c?Xq*?V>;JU1@?UTuhU0~PKh2fhoT zD=r)|Cg@AGmTkbIuz4Pw8nyNyG|P5MJPnuhJZhBzE7${5)R0+r6yaFIVn~gZ|2bH- zkzBL>RFgfb2kmx3YYvyJ~@r@FM&+z|M4+vUHQ{h!P^By63< z4V=tn4DA0~7FWECR6jp_$hOVAs8Pe?`kMwHEK6>yyAlY(Apc^ZW~c4Gq0+pJgyL+5 z->47*_Y3fc!k#oT2+s+wsi~RSwukBS<>w*F-$)fGQp!Mb!<0$v3=dW)(iCZB(5Mt? zO`txck?nGD|Gq3}FG+pCR*KskOi`DET!zhI$+~joqK_mCIA?U((o=)#tuJ|^FbR+> zPlTQJYO=3XtM9_8Fy|}sjkBk)PmGBhO}nJxU=~04X;qKznOw3peeCp z>*%7Z0}=d}-OfOVIR&#q%l|wM?O>EoE2Q5ffK5d6N++0iMEKLlNb8tU5Mtx;N;Zic z$>VZdvI#O29}Ba$8P-c_-HPmXP1Llw zC7&5zzP6ts=S;8b=JyJ}Z*O3JHd}MEY_I_H!9n~r`_WhlK3zz`;i6x!z*(g#X?9G-}h1GZKxz;+s{! z$3Geg2=G~jOrn^!Pj;kb*SF2L1_x($u4J)X zu3jOuzht(uyG>0rbMeaFDs!sUMM7E%=QXjb)u0|bu3`l1vzkpoXPg>V_3(wFM0G`F zQ9Mz-?BOIruF2bm^kRxKHL<8_wwR*Os`iD7Iax4qS)el3xw19xX@|hCMBkUNNQxIEY(RR=eY4~k=^X%wKV!jjjU9!(cn)ux*0^zzU9Z{u+qUIO%? zT1oQZW@@E`$I$>J6e$3cI@|!HRz(6E7&GE#7%fki@OJn;cFI`T;6SY}u{sT_r3qMM zQz@tv9d0ioo5RSo%*vS#6J`Z!cgxCS_ehbv0H|Ve-Hzp0CH|%RDYfbvm$#tvutx-A+khoXyvUzkth%uox zL5TzpW7hI9a0NntJ0-rpx!MHxpNQ$fO?mBBrCsXU0;tZolNv31|Fy65gEm}l^E0Te zDy$%VcWjo~z|>>dDt^FzqjiToijGb&!lm16;=lR7jKB^)oqR4agadaxuDM@Yw$OO& zUNjj88$}m}8L8im*WyZAMo)vN4e#zlm&!0-K~%6Td<<~RLA177y=031B2CB)rVL>Z zppDrpTz9!+&I+@^M_8W~L+uE~!J9q_kwF%N;TK(trEUKGglWdB6Mx` z`O2U&Ukg|b=H#_wyrB_%gG}~{gzStqyMfK_U%uhK(#O^tmTHj_=-QR%kpF$Ez@S6P zh*V_7e%+f$TV@+doJ)2^^x==TV$a&GQdE6)>IE(5AyJN9mD+#ZTTLT$Z{v1no1Ex5 zEm7^Hp1D!dIOR}tPqa{J#J0G0Pk_UkEoJ-Aymg!09qV4#NLD1$2p%TV_#Wn5mH(=9 z_UsRMDsDKu(@Poeu8i;wJN)(WuWi%lASW+e!BE{`u#z#$%DB64Pu(pJ$H=*C4vAgj zoo7Qzfo|4*X5L=@>d&6d-swERaJFXKC~i-4Y*-wArR(y;Pe(;R z-rQ`M+{g!<@q<|T9fZ}c9Bj6)sO6AvXk+R2KEZkKUnRPP8%Q-i9yrc)W=EcZw4v{u zUJbP8SnZ8Yy{L8*B)3Xw!e{OaKh@_ZgKsRN?<|JzUh^EpcRq}3y{LN%rbi8wCssJG z>d?;Re&2=utxE&G1Hg=ibh z^F^XJoGg>o)Tk343L;BxezgVh*Mg8Z#(ZDJB9O}0E&c_(MMD2l`? zXX5z+_T%zJvG0U}_568tfLf$Ev1d^0QmnfsHY(1OSi^IzmMH=PX={M^g5R`?dFw~* z2Koof=da0dl>ux&t*ND1dX!m135T|jl%!sXg@58dd4{Z=0ro13&`2!G*llP0{3I`W zWSS}o+t3GPZKe8bF-~^;JmCtD$Ws;jErqf>EOnz5^XiJ9?qXTDNf&$98h_?}00~Gj zzIRJ&fZBE2=uv4;b=&IZOv`(P3@zD43-5}+vN#0(gQ{TG;I#jcmF_t127h6#aFIKW$eXZvmS!d$AsTmfxpx#figHlk`c0<*D~Kc}%9AmZ>Gux}C2bZ5{5XV3-H6}02`>%VXN zr%?W+!he4K5<~d)i{d|2-O_eO2G%D3hp9=ls)fAPGRjv~6B(|YXxJt?_&Pe&@1dC6 z00(n=7eve5!p8^;N!&expx~fJd3=i$&eN^pQ(U&_OZLh{P6-BCfgom!MAGb2=M34e z=K1bR=ePRqwQQ%HxFBM#C{Z__=S-*W`z)vJ>#z4Eu3wxtc@gah$_z1a0T7_a$}8~B zgcF~{YzQc-!WxE>y&hzSl#&R?9swD|awRGkL&qo+r8oLb$dmu}55-zNqB7`i*7hm0 zdlE^A-;l@s;@N0R-7%+c)>7Rs$057=KGjs1_pGSDUAEpuDZ0Y#DBM#X!8MkfTRmcM zUSuI8d{RNXhV!@8Zh%p^US;KWLLq$%cRc*Z_^%sqAIzTmIo+b zE{3x#n#}M*rq^N(5(@$GGBv;5xIH5mCWBq9;5b2vbWLVUP>LoP!9Hky$}@tasX8pd zrOYK7)5w!CQ$4s3HAPnCWH4;^7Ijv>pMYwNC{{O!>CnpgAE1mjzYiI9@ID2!JYv@+ z1rQubUwyhyXtgB}1cHpDZzylk!);qPJ!STDZ^JNZQMEF?j|78&a3znQUB>Luof!iP z{Wv{zwX7nJs5J(9pDc9;e{Q6zuzHK|C0h{++C{Q7hAq2f7j+iQonzV-qIbM z?q;bS(|2;}BLt=^^qIwZm*3yBTnN)Q5)P!P^2Zy8kYpJTJB=PFoJGnMnq4YdoSuOe z3caXHC?}nfumH%W`Pe`JdUCCyymn5Dd^u|}fCaM5m=kE<6Ofu&@A0lxDtk#zsPB5bv2IK3#I}fev>4yc1aS)^ zOcc?RTo9pR46K7rG8}nlVpp7$C~ zk!0p7JlmwrGb~E0N#04Ru2m%Qd|L?m^(>AU&OSzWAV! zljv^<#&y_zZ^dJ6g;;2AXG8myZNCqY)qj!+(ZC|sfO$&|Z&pO~SP>#)Z{@bmqv8*N z*#x#>)VHJ74BkU)`PQ2m@k2?WPf=RJy6c2au-?PeH6iA8A)aLZ6(1>hHgo-6p1Ydh zHC)AK2+K(!V&QtPGCBb|*bGSONBbE#!ku=|_J7YbeU7DDz7RBzQ&Q&TZd7yz_mF@< zsu~#D-YW-cK>`93gej7wj`Mn2!Omf`f+n*>t?qzwnXA?ca;qH&i9oNbLoVFvX1$>h zlqA?U?lna1dtNRIM>xHr#O0H?;vnk&wwW;ya(X&U6%mvBkA6sa;@7(E2aj#^E=|7fbpV+}>|9X~BfjvPU z|Hya1K#rk|$s45@(A9Z2>4eGp2}w(ZBwJ@Dhgm8EGaNincINrQejU zgbxez;iei~6I?!|cYOS-vg9AEbR^w(2FWrg}5Dt!t(#SoMk|-HBHf%BMcg{EQoE z6Zz@-LsjQT*mpoJQ*`T=1i1(P*kN%?vtzg`ZRO8CF#AB^`lO3K?8q1L3bk6~A#~oK zW;Bj-0at-qcYumPJ~Hd?3u12LCwGeFcE}C$;+x5uCOn&SdQ=?D-XXIV&DbaHRJMml zuNpteU;O1uh~SI=_7f%fN)T8F6?q#l&*?iA%wd(vxyl#llJg@8_A4;*Bg>gG_FkiV z{)_3+Ue?yg(LsuZgSomDrEQ z(w|D;y|jQ&U6|z_kp{{fA99KMCT#iCyw%5kdqkXQ4#D+N=-ab4Khp$VoqOHiX#+EE zZZJC+$f}nmQ#bU?ZRtJ&(*CEiamv*3z@nn%savZOr0E+o3AEvD6&ay)GGe|`cgRj1UU(ctXvoZGbn;4$>lPjYcVLYi+P-0{N7-V><2$`WF zU2h$pTzD0>xhB)hMvniHI#@cCGOmnyahW(HvuxB6{SqO@&u^3!Bq#>iZktcxHkWNu z`AUC9ssb2_Q^R=Y`|ncZt9PdAze2&bf27ENI#9APa5kqCwsZNJn^H8eHT!?&b5yPD zk$&_DttW;=iZPOsfjPodzvl|M{9QQ&n6>!j3L)q)KY46p#|R-+B~fJ*u*Fk=8NY^!2f6q9&uzUdi;{1y`BM%zwF>m?4hC#w>u|H(q?p>hic)ZB&wIhOdy$yJDxd%e6prTNe z0M7lA%ESwsl)*@9**E)$XW92##IC_T6FlA90;Fx*-ii;O=s^tB>U#J7(0bku3V4c& zqK^FNiXul{I$kbja{LfbP4EZ9Rr!damV6auxSIW*OTO=ZnjOl6$U?>uA`?}8lF4W3 zO!@i{{`V0G6Hy5(NrqJ11uCTUwPDCHYn40`NeVfblSE1n^!&2CYbME8!>ZW@Z6c-X zC2s~hYb5(&aHRbQ2AO`M*ZlOdAGtdBPf%b*b6OD=(nQe7YSu>ja2#k9p)*N}YF^S+ z@@LN$^hadcM@BXp>uXItf?m=}vIXVbbNM@=?gO3oc|Q)6{gOLy%v8y?S}+N;2^*8C z^GP}!s(T2WsC2DzL9fX@TyGADW0X0~c!WLGEw z-u7VgT&AI$sT%EE^iWk*cdK;tm-IZz(@^0yB7cL)#GYy5GJktt)S zS27BgTn$5UA!5xNVw4Q|^dk#nM-(8AhgWZpvaQXx;O)Q};M(!E?h?R+9-mYIS)yqk z_r(}c3tS1U#qWyA!+)}mdg;{tBjAm8{dS`Zf9&9o;TgesiVM|~w_V~J7Xu4=`LZ5ZFn*8$^c(DblAAb3)hUnFf`!WUc-^W;l6T&SSY~}Oo7{f!xxFb{(m|#6J3$abh$YkTEEHr%}fZfxo zveimet0g}eRxvQJ{J`YKC~wWNqO}bTTT+zK`NK;;v&kq zBQj3%FU)6}EhOd&&ySXtq-)0lbnsV=mZqo=jTRBN_+up?u|O14s#K0e=i40dhA|V4 zam?HJnLFfQeB)tfLkqni0$Zd(CU!L@lt!x+k+g+im-F_C2;aPfx8Uqi`3egjiQ4%2 zNTc!g-(MhnBQg?}XzF&LSSz7~t#S%o{LL?kge@qCTqSOZ4jjOvxf{9@A&prlOEZD3 z${N)+1ibE81;JZ)Q)h-c=FjLZ7X<4fq?9w{N{RTA;RA|WK?UR`+o_k~5>c)_RyV!) z>O0*J&+yIwolTFn+=s@WSCgdY-Rzq4MrIl%G*)n0-}$32b}mD>>+b(((L!gA{kDuh z-G*m~Vxrp4&|$8ph<2W@m;jtF>+RzralZ#~11zRI1e&RD-S5`9`=_?&xv- z@-Y5RD@4doMI9PkXRUSs@=*S|+~WgXv@P))LcQUr$ZRJMI)-i9 z5O?_3y6ZL&*cT`}D0C`Bs$>{@&LGjG8v<+j?eDQo5<2>Hw^pn{)>-_iU@~PW( zmFitxF~($O=ktcw)a#VnRHvHX>rX!v4nH~r!Mg8M#XNv^un<{EQCbXMj5Lag#hoI6 z9=dEoGQPqeqZe8imPjv95Qe(75q)1l{LU_SA}9K_*N6-+@TAs zdi)xcVk>S>hN25+$gR&^3SVL79%B-H@jf^z%`4BZ`!74O{JPZ(9&k7JmGUQ3t6UYzrr#3U)u&k0@RPhy}RpS<}Xbyu;!-pO7*Q9!H%Fs>)?)tKd`J z`vzI?&rHoD1FD=+83<-&^)=3P)$6eX#wA>TeKEaba=s>uO?}c5IJEkGPhVjywx26y zvh<+Q;r3VLflJQC_%j^lMQLGG=C1exUDITj1b?GcN{odJ1I$#qN)j-iWDDD^X zJct7QftLRAVmSe5O_j~91(!ft-q^40G3-nA>ASK`6%vM$%^@SgP5*FQZz@ku9)u9- zuCbX(D*a<*m+HCzSJN7ANe?~AUnW)086qNBXe&T2hoFOTbI%-LYuY3!?iwcGm2^}a z_9(7J{4OTRNQArwN7OWlRM30?=;4*jqUe~s3%GKj`Z_hL6crs61l%=X*Vp9G4x8C0 z5oq+0%*Fct?AJBdvucyu~hNM^p8hH7?>GD}w z@FUU(j7YYCp0{|5&OzIe6zf|3#sldJ6Ky+;rI4a;H^UQtGiV8CNNaTiyDD>ZgAS~I zFLZqAX_nfFsvQ`@8iyj4Q&mHE?vQ@;@LhN?LwDJbl{-*5A852&U-VSNmME%(95ayg zkI@u=Uj6vw&0F-Uy>#T|q80)TpZK7!?=FL~&pfB|ojY6*BWUt{9jfD+ zKowaBSpW?^#XLr12458^5ozpJSCmQ(oY*%b*E8o4#05(O5L>10l8@vnk<7cvh^39G z=yVq9$z6Ygqm`}xL1^VuRZE18_a3Xi_Z^RRtZIY9#*|qDWNf~`6V@;Y>s#IIt4$$|R?r>96fGe?T@TV|JG?|~7$pVJXb)k4BeLZu^5T7IXXuT((4-FF zO{mTV0f8dFTlG(uV485y9R>)70Sb!)cktp$v?=xg(Fs}A?|gLQ1%iv6DN-)d>;YN+ z=0U{iJXON_?%4x7c!CGe1xMsZ()c%`y?ga6X`hgm z2Wvmz!>Fg+7{>{+0;83%{ew>sCeBf7-2(=$V1y_ouHJ2nj-b&9Y8W=DKwi&GYBvsz zuNV!m7aU*oZ>X>z5g|{;WNy{@>O-7hQ)IYdm|xClGfr6#+?bRihbwYKKc4+>KU*#A zoZ9o2^4ukcg|qsmd1XZVqrV|hC82-^`)9^?bpj z)k36|tTyH@0Zt}Wq929zMFltCO1m}Yvqb=icL3@ISBiIfk4_&FuXkXW_yN4-FWxTA z$3L-ivW6E5HQwC|RNtX(*u{$o($uB(sQCi(P8m(FF!D)3ZkYh!D7MH>Y|z%OSkSr* zQ}IcE80*XOcXRPAA#Z8c51j?6t+LPL3{7nnhj_MO#Gk|!Py*8oE_e_n&Yc!tX%&>x zlq=e=jYq}G2EX!}D%Z+)_dBVjeCy9GoY+S_pGvqp-<$ByFFKwjzvspyq+|7xtQ7)_ zPpH^iKB_38s@q(;0)I%+f{59_3!WICXc(WFQD5t+vjlpg1#t9lc-w#wAB<>E3>1~F zrRg_D%tuDb{GZk9&x)RM>4ovlh5H&E&c3&#sy6v%C%u_GwN5iCMvHYC?vtZ_xr z!Dy*ftYE5>;ni=*f%}Br);2k~>lOjg5x(=4p|4l#4_F8GW$Devg{SS&ZKGbM0=5Hp zjx)C%t&pzF$h|c<>~d)yTSykD9^w##j-xI<;UtNjU4!t>BgN{f5Tq=jGzd4~dhpW8Q`BKbVBVhu|LZYQ!<`7EU^>`B` zZy3A|!juF!_y~^cqG%$|(1XXCM+&^n@o5oeOco-k%u(_56I&u+9bnc6TrQB=ZW>-@ zXl!_<_bJRFkA9;awcN4Y{*QwLg0REb38Y`Y;K_axTmM53<9{guM+2k(a_Ilxw-?kQ zyfaPGzPq>C)JW%e#E9q zb>HnQ<9<}%L;Kb39pGK>27-6T7krat_?{1b@4Hnksd0Qm?+jkwg2R2Ccuvzzo#cSq zjW#jag2pQ9g4`CXVT>J!9_~aqjunhoY>W}9hiiH8lrKaMZj6}Z{IxL79|Os_QaHqA z=`Wx>IK__0Gle`tlc&&65mWI{Zu}XmRpuwPdLIRm##Rv82b&(O{EuTnxq{(DLWFUk6k%d#*i4MH9}6k#l#G@ zn^Q#2JkZn%H#j-B(50V+KMWQK(yhuxikZ9dt|!J!$WzOBfEAHMo4}+? zOWE@xTn69QGfl3h9bHV!T|grc%~A8$F!T(u^*CgtZgLE$ttUB`#nLn8HRt(DvLtn;Y1k+sTa~! zs&vSHe8U1sUlwG!OJ5w~NsCC(WNB2(S%+Q57Ku3cXqc0-jD7olRqy6(NQH{+SBCpP z3eEbaVeEhZ`fhN?P-`Nae;u3~>EZ8HZ52M9?fQrsbqT(FG^2Q4JwGPMh~l18KbYlN zE2-JHUcKP);ypU~LhvVQh-FH#MR8fs9eV%O-!T_q>SL;7T|*Qf4lAm(H!@-G$nS~{ z+yN3XbwB5rwj%z~!GHm0%|n!s|-HG9~nGSk|CUgL5fIS~@8WW*(2t~9CvCW{5{`CC5jWGyquDAYeI z4e;An_j4YQMD5MaGq1_z1_>3LPtzw%gLo1NTozN3V3hChOqS3^-x@hr1$!q77uhh> z%LFw$)JM4IfxQ1lWRqcN%3(epYtr8H&5)7dhy-OCHKxavfDsJ`Rho@gX2y{*4v2TA zPx!OeTQ?9|;SdccwFA+>I3+i^)Yw#S3dk?gp*-bTOpIIBWUsPJfHGkOnVkfGuh8YM zw5l&Nu3H5SZ=;IK+X8FjW@yHZK+alT+eZ0%iRXf>hyK9CRDJE4ycVNKDDsUuDR*6; z!qw~xe+rBcHx3T`y@_!wFUAJW#(aa?%Od7cH-!Fe+BI_f z0y%AhxYYxJ)>?PmNFsZzb#i;u8ExtTq!L12>fzKYZn-0%pCB5$|Lip$TvHj4aK^>Q zG}tgB;e?eO%c}3nbWspy$jbJ;q;oE0k`CtX(|ukF;Xjl9VlB|(g$#m1{FeAl1XP6* zhZu(%hd@uM&!-+gRuY2Gr0;9lIaR2tc0#uVpbs0rtJg}CUeT*%Sf>xa1M`{wsXEjY zTraX3h}K)%jKcj-R+@b3#L)H?agH>AL`?9j5mUMwWbzf+%0(1kq5`CBOdv=dWU^!J zgxZCUA`>$-04oZ>S-HZ2XK#~{+f{^~cLEKCT`$GWJXUr8B<0GCqT8Ma8MX4m1;!uR zHr+%-Me`LWFuxUJnMu~1m%F|$nhVmZTR-K|`9Uq=2YL4by^UDugDfTX2P#OYP8?Qn zk)HlF3?q1TEa56W{c9SI;)z+?_vKL)zg^h>&C?}kS%Ise`}ktZGgZJ0ut<{DJz?@@ z-$rdNDs;`=$~jGVky`67`C+ASqEqP3iJ!Sh%PV4Bxw&@v3$=G$D<>* zLLicGtNIX8npg=FX%#x#n6!zcCAa}Ph6*T@{!*glS=n7S@8Gn@V4|w*#uu8zAM#qk zt4LYZlCc6PZBeeTxrEdna$fepI0Fi9cRPM7lze%69?>mfpDz~|PXzdC2yvs}u%h8* z^$GFfZ;D)D+iJ>LXdxjUSBNE{r2C~iH9fA58#FIgEFgmk z>CkN}P%#F@4YxLSB8ez}AXCed%%V1l0fbxni>!38U}2A8VUM_y(;xmTT$9^B`GtCE zpTe1`UC-ZdR+Hu@(az#EFp9JG8=l7Mlr5?LJI?0&QCRz7dHpB?uNbSwur9mt`m7@8E?~PLIKsW-^6Dq?ofhyL?KPHK>?o%8@BFxlZYF)VZ36FlsLJRG7t z?A25WP(2(3Q;Bdr>?g6rjzc=$cy}^y{_c6JI^|nf$XFXf=&{+7YpMl@zs7@&_gO&<& zdI_J{Gl!ibT8tHon2mB8d#h9=+hz$vb(G+?%Q>)-8CFlWzz3gYCNgQ7I2yjwP^AH-acIiR%s(>i$@m=1}{Z15$qTq zQ{p_6QzHX~Z{_bSkDMajz)TBr@&&#TuV=^R^4&d{kK;g*Hj^3`x0&|s*1Jb?DJB+8 zZnGc3*TmT-jx38>g6VtcsY5NYfKGS1CD?DpkNGDN=C!FOE^diug>w=wNwYI-dW z>LykT0MZt-Q5^P|P83VrNtpKxo9g@~X!&dEL4!kv+WO47gXRMwLmn%}%!ioCsG^e= z5j63$Syu7wt1A-5?uSgVIt1k{>%EOyR_F;a;PRMpx4!H+!&WgpBrvEyw~~)AH@!78CXnK=Ldz&Qy6+)7ZY}8F}a1b z^=IgrE)~Emz?lFp=OZo_46(}Wpn_DC|AIc=>!XHFQXCE5=NFe zTT|ZniD*tOxX_R;aWqvNYt_K-0yH-CPxtCtxc#BrCYh1B&9)JB5DN7y9YZQ4f}V|66sdnXAUY;7-@b6YLHWI`3d?hN{4EbfF>#9#B6u z0Wyx*=m3%d?x!WfpvY_1=~_M3k+)au^U_JqIHN4H);jiaxVS@b1=EcP%Kayx6o2e- z{+J@Z;X9|n#%SbaR~3h)=eS1$ORu0c+|P=&uZqdH;5|UWb=aej@h3(dufS4lHi=d6 z^ga~pxr*zaYbYjmNe!nTg3A_LHidZ8)kd;o{b!r#aSB=_0%Iin+ngS;@yIjlJ4xRt zlJ3?l2h8e~P4v~4Gb~-TiG;<@re&P)QtmN;anG`b@~3WAuuj@s8d$3-=&hQ$+ezAx zB%J?%Jzb>Z94gi|LOZr-kQ`eSd1YQ2Ro2n2fdJ^0S&Ryq&owBKt8$g6eXz#m2is_$ zmb)%$XswafP+UB6CO!#3_igQvF*}#4MN@EyhL9!YIF=4zxptvR~xn7f~jKh354D%T`>BFU`6Zg z6AjtfZ@kcCGx^4*M)B>i>_cxEAAC$Hj~Q?_v{#uiUg@8Ii)_+g8K!+E*nXU50-(Y* zXpt|*U*IGgGOuIwW=9W*q*?S1sDc7{rpc$f2I{AGC5zKjPYzORV7|-rFm?B#2FBlt zc4e6FZ5~OQ?j?Co*J>YweE6QeJj6F(s!>3%tP>4}d(%6Xsg}pQE7hkpeu}I~ta?>z zj?-irH5VsR>|#8VBkF~8l|Si?=FI0ceca9Xc~_Icx4P?K(cUFr5wfLJ|Frd%SmnL% zr_K+fj1*NeYR=2E9ExTry~@Q_VNpfO+hA{-%p z=T{Z1zB+hd##UNQum%{ZLE)K+O4^1om4$6WtDQbYQvJ78k!9f1LlfAIr&{+Pils%4+|p1^C`i`f-` zsOTZ%lj25XBLvqAkFQqyNjaO*4^BdqP2HlD$E3@Oo!TpXI2&`P&^~qe8S<*}X5yh! z^C0!FJ5-OLU23py`Li3dPx7|mUYAE~uo$qbrrQqD`r2zvA>cq+zht+3r7>~!fJI|| zwv0I(=iEdjmMICk;dDoMy4GIkdJ^9o(m&BezOGZ{XFqnGjz8e$|4oefzmtLzA|fJe zEX)r7hHoxTp0ULeK_2NbN=uAsTu)M!wiz|s_LvN^7p5-mJyyl>uHyn`92I+++UxLq6@TK-#Y+>)wRuFnA| zbRLqk01`ALf4pth6omyC4|BHI<)=_hjFSZ{rnTh!jSyJaFP|*mO;?>Fsq+$dUNaYB zpG}YnIDTYOs>~vl@{Idqm0*i`jV>X*Tg$Jp&g-()Je8qO*J6|3ew0L1js#)_Owcny28S$w)^xK}DBMd8y|ZVx6(oA39PO_v(IlyHFLGY52IRk#CS6LGdkKpvllWmHcu*msa}9;vIsOpVQl zIvX7Y*4YA~eiD*;FGye0&B{BYHWPwiZ!Dzlef&5OYLhptO9qN0F{+O96MRb*94L!P z$%}dOl+Ov$5);cfC#NAVJ6)l=`qho8Qa>lx>Nq|eqp8OiBA?3#SY!j!c8ncySL5u! zE%d9@(3!;}R4{ zMrz|d(A37(aul&4#UE6~H&{#`vJ@Wz6d$kP6qfH&?m-H;5K^z#{>7Crlt)4Y6ihOL zwRMCM3;&bCJZtm-YJ2XC~?8ijU0th~souw@a3knC}Y@-gD>meb$Nh z49C~!k02C+A96RUAldP9K1v9)X_16fVmv9;lsXI@8zGt?(H#M@o<*ANU>kftdB{r_ zv5?w)QZa?O8u%UxwWOoYKrsBeywzYuy|+xpO7Uw1v#r_7pAa^X0+PbCCC5b3x+E5; z5ivOMFd;yh0h4^AGZ0IKndInS^iB>(vA*xAessAsc4K81XOVz^*?Bn~m(!YnHAbe- zp*$!{(dNtN0*s5I_ifq)bt@~)CQpkeYdK77Ez^-y7&OJ91}#1=INCv;jiA&mbNzZ; z8*LM!FPFJfXwVOiKBDBgOJ)wC&#b2%fPOI5bxdb1jB5$KDGUv1vS;^iR>R^`8L!-~ z#s`PaR74WIBmM+?kd!6-nzk@lSY|DQu~pfq;14mB4jGp`yH76g8$@xgr*Q{ec_*8F zuqNTCIqvIcF<_T;{)W>^;ly379b)z*N;17nVK_soZAe2XkAc%fQvV$Kgj2W!`!!EM9>6UYQ|?rzc@LYiG}@Es z0G4`o%Sp{n5n#?3<0#sWxQ@G{ge7JAs%i|5AVl$gGXu%Q7mW(wj%JDLx_?Oe&Gb}1)i(H@`VpL_HL#j zaG+$h#S`R{Elz9LWn|Q%amNO}BWy|dQ}CT%vGG=}4m2y^x$1L9w9m>jQ$#*+ug)CS z>GVU$>PP5Q8t~mb;* zl!AHvw-n={<(12pDB0{@>O8w>yCz6C_p~Lr<-WF};2ZJn=ue)5T|#4bLeWw+OPdEm z>>ojGs(ulhCq$6e$ttbAr|rGeiq5O*J^X4W-D}2yYX(nUG0dH!sGS1oondz`Fx&kO ztxq1W!1ROy9^=T}2$#SD7|J;txkdp-3H^{cPx2L6(anLJ+?{8G+{9ZV3uq@|AODc| zFcKB`90NW#ID~RaQ{Q77iUNlRfSF6gi8HYX!BrPma&Vg)46+B8WF|Sb5YP7!o20yq z&)Q+GQ;+*;*G|Ph%zaE!*IdriR4mf~EAHrEoq07MjnnTfIkQAcJ^M6&wo`o-PCmhY zU(#~#DMq{fKb(Tm9bSgccJ6@ z;kXCPdkAck+6MXcYpQ?%@r^NMnh9Ad|a zp?0I7{So~Mx7iU6XmcQuMQw{#g^kosS|7)?t{!$-1&fNpwLWT<#wtl$#+gVNbh}n4 zXzTYX5KFD5_G%UF1@R6#)>FZ~0yHra9{z66fM(re3gHcdMyxpE=SSBJP9ku}`nzQw zo4jh+0eF~%**-C$0i--bH0!P4R3!cGJbJGLuk8olP^nFTV?92SjkE5dg*rbG@WW1j zj&P$$H^>|=$24)u?I`2A?22r>?v|ROA?ಱi+3}G~Fe4k7F5Yzrq#vdH}ij;2* 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 z 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≺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�(gwP)>9FxEnU*j15wa-k%p`ry{EAA^ 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
CLy1XjM0ai2t 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 literal 0 HcmV?d00001 From 0f890f9e6e374ef4d29afe770aa94992c52a3bc9 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 12 Jun 2020 17:10:53 +0200 Subject: [PATCH 036/169] wip: feature function #25 - adapting to most recent FnO spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FunctionLoader - handling the function loader as a singleton → avoids unnecessary parsing of the function description graph StdFunctionLoader - parses the functions according to the new FnO spec (i.e. no more "lib:provided-by" things etc..) - Dedicated FnO exceptions are thrown when needed RMLVoc - fno namespace changed from http → https - added fnoi, fnom and doap namespaces FunctionGeneratorAssembler - now uses the singleton functionloader to load the function FunctionUtils: - added more type classes FnOException: new exception class for when things regarding fno go wrong --- .../core/function/FunctionLoader.scala | 29 +++- .../core/function/FunctionUtils.scala | 4 + .../core/function/std/StdFunctionLoader.scala | 133 ++++++++++++------ .../core/vocabulary/Namespaces.scala | 10 +- .../framework/core/vocabulary/RMLVoc.scala | 49 ++++++- .../FunctionMapGeneratorAssembler.scala | 21 ++- .../rml/framework/shared/FnOException.scala | 3 + 7 files changed, 184 insertions(+), 65 deletions(-) create mode 100644 src/main/scala/io/rml/framework/shared/FnOException.scala diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index cca2e899..3c607c25 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -3,12 +3,13 @@ package io.rml.framework.core.function import java.io.File import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.model.{DynamicMethodFunction, Parameter, Function, FunctionMetaData} +import io.rml.framework.core.function.model.{DynamicMethodFunction, Function, FunctionMetaData, Parameter} import io.rml.framework.core.function.std.StdFunctionLoader import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode} import io.rml.framework.core.util.Turtle +import io.rml.framework.shared.RMLException import scala.collection.immutable.{Map => ImmutableMap} import scala.collection.mutable.{Map => MutableMap} @@ -32,11 +33,7 @@ abstract class FunctionLoader extends Logging { def parseFunctions(file: File): FunctionLoader = { - - //TODO: passing hardcoding Turtle-format. - // HELP: shouldn't we derive the format from the file itself? val graph = RDFGraph.fromFile(file, RMLEnvironment.getGeneratorBaseIRI(),Turtle) - parseFunctions(graph) this } @@ -94,12 +91,32 @@ abstract class FunctionLoader extends Logging { * @return */ def parseParameter(rdfNode: RDFNode, pos: Int): Parameter + + } object FunctionLoader { - def apply(): FunctionLoader = StdFunctionLoader() + private var singletonFunctionLoader : Option[FunctionLoader] = None + + def apply(): FunctionLoader = { + + if(singletonFunctionLoader.isEmpty) { + // construct functionDescriptionTriplesGraph + val functionsGrelFile = new File(getClass.getClassLoader.getResource("functions_grel.ttl").getFile) + if (!functionsGrelFile.exists()) + throw new RMLException(s"Couldn't find ${functionsGrelFile.getName}") + + // construct function description graph + // this graph will be used by the function loader to map the function descriptions to their implementations + val functionDescriptionTriplesGraph = RDFGraph.fromFile(functionsGrelFile, RMLEnvironment.getGeneratorBaseIRI(), Turtle) + // construct functionLoader + singletonFunctionLoader = Some(StdFunctionLoader(functionDescriptionTriplesGraph)) + } + singletonFunctionLoader.get + } + } diff --git a/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala index 507afec1..36515a43 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala @@ -62,9 +62,13 @@ object FunctionUtils extends Logging { case Uri(RMLVoc.Type.XSD_POSITIVE_INTEGER) => classOf[Int] case Uri(RMLVoc.Type.XSD_INTEGER) => classOf[Int] + case Uri(RMLVoc.Type.XSD_INT) => classOf[Int] + case Uri(RMLVoc.Type.XSD_NUMBER) => classOf[Int] // see todo @ RMLVoc.Type case Uri(RMLVoc.Type.XSD_STRING) => classOf[String] case Uri(RMLVoc.Type.XSD_DOUBLE) => classOf[Double] + case Uri(RMLVoc.Type.XSD_BOOLEAN) => classOf[Boolean] case Uri(RMLVoc.Type.RDF_LIST) => classOf[List[_]] + case Uri(RMLVoc.Type.XSD_ANY) => classOf[Any] case _ => throw new RMLException(s"Type $uri not supported for parameter") } } diff --git a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala index e0ef2151..a1b467ae 100644 --- a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala @@ -1,67 +1,112 @@ package io.rml.framework.core.function.std -import io.rml.framework.core.function.model.{Parameter, FunctionMetaData} +import java.net.MalformedURLException + +import io.rml.framework.core.extractors.SubjectMapExtractor +import io.rml.framework.core.function.FunctionUtils.logError import io.rml.framework.core.function.{FunctionLoader, FunctionUtils} -import io.rml.framework.core.model.Uri +import io.rml.framework.core.function.model.{FunctionMetaData, Parameter} +import io.rml.framework.core.model.{Uri, rdf} +import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode, RDFResource, RDFTriple} import io.rml.framework.core.model.rdf.jena.JenaResource -import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode, RDFResource} import io.rml.framework.core.util.{JenaUtil, Util} import io.rml.framework.core.vocabulary.RMLVoc - -case class StdFunctionLoader() extends FunctionLoader { - - - override def parseFunctions(graph: RDFGraph): FunctionLoader = { - val functionMaps = graph.filterProperties(Uri(RMLVoc.Property.LIB_PROVIDED_BY)) - logDebug("found %d transformation maps".format( functionMaps.length)) - - for (map <- functionMaps) { - - val providedByTermMap = map.listProperties(RMLVoc.Property.LIB_PROVIDED_BY).head.asInstanceOf[RDFResource] - - val libPath = providedByTermMap.listProperties(RMLVoc.Property.LIB_LOCAL_LIBRARY).flatMap(Util.getLiteral).headOption - val classNames = providedByTermMap.listProperties(RMLVoc.Property.LIB_CLASS).flatMap(Util.getLiteral) - val methodNames = providedByTermMap.listProperties(RMLVoc.Property.LIB_METHOD).flatMap(Util.getLiteral) - - logDebug("\t" + "lib path: %s".format(libPath)) - if (libPath.nonEmpty && classNames.nonEmpty && methodNames.nonEmpty) { - - val classNameLit = classNames.head - val methodNameLit = methodNames.head - classLibraryMap.put(classNameLit.toString.trim, libPath.get.toString.trim) - logDebug("\t\t" + "class: %s - method: %s".format(classNameLit, methodNameLit)) - val inputParams = parseParameterList(map, RMLVoc.Property.FNO_EXPECTS).sorted +import io.rml.framework.shared.{FnOException, RMLException} - val outputParams = parseParameterList(map, RMLVoc.Property.FNO_RETURNS).sorted +case class StdFunctionLoader(functionDescriptionTriplesGraph : RDFGraph) extends FunctionLoader { - val functionMetaData = FunctionMetaData(libPath.get.toString.trim, classNameLit.toString.trim, - methodNameLit.toString.trim, - inputParams, - outputParams - ) - - functionMap.put(map.uri, functionMetaData) + override def parseFunctions(graph: RDFGraph): FunctionLoader = { + logDebug("parsing functions the new way (i.e. using StdFunctionLoader)") + + // a fnoi:Mapping + // property: fno:function + // property: fno:implementation + // an fno:implementation resource have type a like + // - fnoi:JavaClass + // + val fnoFunctionProperty = Uri(RMLVoc.Property.FNO_FUNCTION) + + // subject resources with fno:function property + // these resources have type fnoi:Mapping + val mappings = graph.filterProperties(fnoFunctionProperty) + if(mappings.isEmpty) + throw new RMLException("No function mappings found...") + + val functionDescriptionResources = this.functionDescriptionTriplesGraph.filterResources(Uri(RMLVoc.Class.FNO_FUNCTION)) + logDebug(s"${functionDescriptionResources.length} functionDescriptionResources present") + logDebug(s"The current function description graph contains ${mappings.length} mappings") + for (map <- mappings) { + logDebug(s"Processing mapping: ${map.uri}") + try { + val functionUri = map.listProperties(RMLVoc.Property.FNO_FUNCTION).head.asInstanceOf[RDFResource].uri + + val methodMappingResource = map.listProperties(RMLVoc.Property.FNO_METHOD_MAPPING).head.asInstanceOf[RDFResource] + val methodName = methodMappingResource.listProperties(RMLVoc.Property.FNOM_METHOD_NAME).head.toString + val implementationResource = map.listProperties(RMLVoc.Property.FNO_IMPLEMENTATION).head.asInstanceOf[RDFResource] + + val className = Util.getLiteral(implementationResource.listProperties(RMLVoc.Property.FNOI_CLASS_NAME).head) + val downloadPage = Util.getLiteral(implementationResource.listProperties(RMLVoc.Property.DOAP_DOWNLOAD_PAGE).head) + logDebug(s"Found map with methodname: ${methodName}, className: ${className}, downloadPage: ${downloadPage}") + + // Get function description resource that corresponds with the current functionUri + // If not present, throw appropriate exception + val functionDescriptionResourceOption = functionDescriptionResources.find(fd => fd.uri == functionUri) + if(functionDescriptionResourceOption.isEmpty) + throw new FnOException(s"No function description resource found with uri: ${functionUri}") + + + // extraction of input parameters + val expectsResource = functionDescriptionResourceOption.get.listProperties(RMLVoc.Property.FNO_EXPECTS).headOption + val inputParameterResources = expectsResource.get.asInstanceOf[RDFResource].getList.asInstanceOf[List[RDFResource]] + val inputParamList = parseParameterResources(inputParameterResources) + + // extraction of output parameters + val returnsResource = functionDescriptionResourceOption.get.listProperties(RMLVoc.Property.FNO_RETURNS).headOption + val outputParameterResources = returnsResource.get.asInstanceOf[RDFResource].getList.asInstanceOf[List[RDFResource]] + val outputParamList = parseParameterResources(outputParameterResources) + + // construct function meta data object and store it in the functionMap + val functionMetaData = FunctionMetaData(downloadPage.get.value, className.get.value, methodName, inputParamList, outputParamList) + this.functionMap.put(functionUri, functionMetaData) + + }catch { + case e@(_: RMLException | _: FnOException) => + logError(e.getMessage) } + } + logDebug(s"${this.functionMap.size} functions are parsed. The function maps contains the following functions") + this.functionMap.foreach{ + kv => + logDebug(s"\t${kv._1}") + } this } - def parseParameterList(resource: RDFResource, property: String): List[Parameter] = { - JenaUtil - .parseListNodes(resource, property) - .map { case (node, pos) => parseParameter(node, pos) } + def parseParameterResources(parameterResources : List[RDFResource]) : List[Parameter] = { + parameterResources.zipWithIndex.map{ + case (paramResource, paramIndex) => + parseParameter(paramResource, paramIndex) + } } override def parseParameter(inputNode: RDFNode, pos: Int): Parameter = { val inputResource = inputNode.asInstanceOf[JenaResource] - val paramType = inputResource.listProperties(RMLVoc.Property.FNO_TYPE).head.toString - val paramUri = inputResource.listProperties(RMLVoc.Property.FNO_PREDICATE).head.toString - val typeClass = FunctionUtils.getTypeClass(Uri(paramType)) - Parameter(typeClass, Uri(paramUri), pos) + val paramType = inputResource.listProperties(RMLVoc.Property.FNO_TYPE).headOption + val paramUri = inputResource.listProperties(RMLVoc.Property.FNO_PREDICATE).headOption + + if(paramType.isEmpty) + throw new FnOException("Parameter Type not defined") + + if(paramUri.isEmpty) + throw new FnOException("Parameter Uri not defined") + + + val typeClass = FunctionUtils.getTypeClass(Uri(paramType.get.toString)) + Parameter(typeClass, Uri(paramUri.get.toString), pos) } } - diff --git a/src/main/scala/io/rml/framework/core/vocabulary/Namespaces.scala b/src/main/scala/io/rml/framework/core/vocabulary/Namespaces.scala index 79485e58..7fbec062 100644 --- a/src/main/scala/io/rml/framework/core/vocabulary/Namespaces.scala +++ b/src/main/scala/io/rml/framework/core/vocabulary/Namespaces.scala @@ -38,10 +38,16 @@ object Namespaces { "rml" -> "http://semweb.mmlab.be/ns/rml#", "rmls" -> "http://semweb.mmlab.be/ns/rmls#", "fnml" -> "http://semweb.mmlab.be/ns/fnml#", - "fno" -> "http://w3id.org/function/ontology#", + + "fno" -> "https://w3id.org/function/ontology#", + "fnom" -> "https://w3id.org/function/vocabulary/mapping#", + "fnoi" -> "https://w3id.org/function/vocabulary/implementation#", + "grel" -> "http://users.ugent.be/~bjdmeest/function/grel.ttl#", "lib" -> "http://example.com/library#", - "xsd" -> "http://www.w3.org/2001/XMLSchema#" + "xsd" -> "http://www.w3.org/2001/XMLSchema#", + + "doap" -> "http://usefulinc.com/ns/doap#" ) /** diff --git a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala index 25db748c..cf456ca3 100644 --- a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala +++ b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala @@ -32,10 +32,17 @@ object RMLVoc { object Type { val XSD_STRING = Namespaces("xsd", "string") - val XSD_INTEGER = Namespaces("xsd", "integer") + val XSD_INT = Namespaces("xsd", "int") // signed 32-bit integer + val XSD_INTEGER = Namespaces("xsd", "integer") // integer value + // TODO: xsd:number isn't defined in the XML Schema; however it's being used by grel.tll + // Therefore, this "Type" is added as a temporary solution + val XSD_NUMBER = Namespaces("xsd", "number") val XSD_DOUBLE = Namespaces("xsd", "decimal") val RDF_LIST = Namespaces("rdf", "List") val XSD_POSITIVE_INTEGER = Namespaces("xsd", "positiveInteger") + val XSD_BOOLEAN = Namespaces("xsd", "boolean") + + val XSD_ANY = Namespaces("xsd", "any") } @@ -118,6 +125,11 @@ object RMLVoc { val FNO_RETURNS = Namespaces("fno", "returns") val FNO_TYPE = Namespaces("fno", "type") + val FNO_IMPLEMENTATION = Namespaces("fno", "implementation") + + val FNO_FUNCTION = Namespaces("fno", "function") + + val FNO_METHOD_MAPPING = Namespaces("fno", "methodMapping") /////////////////////////////////////////////////////////////////////////// // LIB @@ -128,6 +140,27 @@ object RMLVoc { val LIB_METHOD = Namespaces("lib", "method") val LIB_LOCAL_LIBRARY = Namespaces("lib", "localLibrary") + /////////////////////////////////////////////////////////////////////////// + // FNOM(apping) + /////////////////////////////////////////////////////////////////////////// + + val FNOM_METHOD_NAME = Namespaces("fnom", "method-name") + + + + /////////////////////////////////////////////////////////////////////////// + // FNOI + /////////////////////////////////////////////////////////////////////////// + val FNOI_CLASS_NAME = Namespaces("fnoi", "class-name") + + /////////////////////////////////////////////////////////////////////////// + // DOAP + /////////////////////////////////////////////////////////////////////////// + + val DOAP_DOWNLOAD_PAGE = Namespaces("doap", "download-page") + + + } object Class { @@ -174,6 +207,20 @@ object RMLVoc { val FNO_ALGORITHM = Namespaces("fno", "Algorithm") val FNO_PROBLEM = Namespaces("fno", "Problem") + val FNO_MAPPING = Namespaces("fno", "Mapping") + val FNO_METHOD_MAPPING = Namespaces("fno", "MethodMapping") + + /////////////////////////////////////////////////////////////////////////// + // FNOI + /////////////////////////////////////////////////////////////////////////// + + val FNOI_JAVA_CLASS = Namespaces("fnoi", "JavaClass") + + /////////////////////////////////////////////////////////////////////////// + // FNOM(apping) + /////////////////////////////////////////////////////////////////////////// + + val FNOM_STRING_METHOD_MAPPING = Namespaces("fnom", "StringMethodMapping") } diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index 48792dbe..eb4b28c2 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -24,7 +24,9 @@ **/ package io.rml.framework.engine.statement +import java.io.File import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.function.FunctionLoader import io.rml.framework.core.function.model.Function import io.rml.framework.core.model._ import io.rml.framework.core.vocabulary.RMLVoc @@ -54,8 +56,7 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { } private def parseFunction(assembledPom: - List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): - Function = { + List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Function = { this.logDebug("parseFunction (assembledPom)") val placeHolder: List[FlinkRDFQuad] = generateFunctionTriples(new EmptyItem(), assembledPom) @@ -71,16 +72,12 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { .`object` .value .toString) - - //throw new NotImplementedError() - val functionMapping = FunctionMapping - .getOpt - .getOrElse( throw new IllegalStateException("Function mapping hasn't been read/init yet")) - - functionMapping - .functionLoader - .loadFunction(functionName) - .getOrElse(throw new IllegalStateException(s"Function $functionName doesn't exist")) + + val loadedFunctionOption = FunctionLoader().loadFunction(functionName) + loadedFunctionOption.getOrElse{ + // complain about function that isn't present + throw new RMLException("Can't load function..") + } } /** diff --git a/src/main/scala/io/rml/framework/shared/FnOException.scala b/src/main/scala/io/rml/framework/shared/FnOException.scala new file mode 100644 index 00000000..9230bc98 --- /dev/null +++ b/src/main/scala/io/rml/framework/shared/FnOException.scala @@ -0,0 +1,3 @@ +package io.rml.framework.shared; + +class FnOException(msg: String) extends Exception(msg) From 5b1cfecd06b877c3187822473f762f48274cf601 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 12 Jun 2020 18:07:29 +0200 Subject: [PATCH 037/169] wip: feature function #25 - refactoring tests Due to adapting to the new FnO spec, the following tests are now failing - RMLFNOTC0004-CSV: uses toUpperCaseURL which isn't implemented and defined yet - RMLFNOTC0005-CSV: uses toUpperCaseURL which isn't implemented and defined yet - RMLFNOTC0006-CSV: uses toUpperCaseURL which isn't implemented and defined yet - RMLFNOTC0011-CSV: currently being ignored until agreement on testcase --- .../RMLFNOTC0004-CSV/mapping.ttl | 9 +++-- .../fno-testcases/RMLFNOTC0004-CSV/output.ttl | 0 .../RMLFNOTC0005-CSV/mapping.ttl | 10 +++--- .../fno-testcases/RMLFNOTC0005-CSV/output.ttl | 0 .../RMLFNOTC0006-CSV/mapping.ttl | 8 ++--- .../fno-testcases/RMLFNOTC0006-CSV/output.nq | 2 +- .../RMLFNOTC0011-CSV/mapping.ttl | 4 +-- .../fno-testcases/RMLFNOTC0011-CSV/output.ttl | 0 .../RMLFNOTC0001-CSV/mapping.ttl | 3 +- .../fno-testcases/RMLFNOTC0001-CSV/output.ttl | 2 +- .../RMLFNOTC0001-CSV/output.ttl.bak | 1 - .../RMLFNOTC0002-CSV/mapping.ttl | 2 +- .../fno-testcases/RMLFNOTC0002-CSV/output.ttl | 2 +- .../RMLFNOTC0002-CSV/output.ttl.bak | 1 - .../RMLFNOTC0003-CSV/mapping.ttl | 2 +- .../fno-testcases/RMLFNOTC0003-CSV/output.ttl | 2 +- .../RMLFNOTC0003-CSV/output.ttl.bak | 1 - .../RMLFNOTC0004-CSV/output.ttl.bak | 1 - .../RMLFNOTC0005-CSV/output.ttl.bak | 1 - .../fno-testcases/RMLFNOTC0011-CSV/output.ttl | 1 - .../RMLFNOTC0011-CSV/output.ttl.bak | 1 - .../RMLFNOTC0013-CSV/mapping.ttl | 2 +- .../fno-testcases/RMLFNOTC0013-CSV/output.ttl | 2 +- .../RMLFNOTC0013-CSV/output.ttl.bak | 1 - .../RMLFNOTC0018-CSV/mapping.ttl | 2 +- .../fno-testcases/RMLFNOTC0018-CSV/output.ttl | 2 +- .../RMLFNOTC0018-CSV/output.ttl.bak | 1 - .../RMLFNOTC0021-JSON/books.json | 8 ----- .../RMLFNOTC0021-JSON/mapping.ttl | 33 ------------------- .../RMLFNOTC0021-JSON/output.ttl | 7 ---- .../rml/framework/OutputGenerationTest.scala | 5 ++- 31 files changed, 31 insertions(+), 85 deletions(-) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl (76%) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0004-CSV/output.ttl (100%) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl (74%) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0005-CSV/output.ttl (100%) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl (80%) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0006-CSV/output.nq (75%) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl (89%) create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl.bak delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl.bak delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl.bak delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl.bak delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl.bak delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0021-JSON/books.json delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl similarity index 76% rename from src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl index 7ee60664..b8a44fc5 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl @@ -7,9 +7,8 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . -#@prefix idlab-fn: . -@prefix grel: . +@prefix fno: . +@prefix idlab-fn: . @base . @@ -30,9 +29,9 @@ fnml:functionValue [ rr:predicateObjectMap [ rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:objectMap [ rr:constant idlab-fn:toUpperCaseURL ] ] ; rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; + rr:predicate idlab-fn:str ; rr:objectMap [ rml:reference "Name" ] ] ] ; rr:termType rr:IRI diff --git a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl similarity index 74% rename from src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl index f7fac9b7..511d3344 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl @@ -7,8 +7,8 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . -@prefix grel: . +@prefix fno: . +@prefix idlab-fn: . @base . @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student_url.csv"; + rml:source "fno-testcases/student.csv"; rml:referenceFormulation ql:CSV ]; @@ -24,9 +24,9 @@ fnml:functionValue [ rr:predicateObjectMap [ rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:objectMap [ rr:constant idlab-fn:toUpperCaseURL ] ] ; rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; + rr:predicate idlab-fn:str ; rr:objectMap [ rml:reference "url" ] ] ] ; rr:termType rr:IRI diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl similarity index 80% rename from src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl index ba6f2fe3..dc5d9a35 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl @@ -7,8 +7,8 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . -@prefix grel: . +@prefix fno: . +@prefix idlab-fn: . @base . @@ -31,9 +31,9 @@ fnml:functionValue [ rr:predicateObjectMap [ rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:objectMap [ rr:constant idlab-fn:toUpperCaseURL ] ] ; rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; + rr:predicate idlab-fn:str ; rr:objectMap [ rml:reference "Name" ] ] ] ; rr:termType rr:IRI diff --git a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq b/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq similarity index 75% rename from src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq rename to src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq index 2456fe11..2258872a 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq @@ -1 +1 @@ - "Venus" . + "Venus" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl similarity index 89% rename from src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl index 68ac38aa..d6a18f37 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl @@ -7,8 +7,8 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . -@prefix grel: . +@prefix fno: . +@prefix grel: . @base . diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl index e7a1c7bf..beba67cc 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl @@ -7,8 +7,9 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . +@prefix idlab-fn: . @base . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl index 57872f74..b0369690 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl @@ -1 +1 @@ - "VENUS". + "VENUS" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl.bak deleted file mode 100644 index b0369690..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - "VENUS" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl index e2bd587c..e530250b 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl @@ -7,7 +7,7 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . @base . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl index 6b504619..fb8edf94 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl @@ -1 +1 @@ - "NAME". + "NAME" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl.bak deleted file mode 100644 index fb8edf94..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - "NAME" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl index 06823449..a973198a 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl @@ -7,7 +7,7 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . @base . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl index 7f158a88..af03220c 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl @@ -1 +1 @@ - "A&B". + "A&B" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl.bak deleted file mode 100644 index af03220c..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - "A&B" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak deleted file mode 100644 index 4aa4759e..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak deleted file mode 100644 index 80493637..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - "Venus" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl deleted file mode 100644 index a5026672..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - "VENUS"^^. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak deleted file mode 100644 index a5026672..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - "VENUS"^^. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl index e0d25a62..391dfe0d 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl @@ -7,7 +7,7 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . @base . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl index 9578e600..6629e021 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl @@ -1 +1 @@ - "". + "" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl.bak deleted file mode 100644 index 6629e021..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - "" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl index b1360640..daaa7860 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl @@ -7,7 +7,7 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . @base . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl index 556a47d4..2296c1ec 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl @@ -1 +1 @@ - "BEN & PIETER". + "BEN & PIETER" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl.bak deleted file mode 100644 index 2296c1ec..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - "BEN & PIETER" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/books.json b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/books.json deleted file mode 100644 index 9856321f..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/books.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "books": [ - {"title": "The adventure of young turtle", "authors": ["John"]}, - {"title": "The big rabbit's trip", "authors": ["Edward", "Steve"]}, - {"title": "A new horizon at the end of the night", "authors": []}, - {"title": "The past comes back in the future"} - ] -} diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl deleted file mode 100644 index 0932eb85..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl +++ /dev/null @@ -1,33 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . -@prefix idlab-fn: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/RMLFNOTC0021-JSON/books.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.books[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/book/{title}"; - rr:class ex:Book - ]; - - rr:predicateObjectMap [ - rr:predicate ex:writtenBy; - rr:objectMap [ - rml:reference "authors[*]" - ] - ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl deleted file mode 100644 index 445fac6f..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl +++ /dev/null @@ -1,7 +0,0 @@ - . - "John" . - . - "Edward" . - "Steve" . - . - . diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index bfa05390..77d5a0d2 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -28,6 +28,7 @@ import java.io.File import io.rml.framework.api.RMLEnvironment import io.rml.framework.core.extractors.{MappingExtractor, MappingReader} +import io.rml.framework.core.function.FunctionLoader import io.rml.framework.core.model.FunctionMapping import io.rml.framework.engine.PostProcessor import io.rml.framework.util.TestUtil @@ -63,7 +64,9 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { "Valid mapping output generation" should "match the output from output.ttl" in { // load functions - MappingReader(MappingExtractor(FunctionMapping)).read(functionFile) + val grelJavaMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) + FunctionLoader().parseFunctions(grelJavaMappingFile) // singleton FunctionLoader + passing.foreach(test => { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.com/base/")) From 564a6de7a4c3174c69ec2e92a6c9be0ce85c5ffe Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 12 Jun 2020 20:13:30 +0200 Subject: [PATCH 038/169] wip: feature function #25 - cleaned FunctionLoaderTests Deleted deprecated test code --- .../model/function/FunctionLoaderTest.scala | 47 ++++--------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala index f22f6d4d..e32e57b3 100644 --- a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala +++ b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala @@ -5,54 +5,23 @@ import java.io.File import io.rml.framework.StaticTestSpec import io.rml.framework.api.RMLEnvironment import io.rml.framework.core.function.model.{DynamicMethodFunction, Function} +import io.rml.framework.core.function.std.StdFunctionLoader import io.rml.framework.core.function.{FunctionLoader, FunctionUtils} import io.rml.framework.core.model.Uri import io.rml.framework.core.vocabulary.{Namespaces, RMLVoc} class FunctionLoaderTest extends StaticTestSpec { - val functionFile = new File(getClass.getClassLoader.getResource("functions.ttl").getFile) + val functionMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) - "Loading default grel functions classes" should "succeed without error" in { - - val filePath = RMLEnvironment.getClass.getClassLoader.getResource("GrelFunctions.jar").getFile - val cls = FunctionUtils.loadClassFromJar(new File(filePath), "GrelFunctions") - println(cls) - assert(cls.getDeclaredMethods.length > 0, "Declared methods must be more than 0 for now") - } "FunctionLoader" should "initialize the transformation lazily and correctly" in { - val loader = FunctionLoader().parseFunctions(functionFile) - val test = Uri("http://users.ugent.be/~bjdmeest/function/grel.ttl#toUpperCase") - val transformation = loader.loadFunction(test) + val loader = FunctionLoader().parseFunctions(functionMappingFile) + assert(loader.isInstanceOf[StdFunctionLoader]) - assume(transformation.isInstanceOf[Option[DynamicMethodFunction]]) +// val test = Uri("http://users.ugent.be/~bjdmeest/function/grel.ttl#toUpperCase") +// val transformation = loader.loadFunction(test) +// +// assume(transformation.isInstanceOf[Option[DynamicMethodFunction]]) } - - "Dynamic Function" should "be loaded and executable" in { - val loader = FunctionLoader().parseFunctions(functionFile) - - val testValue = "qmlsdkfje sdfesdfFJ" - val functionUri = Uri(Namespaces("grel", "toUpperCase")) - - // map: uri -> trans. metadata - val transformationMap = loader.getFunctionMap - - // transformation meta data for given function uri - val transformationMetaData = transformationMap.getOrElse( - functionUri, - throw new Exception("Unable to find transformation meta data in transformation map")) - - - val transformation = Function(functionUri.identifier,transformationMetaData) - // initializedTransformation is a DynamicMethodFunction - val initializedTransformation: Function = transformation.initialize() - - // bind value parameter to its actual value - val paramMap = Map(Uri(Namespaces("grel", "valueParameter")) -> testValue) - // execute transformation and obtain its results - val result = initializedTransformation.execute(paramMap).get.head - - assume(result.toString == testValue.toUpperCase()) - } } From ab0a43ca7b4a110f8749f99254a1014d023b6082 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 16 Jun 2020 14:50:03 +0200 Subject: [PATCH 039/169] wip: feature function #25 - update FunctionLoader FunctionLoader - function loader can be initialized given a list of paths to function description files. When that list is empty, the function loader falls back to using the default function descriptions (e.g. `functions_grel.ttl` - updated method docs --- .../core/function/FunctionLoader.scala | 81 ++++++++++++++----- 1 file changed, 60 insertions(+), 21 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index 3c607c25..fd5a55df 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -9,10 +9,11 @@ import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode} import io.rml.framework.core.util.Turtle -import io.rml.framework.shared.RMLException +import io.rml.framework.shared.{FnOException, RMLException} import scala.collection.immutable.{Map => ImmutableMap} -import scala.collection.mutable.{Map => MutableMap} +import scala.collection.mutable +import scala.collection.mutable.{MutableList, Map => MutableMap} abstract class FunctionLoader extends Logging { /** @@ -26,18 +27,11 @@ abstract class FunctionLoader extends Logging { */ protected val functionMap: MutableMap[Uri, FunctionMetaData] = MutableMap() - def getClassLibraryMap: ImmutableMap[String, String] = classLibraryMap.toMap def getFunctionMap = functionMap.toMap - def parseFunctions(file: File): FunctionLoader = { - val graph = RDFGraph.fromFile(file, RMLEnvironment.getGeneratorBaseIRI(),Turtle) - parseFunctions(graph) - this - } - /** * Given the [[Uri]] representation of the transformation, the [[FunctionLoader]] * will search for the transformation in the [[functionMap]] and dynamically load @@ -75,14 +69,31 @@ abstract class FunctionLoader extends Logging { } /** - * Parse transformations from the [[RDFGraph]] of the whole function mapping file. + * The given `functionMappingFile` should be a Turtle-file containing the function mappings. These mappings will be parsed and + * the FunctionLoader's functionMap is updated accordingly. + * + * @param functionMappingFile + * @return + */ + def parseFunctions(functionMappingFile: File): FunctionLoader = { + val graph = RDFGraph.fromFile(functionMappingFile, RMLEnvironment.getGeneratorBaseIRI(),Turtle) + parseFunctions(graph) + this + } + + + /** + * The given `graph` should contain the function mappings. These mappings will be parsed and + * the FunctionLoader's functionMap is updated accordingly. * - * @param graph [[RDFGraph]] representing the whole function mapping file + * @param graph [[RDFGraph]] representing a function mapping * @return [[FunctionLoader]] */ def parseFunctions(graph: RDFGraph): FunctionLoader + + /** * Parse [[Parameter]] from the given [[RDFNode]] which represents the parameter * @@ -100,19 +111,47 @@ object FunctionLoader { private var singletonFunctionLoader : Option[FunctionLoader] = None - def apply(): FunctionLoader = { + private val defaultFunctionDescriptionFilePaths = List( + "functions_grel.ttl" + ) + + private def readFunctionDescriptionsFromFile(filePath : String): RDFGraph = { + val functionDescriptionsFile = new File(getClass.getClassLoader.getResource(filePath).getFile) + if (!functionDescriptionsFile.exists()) + throw new RMLException(s"Couldn't find ${functionDescriptionsFile.getName}") + + RDFGraph.fromFile(functionDescriptionsFile, RMLEnvironment.getGeneratorBaseIRI(), Turtle) + } + + def apply(functionDescriptionFilePaths : List[String] = List()): FunctionLoader = { if(singletonFunctionLoader.isEmpty) { - // construct functionDescriptionTriplesGraph - val functionsGrelFile = new File(getClass.getClassLoader.getResource("functions_grel.ttl").getFile) - if (!functionsGrelFile.exists()) - throw new RMLException(s"Couldn't find ${functionsGrelFile.getName}") - - // construct function description graph - // this graph will be used by the function loader to map the function descriptions to their implementations - val functionDescriptionTriplesGraph = RDFGraph.fromFile(functionsGrelFile, RMLEnvironment.getGeneratorBaseIRI(), Turtle) + + // The functionDescriptionsGraph is populated by iterating over the filepaths of the function description files. + // When no filepaths are provided (i.e. functionDescriptionFilePaths is empty), the function loader will use the + // default function description files (i.e. defaultFunctionDescriptionFilePaths) + val fdit = if(functionDescriptionFilePaths.isEmpty) defaultFunctionDescriptionFilePaths.iterator else functionDescriptionFilePaths.iterator + + + // construct the initial functionDescriptionTriplesGraph using the first functiondescription filepath + val functionDescriptionsGraph : Option[RDFGraph] = + if(fdit.hasNext) + Some(readFunctionDescriptionsFromFile(fdit.next())) + else + None + + // If more function description filepaths are specified, they will be read in. + // The resulting triples will be added to the functionDescriptionsGraph + while (fdit.hasNext) { + val fdescGraph = readFunctionDescriptionsFromFile(fdit.next()) + functionDescriptionsGraph.get.addTriples(fdescGraph.listTriples) + } + // construct functionLoader - singletonFunctionLoader = Some(StdFunctionLoader(functionDescriptionTriplesGraph)) + if(functionDescriptionsGraph.isDefined) + singletonFunctionLoader = Some(StdFunctionLoader(functionDescriptionsGraph.get)) + else + throw new FnOException("No function description functionMappingGraph was created...") } singletonFunctionLoader.get } From 3698e54c1b0e56e548978dbb688a95b1f52b2892 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 16 Jun 2020 15:27:00 +0200 Subject: [PATCH 040/169] wip: feature function #25 - renaming / documenting - renamed `parseFunctions` to `parseFunctionMapping` - added documentation to the methods --- .../std/StdFunctionMappingExtractor.scala | 2 +- .../core/function/FunctionLoader.scala | 41 +++++++++---------- .../core/function/std/StdFunctionLoader.scala | 3 +- .../rml/framework/OutputGenerationTest.scala | 4 +- .../model/function/FunctionLoaderTest.scala | 2 +- 5 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala index 4c254c00..9b096fea 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala @@ -16,7 +16,7 @@ class StdFunctionMappingExtractor extends MappingExtractor[FunctionMapping] { override def extract(node: RDFGraph): FunctionMapping = { val loader = FunctionLoader() - loader.parseFunctions(node) + loader.parseFunctionMapping(node) FunctionMapping("defaulty", loader) } diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index fd5a55df..19349352 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -21,7 +21,6 @@ abstract class FunctionLoader extends Logging { */ protected val classLibraryMap: MutableMap[String, String] = MutableMap() - /** * Map names of [[Function]] to concrete [[Function]] object */ @@ -43,22 +42,15 @@ abstract class FunctionLoader extends Logging { def loadFunction(uri: Uri): Option[Function] = { logDebug(s"loadFunction: ${uri.uri}") - val optTransformation = functionMap.get(uri) - - if (optTransformation.isDefined) { - val trans = optTransformation.get - - logDebug(s"Dynamically loading function: $uri, ${trans.toString}" ) + val optFunction = functionMap.get(uri) - trans match { - case transformationMetaData: FunctionMetaData => { - // val loadedTrans = transient.initialize() - // functionMap.put(uri, loadedTrans) - // Some(loadedTrans) + if (optFunction.isDefined) { + val functionMetaData = optFunction.get - Some(Function(transformationMetaData.identifier, transformationMetaData)) - } + logDebug(s"Dynamically loading function: $uri, ${functionMetaData.toString}" ) + functionMetaData match { + case functionMetaData: FunctionMetaData => Some(Function(functionMetaData.identifier, functionMetaData)) case loadedFunction: DynamicMethodFunction => Some(loadedFunction) case _ => None } @@ -75,13 +67,12 @@ abstract class FunctionLoader extends Logging { * @param functionMappingFile * @return */ - def parseFunctions(functionMappingFile: File): FunctionLoader = { + def parseFunctionMapping(functionMappingFile: File): FunctionLoader = { val graph = RDFGraph.fromFile(functionMappingFile, RMLEnvironment.getGeneratorBaseIRI(),Turtle) - parseFunctions(graph) + parseFunctionMapping(graph) this } - /** * The given `graph` should contain the function mappings. These mappings will be parsed and * the FunctionLoader's functionMap is updated accordingly. @@ -89,10 +80,7 @@ abstract class FunctionLoader extends Logging { * @param graph [[RDFGraph]] representing a function mapping * @return [[FunctionLoader]] */ - def parseFunctions(graph: RDFGraph): FunctionLoader - - - + def parseFunctionMapping(graph: RDFGraph): FunctionLoader /** * Parse [[Parameter]] from the given [[RDFNode]] which represents the parameter @@ -115,6 +103,11 @@ object FunctionLoader { "functions_grel.ttl" ) + /** + * Private helper method for reading in the function descriptions as an RDFGraph. + * @param filePath + * @return RDFGraph containing the function descriptions. + */ private def readFunctionDescriptionsFromFile(filePath : String): RDFGraph = { val functionDescriptionsFile = new File(getClass.getClassLoader.getResource(filePath).getFile) if (!functionDescriptionsFile.exists()) @@ -123,6 +116,12 @@ object FunctionLoader { RDFGraph.fromFile(functionDescriptionsFile, RMLEnvironment.getGeneratorBaseIRI(), Turtle) } + /** + * Construction of the (singleton) FunctionLoader instance. + * When the funcitonDescriptionFilePaths-list is empty, the default function descriptions are used. + * @param functionDescriptionFilePaths filepaths to the function descriptions. Default value is an empty list. + * @return FunctionLoader + */ def apply(functionDescriptionFilePaths : List[String] = List()): FunctionLoader = { if(singletonFunctionLoader.isEmpty) { diff --git a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala index a1b467ae..08098631 100644 --- a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala @@ -16,8 +16,7 @@ import io.rml.framework.shared.{FnOException, RMLException} case class StdFunctionLoader(functionDescriptionTriplesGraph : RDFGraph) extends FunctionLoader { - - override def parseFunctions(graph: RDFGraph): FunctionLoader = { + override def parseFunctionMapping(graph: RDFGraph): FunctionLoader = { logDebug("parsing functions the new way (i.e. using StdFunctionLoader)") // a fnoi:Mapping diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index 77d5a0d2..cb7a72bf 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -47,7 +47,7 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { // This is useful, for example, if you only want to check the tests that should pass. val failing : Array[String] = Array( -// "negative_test_cases" + "negative_test_cases" ) val passing : Array[Tuple2[String,String]] =Array( // ("bugs","noopt"), @@ -65,7 +65,7 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { "Valid mapping output generation" should "match the output from output.ttl" in { // load functions val grelJavaMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) - FunctionLoader().parseFunctions(grelJavaMappingFile) // singleton FunctionLoader + FunctionLoader().parseFunctionMapping(grelJavaMappingFile) // singleton FunctionLoader passing.foreach(test => { diff --git a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala index e32e57b3..400a1162 100644 --- a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala +++ b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala @@ -15,7 +15,7 @@ class FunctionLoaderTest extends StaticTestSpec { "FunctionLoader" should "initialize the transformation lazily and correctly" in { - val loader = FunctionLoader().parseFunctions(functionMappingFile) + val loader = FunctionLoader().parseFunctionMapping(functionMappingFile) assert(loader.isInstanceOf[StdFunctionLoader]) // val test = Uri("http://users.ugent.be/~bjdmeest/function/grel.ttl#toUpperCase") From d45374ed852e65f02cef5ec39dcd4331fa078f49 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 16 Jun 2020 16:17:10 +0200 Subject: [PATCH 041/169] wip: feature documentation #86 documentation: - added documentation (tutorial) about using FnO within the RML Streamer resources: - function descriptions - function mapping - JAR file containing the `toUpperCaseURL` method SandboxTests - updated `executeTest` by instructing the function loader to use the appropriate function description files - added 3 sandbox tests - RMLFNOTC0004-CSV - RMLFNOTC0005-CSV - RMLFNOTC0006-CSV Updated the testcase mappingfiles to use the HTTPS-url of the FnO namespace --- documentation/README_Functions.md | 98 ++++++++++++++++++ src/main/resources/IDLabFunctions.jar | Bin 0 -> 2349 bytes src/main/resources/functions_idlab.ttl | 62 +++++++++++ src/main/resources/idlab_java_mapping.ttl | 67 ++++++++++++ .../RMLFNOTC0004-CSV/mapping.ttl | 2 +- .../RMLFNOTC0005-CSV/mapping.ttl | 4 +- .../RMLFNOTC0006-CSV/mapping.ttl | 2 +- .../scala/io/rml/framework/SandboxTests.scala | 92 +++++----------- 8 files changed, 257 insertions(+), 70 deletions(-) create mode 100644 documentation/README_Functions.md create mode 100644 src/main/resources/IDLabFunctions.jar create mode 100644 src/main/resources/functions_idlab.ttl create mode 100644 src/main/resources/idlab_java_mapping.ttl diff --git a/documentation/README_Functions.md b/documentation/README_Functions.md new file mode 100644 index 00000000..169e4e3b --- /dev/null +++ b/documentation/README_Functions.md @@ -0,0 +1,98 @@ +# Tutorial +> Under construction + +## Using a function from a local JAR + +The following testcases use the function `toUpperCaseURL`, which isn’t implemented yet: + +- RMLFNOTC0004-CSV +- RMLFNOTC0005-CSV +- RMLFNOTC0006-CSV + +The following steps show how to integrate the `toUpperCaseURL` function in the RML Streamer. + +### Step 1: creating the JAR +This step is based on best-practice example `grel-functions-java`. +- Create package `io.fno.idlab` and within that package, create the class `IDLabFunctions` +- For these testcases, we need a function that returns the given URL in uppercase. + +```Java +package io.fno.idlab; + +public class IDLabFunctions { + public static String toUpperCaseURL(String s) { + if(!s.startsWith("http")) + return "http://" + s.toUpperCase(); + return s.toUpperCase(); + } +} +``` + +Use Maven to build a JAR-file, and move this JAR-file to the RMLStreamer’s `main/resources`. + +### Step 2: defining the FnO descriptions +An FnO description represents the abstract definition of a function. + +The testcases mentioned above require a function that returns a valid URL in uppercase, and is described as follows + + +```Turtle +# source: `functions_idlab.ttl`. +grel:prob_ucase + a fno:Problem ; + fno:name "The ucase problem"^^xsd:string ; + dcterms:description "Converting a string to upper case characters."^^xsd:string . + +grel:toUpperCaseURL + a fno:Function ; + fno:name "toUppercaseURL" ; + rdfs:label "toUppercaseURL" ; + dcterms:description "Returns an uppercase, valid url." ; + fno:solves grel:prob_ucase ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:stringOut ) . +``` + +### Step 3: map FnO descriptions to the corresponding implementations +In the previous step, the abstract functions were created. +The current step will define the link between abstract function descriptions and the corresponding implementation. This is illustrated by the following snippet. +```Turtle +grelm:IDLabFunctions + a fnoi:JavaClass ; + doap:download-page "IDLabFunctions.jar" ; + fnoi:class-name "io.fno.idlab.IDLabFunctions" . + +#UPPERCASERURL +grelm:uppercaseURLMapping + a fno:Mapping ; + fno:function grel:toUpperCaseURL ; + fno:implementation grelm:IDLabFunctions ; + fno:parameterMapping [ ] ; + fno:returnMapping [ ] ; + fno:methodMapping [ + a fnom:StringMethodMapping ; + fnom:method-name "toUpperCaseURL" + ] ; +. +``` +This mapping instructs the RML Streamer to look for a method called `toUpperCaseURL` within the `io.fno.idlab.IDLabFunctions`-class of the `IDLabFunctions.jar`. Make sure that the JAR-file is located in `main/resources`. + +## How the `FunctionLoader` works + +The function descriptions and mappings mentioned in the previous steps will be used by the `FunctionLoader`. + +First, a `FunctionLoader` has to be aware of the available functions. +Therefore, it can be instantiated providing file paths to the function description files. When no such file paths where provided, the default function descriptions are used (e.g. `functions_grel.ttl`). + +Secondly, function URIs are mapped to the corresponding implementations by parsing the function mappings (e.g. `resources/grel_java_mapping.ttl` and `resources/idlab_java_mapping.ttl`). During this step, every function URI is mapped to a `FunctionMetaData`-object which contains the necessary meta data such as: the *download-page* of the library, the *class-name* of the function, the *method-name*, *input parameters* and *output parameters*. + + +## How the `FunctionLoader` is used + +Initially, the `FunctionLoader` is used to read and parse function descriptions and mappings. Afterwards, when running FNOT-testcases, the `FunctionLoader`-instance is used to load and bind every function as specified in the `mapping.ttl`. + + +## Remarks +- When running the `SandboxTests` , make sure to set the *Working Directory* of the *Run-configuration* to the absolute path of `rml-streamer/src/test/resources/sandbox`. + + diff --git a/src/main/resources/IDLabFunctions.jar b/src/main/resources/IDLabFunctions.jar new file mode 100644 index 0000000000000000000000000000000000000000..8431970c5c9692e01625fb8a4fe08d4885a6b875 GIT binary patch literal 2349 zcmWIWW@h1H0D(<$7XrWxD8UJ&eO*Hwbv^yu^aG&EI2bkpm3_UHQBeq#ZUr)RmQ7$Ewn* zjtTf`?uygAsZg!+h38Rk4^QRJik%EFCo(X!MWFhG8R*2!e7GMl6|h4Tq~#$i0(lfD z4hOtI7SI%sqRf<>#3Z8RUpTs1$(!Au7%>2A!z2uz4 z;^N+*i+MthBDUKD#9oL^5ZfBEW$UFwQFni69c#a2VtDh4i{eZ$&39FIH_KmM ze?WXz#v}G0fyb;JrffS>BL8k@@w0b3%g>!zfB$|xQ$_P%ov;lP-7LF(Z43iWDy_Wk zZ)$h>$+UCZcx}u#ID71!+!*qnvoq@NlnFU)vHcUuQy$3j>&NO_39dWubCJ{fkiF={ zE3YMIhSW+5YxVKG{j9Jh^}6`FzYi}6zPo7fLPL_Ruz5moVzt4CMaw$&ep7GX5M8Wy zBs}rA(uYiQGtv8>%**(>=n)CJ6R=;JT7H2o|{&o4Xo#m2V;hB%8 z(o~M6zLxruyJ_z88M7vEidf9L%w*#*(XiQc&G|aJ*&U3bt9O{VJ>q&Q?@_n!SdpP= zTVn6TGzn$nOD|unujp&tn$UJT=irR&AXiR)$)D%cuJ->&N?GW6gdZ5u@H~>6SeBXx zPZgLMN*Ysfeo?w!YDHphK~5?jjRyENf>Wbz8Z33`W+j#-!cF5~kOt-kpFR__??6*F z0~4q@8KxEF=jv7D=ClT$_dl#4vhVwPg*%OYwlmr`RT$37$@5(P@z;_y$(aiouYEf& z{&L%y=84kxf7k8V)33jLoojPZTy*dw*0Y8|ZnvUlFFW#nclxJ}=}M3HZgy8??#g-W zUBj_ZU*dH_K${c)rv)oYd2i=kd(-&rqN?-s=_*H`d<`}0QK_l#BH$wHLp_3dGkoKOY{8?Ka==$>!#U}oy+v=uC+=Wd!iOc~% z4XI*4n1ERjgGy=$09kwr$OM<$2$!N4?Vyqy0zevG1DVhw8rc?XB{@Qq05DIWmFqD3 zu$Sym3xQs=M%Rk1oJV#Ew( . +@prefix dcterms: . +@prefix fno: . +@prefix foaf: . +@prefix grel: . +@prefix rdf: . +@prefix rdfs: . +@prefix void: . +@prefix xsd: . + +grel:void + a void:DatasetDescription ; + dcterms:title "A VoID Description of the GREL Fno Descriptions Dataset" ; + dcterms:creator ; + foaf:primaryTopic grel:dataset ; +. + + + rdf:type foaf:Person ; + foaf:mbox "mailto:Ben.DeMeester@UGent.be" ; + foaf:name "Ben De Meester"@en . + +grel:dataset + a void:Dataset ; + foaf:homepage ; + foaf:homepage ; + dcterms:title "FnO descriptions for IDLab functions"@en ; + dcterms:description "The FnO descriptions of the IDLab functions" ; + dcterms:contributor ; + dcterms:modified "2020-06-16"^^xsd:date ; + cc:license ; + dcterms:issued "2016-12-15"^^xsd:date ; + dcterms:rights "Copyright © Ghent University – imec – IDLab"@en ; + dcterms:subject ; + dcterms:subject ; + void:feature ; + void:exampleResource grel:boolean_and ; + void:vocabulary . + +# Contents: +# - Parameters (per java) param_{var} with predicate p_{type}_{var} +# - Outputs (per java) output_{type} with predicate o_{type} +# - Problems (per java) prob_{var} +# - Functions (per java) + + +grel:prob_ucase + a fno:Problem ; + fno:name "The ucase problem"^^xsd:string ; + dcterms:description "Converting a string to upper case characters."^^xsd:string . + +grel:toUpperCaseURL + a fno:Function ; + fno:name "toUppercaseURL" ; + rdfs:label "toUppercaseURL" ; + dcterms:description "Returns an uppercase, valid url." ; + fno:solves grel:prob_ucase ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:stringOut ) . + + + diff --git a/src/main/resources/idlab_java_mapping.ttl b/src/main/resources/idlab_java_mapping.ttl new file mode 100644 index 00000000..25b7bdef --- /dev/null +++ b/src/main/resources/idlab_java_mapping.ttl @@ -0,0 +1,67 @@ +@prefix cc: . +@prefix dcterms: . +@prefix doap: . +@prefix fno: . +@prefix fnoi: . +@prefix fnom: . +@prefix foaf: . +@prefix grel: . +@prefix grelm: . +@prefix rdf: . +@prefix rdfs: . +@prefix void: . +@prefix xsd: . + +grelm:void + a void:DatasetDescription ; + dcterms:title "A VoID Description of the IDLab Fno Java Mapping Descriptions Dataset" ; + dcterms:creator ; + foaf:primaryTopic grelm:dataset ; +. + + + rdf:type foaf:Person ; + foaf:mbox "mailto:Ben.DeMeester@UGent.be" ; + foaf:name "Ben De Meester"@en . + +grelm:dataset + a void:Dataset ; + foaf:homepage ; + foaf:homepage ; + dcterms:title "IDLab Fno Java Mapping Descriptions"@en ; + dcterms:description "The FnO Java mapping descriptions of the IDLab functions" ; + dcterms:contributor ; + dcterms:modified "2020-06-16"^^xsd:date ; + cc:license ; + dcterms:issued "2020-06-16"^^xsd:date ; + dcterms:rights "Copyright © Ghent University – imec – IDLab"@en ; + dcterms:subject ; + dcterms:subject ; + void:feature ; + void:exampleResource grelm:boolean_and ; + void:vocabulary , , + . + +# Contents: +# - Parameters (per java) param_{var} with predicate p_{type}_{var} +# - Outputs (per java) output_{type} with predicate o_{type} +# - Problems (per java) prob_{var} +# - Functions (per java) + +grelm:IDLabFunctions + a fnoi:JavaClass ; + doap:download-page "IDLabFunctions.jar" ; + fnoi:class-name "io.fno.idlab.IDLabFunctions" . + +#UPPERCASERURL + +grelm:uppercaseURLMapping + a fno:Mapping ; + fno:function grel:toUpperCaseURL ; + fno:implementation grelm:IDLabFunctions ; + fno:parameterMapping [ ] ; + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "toUpperCaseURL" ] ; +. + diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl index fe1c29b7..4901ced9 100644 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl @@ -7,7 +7,7 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . @base . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl index e5714b73..49423171 100644 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl @@ -7,7 +7,7 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . @base . @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/RMLFNOTC0005-CSV/student.csv"; + rml:source "sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl index ba6f2fe3..bfff3dcc 100644 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl @@ -7,7 +7,7 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . @base . diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index f43082c5..4618382b 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -55,8 +55,26 @@ class SandboxTests extends FunSuite with Matchers { val testDir = Util.getFile(new File(mappingFile).getParent) val mappingFileAbs = new File(testDir, new File(mappingFile).getName) - // load functions - MappingReader(MappingExtractor(FunctionMapping)).read(functionFile) + // function descriptions + val functionDescriptionFilePaths = List( + "functions_grel.ttl", + "functions_idlab.ttl" + ) + + // function mappings + val grelJavaMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) + val idlabJavaMappingFile = new File(getClass.getClassLoader.getResource("idlab_java_mapping.ttl").getFile) + + // singleton FunctionLoader created and initialized with given function descriptions + val functionLoader = FunctionLoader(functionDescriptionFilePaths) + + // Parse the function mapping files. + // The functionloader will construct a mapping between function uris and the corresponding function meta data objects + functionLoader + .parseFunctionMapping(grelJavaMappingFile) + .parseFunctionMapping(idlabJavaMappingFile) + + // read the mapping val formattedMapping = Util.readMappingFile(mappingFileAbs.getAbsolutePath) @@ -80,83 +98,25 @@ class SandboxTests extends FunSuite with Matchers { } } - - /** - * RML TESTCASES - */ - - /** - * [STATE @ ] - - */ - test("sandbox/rml-testcases/RMLTC0011b-CSV") { - pending - executeTest("sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl") - - } - - /** - * [STATE @ ] - * - - */ - test("sandbox/rml-testcases/RMLTC0011b-CSV-small") { - pending - executeTest("sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl") - - } - - - /** * FNO TEST CASES */ - test("sandbox/fno-testcases/RMLFNOTC0001-CSV") { - pending - executeTest("sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl") + test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { + executeTest("sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl") } - test("sandbox/fno-testcases/RMLFNOTC0001-CSV-explicit") { - pending - executeTest("sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl") + test("sandbox/fno-testcases/RMLFNOTC0005-CSV") { + executeTest("sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl") } - - /** - * [STATE @ do 28 mei 2020 14:48:03 CEST] FAILING - * log. source: students.csv - * used function: grel:toUpperCaseURL - * value parameter: reference to "Name" - */ - test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { - pending - executeTest("sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl") + test("sandbox/fno-testcases/RMLFNOTC0006-CSV") { + executeTest("sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl") } - /** - * [STATE @ do 28 mei 2020 14:48:03 CEST] WORKING - * log. source: students.csv - * used function: grel:toUpperCase - * value parameter: template using {Name} - */ - test("sandbox/fno-testcases/RMLFNOTC0008-CSV") { - pending - executeTest("sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl") - } - /** - * [STATE @ ] - * log. source: students.csv - * used function: grel:toUpperCase - * value parameter: reference to "Name" - */ - test("sandbox/fno-testcases/RMLFNOTC0011-CSV") { - pending - //executeTest("sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl") - } From 4dc022ffa140b49513a306815dd466fccbe60490 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 17 Jun 2020 09:45:21 +0200 Subject: [PATCH 042/169] wip: feature function #25 - function descriptions and mappings update - Added parameter URI to exception message OutputGenerationTests - functionLoader is initialized using multiple function description and mapping files functions_idlab.ttl - added idlab-fn prefix - updated the description of toUpperCaseURL function by using the idlab-fn - added parameter descriptions idlab_java_mapping.ttl - added idlab-fn prefix and updated usages accordingly --- src/main/resources/functions_idlab.ttl | 120 +++++++++++++++++- src/main/resources/idlab_java_mapping.ttl | 12 +- .../core/function/std/StdFunctionLoader.scala | 5 +- .../rml/framework/OutputGenerationTest.scala | 18 ++- 4 files changed, 145 insertions(+), 10 deletions(-) diff --git a/src/main/resources/functions_idlab.ttl b/src/main/resources/functions_idlab.ttl index 271197dd..fae6b55a 100644 --- a/src/main/resources/functions_idlab.ttl +++ b/src/main/resources/functions_idlab.ttl @@ -7,7 +7,7 @@ @prefix rdfs: . @prefix void: . @prefix xsd: . - +@prefix idlab-fn: . grel:void a void:DatasetDescription ; dcterms:title "A VoID Description of the GREL Fno Descriptions Dataset" ; @@ -43,20 +43,132 @@ grel:dataset # - Problems (per java) prob_{var} # - Functions (per java) +################################ +#### PROBLEMS +################################ grel:prob_ucase a fno:Problem ; fno:name "The ucase problem"^^xsd:string ; dcterms:description "Converting a string to upper case characters."^^xsd:string . -grel:toUpperCaseURL +################################ +#### FUNCTIONS +################################ + +idlab-fn:toUpperCaseURL a fno:Function ; fno:name "toUppercaseURL" ; rdfs:label "toUppercaseURL" ; dcterms:description "Returns an uppercase, valid url." ; fno:solves grel:prob_ucase ; - fno:expects ( grel:valueParam ) ; - fno:returns ( grel:stringOut ) . + fno:expects ( idlab-fn:_str ) ; + fno:returns ( idlab-fn:_stringOut ) . + +################################ +#### PARAMETERS +################################ +idlab-fn:_path + a fno:Parameter ; + fno:name "input path" ; + rdfs:label "input path" ; + fno:type xsd:string ; + fno:predicate idlab-fn:path . + +idlab-fn:_str + a fno:Parameter ; + fno:name "input string" ; + rdfs:label "input string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:str . + +idlab-fn:_strBoolean + a fno:Parameter ; + fno:name "boolean encoded as string" ; + rdfs:label "boolean encoded as string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:strBoolean . + +idlab-fn:_endpoint + a fno:Parameter ; + fno:name "endpoint url string" ; + rdfs:label "endpoint url string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:endpoint . + +idlab-fn:_otherStr + a fno:Parameter ; + fno:name "other input string" ; + rdfs:label "other input string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:otherStr . + +idlab-fn:_expectedStr + a fno:Parameter ; + fno:name "expected input string" ; + rdfs:label "expected input string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:expectedStr . + +idlab-fn:_result + a fno:Parameter ; + fno:name "result string" ; + rdfs:label "result string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:result . + +idlab-fn:_list + a fno:Parameter ; + fno:name "list" ; + rdfs:label "list" ; + fno:type rdf:List ; + fno:predicate idlab-fn:list . + +idlab-fn:_listOut + a fno:Parameter ; + fno:name "output list" ; + rdfs:label "output list" ; + fno:type rdf:List ; + fno:predicate idlab-fn:listOut . + +idlab-fn:_delimiter + a fno:Parameter ; + fno:name "delimiter" ; + rdfs:label "delimiter" ; + fno:type xsd:string ; + fno:predicate idlab-fn:delimiter . + +idlab-fn:_test + a fno:Parameter ; + fno:name "test" ; + rdfs:label "test" ; + fno:type xsd:double ; + fno:predicate idlab-fn:p_test . + +idlab-fn:_from + a fno:Parameter ; + fno:name "from" ; + rdfs:label "from" ; + fno:type xsd:double ; + fno:predicate idlab-fn:p_from . +idlab-fn:_to + a fno:Parameter ; + fno:name "to" ; + rdfs:label "to" ; + fno:type xsd:double ; + fno:predicate idlab-fn:p_to . +idlab-fn:_stringOut + a fno:Output ; + fno:name "output string" ; + rdfs:label "output string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:stringOut . +idlab-fn:_boolOut + a fno:Output ; + fno:name "output boolean" ; + rdfs:label "output boolean" ; + fno:type xsd:boolean ; + fno:predicate idlab-fn:o_boolOut . diff --git a/src/main/resources/idlab_java_mapping.ttl b/src/main/resources/idlab_java_mapping.ttl index 25b7bdef..d05ddecf 100644 --- a/src/main/resources/idlab_java_mapping.ttl +++ b/src/main/resources/idlab_java_mapping.ttl @@ -11,7 +11,7 @@ @prefix rdfs: . @prefix void: . @prefix xsd: . - +@prefix idlab-fn: . grelm:void a void:DatasetDescription ; dcterms:title "A VoID Description of the IDLab Fno Java Mapping Descriptions Dataset" ; @@ -48,16 +48,22 @@ grelm:dataset # - Problems (per java) prob_{var} # - Functions (per java) +################################ +#### IMPLEMENTATIONS +################################ grelm:IDLabFunctions a fnoi:JavaClass ; doap:download-page "IDLabFunctions.jar" ; fnoi:class-name "io.fno.idlab.IDLabFunctions" . -#UPPERCASERURL +################################ +#### MAPPINGS +################################ +#UPPERCASERURL grelm:uppercaseURLMapping a fno:Mapping ; - fno:function grel:toUpperCaseURL ; + fno:function idlab-fn:toUpperCaseURL; fno:implementation grelm:IDLabFunctions ; fno:parameterMapping [ ] ; fno:returnMapping [ ] ; diff --git a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala index 08098631..d28253f9 100644 --- a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala @@ -98,11 +98,12 @@ case class StdFunctionLoader(functionDescriptionTriplesGraph : RDFGraph) extends val paramType = inputResource.listProperties(RMLVoc.Property.FNO_TYPE).headOption val paramUri = inputResource.listProperties(RMLVoc.Property.FNO_PREDICATE).headOption + if(paramType.isEmpty) - throw new FnOException("Parameter Type not defined") + throw new FnOException(s"Parameter Type not defined for parameter resource: ${inputResource.uri}") if(paramUri.isEmpty) - throw new FnOException("Parameter Uri not defined") + throw new FnOException(s"Parameter Uri not defined for parameter resource: ${inputResource.uri}") val typeClass = FunctionUtils.getTypeClass(Uri(paramType.get.toString)) diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index cb7a72bf..4572b9cb 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -64,9 +64,25 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { "Valid mapping output generation" should "match the output from output.ttl" in { // load functions + + // function descriptions + val functionDescriptionFilePaths = List( + "functions_grel.ttl", + "functions_idlab.ttl" + ) + + // function mappings val grelJavaMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) - FunctionLoader().parseFunctionMapping(grelJavaMappingFile) // singleton FunctionLoader + val idlabJavaMappingFile = new File(getClass.getClassLoader.getResource("idlab_java_mapping.ttl").getFile) + + // singleton FunctionLoader created and initialized with given function descriptions + val functionLoader = FunctionLoader(functionDescriptionFilePaths) + // Parse the function mapping files. + // The functionloader will construct a mapping between function uris and the corresponding function meta data objects + functionLoader + .parseFunctionMapping(grelJavaMappingFile) + .parseFunctionMapping(idlabJavaMappingFile) passing.foreach(test => { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.com/base/")) From 5d39707ae088b92165e77d38d377fef0d8d4e193 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 17 Jun 2020 09:46:55 +0200 Subject: [PATCH 043/169] =?UTF-8?q?wip:=20feature=20function=20#25=20-=20m?= =?UTF-8?q?oving=20RMLFNOTC000{4,56}=C2=A0to=20working=20dir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{failing => }/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl | 0 .../{failing => }/fno-testcases/RMLFNOTC0004-CSV/output.ttl | 0 .../{failing => }/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl | 2 +- .../{failing => }/fno-testcases/RMLFNOTC0005-CSV/output.ttl | 0 .../{failing => }/fno-testcases/RMLFNOTC0005-CSV/student.csv | 0 .../{failing => }/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl | 0 .../{failing => }/fno-testcases/RMLFNOTC0006-CSV/output.nq | 0 7 files changed, 1 insertion(+), 1 deletion(-) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0004-CSV/output.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl (94%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0005-CSV/output.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0005-CSV/student.csv (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0006-CSV/output.nq (100%) diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl similarity index 94% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl index 511d3344..242b17c9 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "fno-testcases/RMLFNOTC0005-CSV/student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/student.csv b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/student.csv rename to src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq rename to src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq From ff66e939521908e7199d1ab39ffe949034429589 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 17 Jun 2020 10:11:22 +0200 Subject: [PATCH 044/169] wip: feature function #25 - removed sandboxtests --- .../scala/io/rml/framework/SandboxTests.scala | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 4618382b..0f41cdfb 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -97,22 +97,12 @@ class SandboxTests extends FunSuite with Matchers { } } } + // Example +// test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { +// pending +// executeTest("sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl") +// } - /** - * FNO TEST CASES - */ - - test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { - executeTest("sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl") - } - - test("sandbox/fno-testcases/RMLFNOTC0005-CSV") { - executeTest("sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl") - } - - test("sandbox/fno-testcases/RMLFNOTC0006-CSV") { - executeTest("sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl") - } From 623515731e72be6198753014c2088e260c3f699e Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Wed, 17 Jun 2020 10:49:08 +0200 Subject: [PATCH 045/169] Removed unused WebSocket library; updated log4j for security reasons. --- CHANGELOG.md | 12 ++++++++++++ pom.xml | 14 ++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c968b923..69200f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Function mapping. * Joins of data streams +### Changed +* Updated Flink from version 1.10.0 to 1.10.1 + +### Fixed +* Escape characters were not escaped in generated literals (Internal [issue #81](https://gitlab.ilabt.imec.be/rml/proc/rml-streamer/issues/81)). +* Curly brackets were not escaped correctly (Internal [issue #65](https://gitlab.ilabt.imec.be/rml/proc/rml-streamer/-/issues/65)). + +## [1.2.3] - 2020-03-16 + +### Changed +* Updated documentation + ## [2.0.0] - 2020-06-08 ### Changed diff --git a/pom.xml b/pom.xml index 97427906..55d1a4c9 100644 --- a/pom.xml +++ b/pom.xml @@ -36,9 +36,9 @@ SOFTWARE. UTF-8 - 1.10.0 + 1.10.1 1.7.26 - 2.13.1 + 2.13.3 3.11.0 2.11 @@ -184,17 +184,11 @@ SOFTWARE. - - org.java-websocket - Java-WebSocket - 1.3.6 - - org.apache.logging.log4j log4j-core - 2.8.2 + ${log4j.version} @@ -254,7 +248,7 @@ SOFTWARE. log4j - log4j + org.apache.logging.log4j From 3c591249403e49a3d6fd365606ffdd543fb73ad5 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Wed, 17 Jun 2020 11:11:41 +0200 Subject: [PATCH 046/169] Transformer already added. --- pom.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pom.xml b/pom.xml index 1dbf03d0..a5275577 100644 --- a/pom.xml +++ b/pom.xml @@ -366,9 +366,6 @@ SOFTWARE. implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> io.rml.framework.Main - - From b90243fdb56fad7438e0ea168832c7735a41f257 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 17 Jun 2020 13:50:04 +0200 Subject: [PATCH 047/169] wip: reset to working commit --- src/main/resources/functions_idlab.ttl | 120 +++++++++++++++++- src/main/resources/idlab_java_mapping.ttl | 12 +- .../core/function/std/StdFunctionLoader.scala | 5 +- .../RMLFNOTC0004-CSV/mapping.ttl | 0 .../fno-testcases/RMLFNOTC0004-CSV/output.ttl | 0 .../RMLFNOTC0005-CSV/mapping.ttl | 2 +- .../fno-testcases/RMLFNOTC0005-CSV/output.ttl | 0 .../RMLFNOTC0005-CSV/student.csv | 0 .../RMLFNOTC0006-CSV/mapping.ttl | 0 .../fno-testcases/RMLFNOTC0006-CSV/output.nq | 0 .../rml/framework/OutputGenerationTest.scala | 18 ++- .../scala/io/rml/framework/SandboxTests.scala | 20 +-- 12 files changed, 151 insertions(+), 26 deletions(-) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0004-CSV/output.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl (94%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0005-CSV/output.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0005-CSV/student.csv (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0006-CSV/output.nq (100%) diff --git a/src/main/resources/functions_idlab.ttl b/src/main/resources/functions_idlab.ttl index 271197dd..fae6b55a 100644 --- a/src/main/resources/functions_idlab.ttl +++ b/src/main/resources/functions_idlab.ttl @@ -7,7 +7,7 @@ @prefix rdfs: . @prefix void: . @prefix xsd: . - +@prefix idlab-fn: . grel:void a void:DatasetDescription ; dcterms:title "A VoID Description of the GREL Fno Descriptions Dataset" ; @@ -43,20 +43,132 @@ grel:dataset # - Problems (per java) prob_{var} # - Functions (per java) +################################ +#### PROBLEMS +################################ grel:prob_ucase a fno:Problem ; fno:name "The ucase problem"^^xsd:string ; dcterms:description "Converting a string to upper case characters."^^xsd:string . -grel:toUpperCaseURL +################################ +#### FUNCTIONS +################################ + +idlab-fn:toUpperCaseURL a fno:Function ; fno:name "toUppercaseURL" ; rdfs:label "toUppercaseURL" ; dcterms:description "Returns an uppercase, valid url." ; fno:solves grel:prob_ucase ; - fno:expects ( grel:valueParam ) ; - fno:returns ( grel:stringOut ) . + fno:expects ( idlab-fn:_str ) ; + fno:returns ( idlab-fn:_stringOut ) . + +################################ +#### PARAMETERS +################################ +idlab-fn:_path + a fno:Parameter ; + fno:name "input path" ; + rdfs:label "input path" ; + fno:type xsd:string ; + fno:predicate idlab-fn:path . + +idlab-fn:_str + a fno:Parameter ; + fno:name "input string" ; + rdfs:label "input string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:str . + +idlab-fn:_strBoolean + a fno:Parameter ; + fno:name "boolean encoded as string" ; + rdfs:label "boolean encoded as string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:strBoolean . + +idlab-fn:_endpoint + a fno:Parameter ; + fno:name "endpoint url string" ; + rdfs:label "endpoint url string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:endpoint . + +idlab-fn:_otherStr + a fno:Parameter ; + fno:name "other input string" ; + rdfs:label "other input string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:otherStr . + +idlab-fn:_expectedStr + a fno:Parameter ; + fno:name "expected input string" ; + rdfs:label "expected input string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:expectedStr . + +idlab-fn:_result + a fno:Parameter ; + fno:name "result string" ; + rdfs:label "result string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:result . + +idlab-fn:_list + a fno:Parameter ; + fno:name "list" ; + rdfs:label "list" ; + fno:type rdf:List ; + fno:predicate idlab-fn:list . + +idlab-fn:_listOut + a fno:Parameter ; + fno:name "output list" ; + rdfs:label "output list" ; + fno:type rdf:List ; + fno:predicate idlab-fn:listOut . + +idlab-fn:_delimiter + a fno:Parameter ; + fno:name "delimiter" ; + rdfs:label "delimiter" ; + fno:type xsd:string ; + fno:predicate idlab-fn:delimiter . + +idlab-fn:_test + a fno:Parameter ; + fno:name "test" ; + rdfs:label "test" ; + fno:type xsd:double ; + fno:predicate idlab-fn:p_test . + +idlab-fn:_from + a fno:Parameter ; + fno:name "from" ; + rdfs:label "from" ; + fno:type xsd:double ; + fno:predicate idlab-fn:p_from . +idlab-fn:_to + a fno:Parameter ; + fno:name "to" ; + rdfs:label "to" ; + fno:type xsd:double ; + fno:predicate idlab-fn:p_to . +idlab-fn:_stringOut + a fno:Output ; + fno:name "output string" ; + rdfs:label "output string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:stringOut . +idlab-fn:_boolOut + a fno:Output ; + fno:name "output boolean" ; + rdfs:label "output boolean" ; + fno:type xsd:boolean ; + fno:predicate idlab-fn:o_boolOut . diff --git a/src/main/resources/idlab_java_mapping.ttl b/src/main/resources/idlab_java_mapping.ttl index 25b7bdef..d05ddecf 100644 --- a/src/main/resources/idlab_java_mapping.ttl +++ b/src/main/resources/idlab_java_mapping.ttl @@ -11,7 +11,7 @@ @prefix rdfs: . @prefix void: . @prefix xsd: . - +@prefix idlab-fn: . grelm:void a void:DatasetDescription ; dcterms:title "A VoID Description of the IDLab Fno Java Mapping Descriptions Dataset" ; @@ -48,16 +48,22 @@ grelm:dataset # - Problems (per java) prob_{var} # - Functions (per java) +################################ +#### IMPLEMENTATIONS +################################ grelm:IDLabFunctions a fnoi:JavaClass ; doap:download-page "IDLabFunctions.jar" ; fnoi:class-name "io.fno.idlab.IDLabFunctions" . -#UPPERCASERURL +################################ +#### MAPPINGS +################################ +#UPPERCASERURL grelm:uppercaseURLMapping a fno:Mapping ; - fno:function grel:toUpperCaseURL ; + fno:function idlab-fn:toUpperCaseURL; fno:implementation grelm:IDLabFunctions ; fno:parameterMapping [ ] ; fno:returnMapping [ ] ; diff --git a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala index 08098631..d28253f9 100644 --- a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala @@ -98,11 +98,12 @@ case class StdFunctionLoader(functionDescriptionTriplesGraph : RDFGraph) extends val paramType = inputResource.listProperties(RMLVoc.Property.FNO_TYPE).headOption val paramUri = inputResource.listProperties(RMLVoc.Property.FNO_PREDICATE).headOption + if(paramType.isEmpty) - throw new FnOException("Parameter Type not defined") + throw new FnOException(s"Parameter Type not defined for parameter resource: ${inputResource.uri}") if(paramUri.isEmpty) - throw new FnOException("Parameter Uri not defined") + throw new FnOException(s"Parameter Uri not defined for parameter resource: ${inputResource.uri}") val typeClass = FunctionUtils.getTypeClass(Uri(paramType.get.toString)) diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl similarity index 94% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl index 511d3344..242b17c9 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "fno-testcases/RMLFNOTC0005-CSV/student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/student.csv b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/student.csv rename to src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq rename to src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index cb7a72bf..4572b9cb 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -64,9 +64,25 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { "Valid mapping output generation" should "match the output from output.ttl" in { // load functions + + // function descriptions + val functionDescriptionFilePaths = List( + "functions_grel.ttl", + "functions_idlab.ttl" + ) + + // function mappings val grelJavaMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) - FunctionLoader().parseFunctionMapping(grelJavaMappingFile) // singleton FunctionLoader + val idlabJavaMappingFile = new File(getClass.getClassLoader.getResource("idlab_java_mapping.ttl").getFile) + + // singleton FunctionLoader created and initialized with given function descriptions + val functionLoader = FunctionLoader(functionDescriptionFilePaths) + // Parse the function mapping files. + // The functionloader will construct a mapping between function uris and the corresponding function meta data objects + functionLoader + .parseFunctionMapping(grelJavaMappingFile) + .parseFunctionMapping(idlabJavaMappingFile) passing.foreach(test => { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.com/base/")) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 4618382b..0f41cdfb 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -97,22 +97,12 @@ class SandboxTests extends FunSuite with Matchers { } } } + // Example +// test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { +// pending +// executeTest("sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl") +// } - /** - * FNO TEST CASES - */ - - test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { - executeTest("sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl") - } - - test("sandbox/fno-testcases/RMLFNOTC0005-CSV") { - executeTest("sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl") - } - - test("sandbox/fno-testcases/RMLFNOTC0006-CSV") { - executeTest("sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl") - } From 7795f3a64758deecb0fefd403ba34da85694877a Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 17 Jun 2020 19:53:50 +0200 Subject: [PATCH 048/169] Merge branch 'fix/function_map_dev_gdm2' into feature/function_map_dev_gdm functions_idlab.ttl: removed commented sections FunctionLoader: throw exceptions instead of returning None. This helps with finding bugs. FunctionLoaderTest: set to not discoverable SandboxTests: set to not discoverable OutputGenerationTest: - added before method setting up the function loader --- src/main/resources/functions_idlab.ttl | 12 ++--- .../core/extractors/MappingExtractor.scala | 1 - .../core/function/FunctionLoader.scala | 10 ++-- .../rml/framework/OutputGenerationTest.scala | 46 +++++++++++-------- .../scala/io/rml/framework/SandboxTests.scala | 5 +- .../model/function/FunctionLoaderTest.scala | 11 +---- 6 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/main/resources/functions_idlab.ttl b/src/main/resources/functions_idlab.ttl index fae6b55a..450354e2 100644 --- a/src/main/resources/functions_idlab.ttl +++ b/src/main/resources/functions_idlab.ttl @@ -43,18 +43,14 @@ grel:dataset # - Problems (per java) prob_{var} # - Functions (per java) -################################ -#### PROBLEMS -################################ + grel:prob_ucase a fno:Problem ; fno:name "The ucase problem"^^xsd:string ; dcterms:description "Converting a string to upper case characters."^^xsd:string . -################################ -#### FUNCTIONS -################################ + idlab-fn:toUpperCaseURL a fno:Function ; @@ -65,9 +61,7 @@ idlab-fn:toUpperCaseURL fno:expects ( idlab-fn:_str ) ; fno:returns ( idlab-fn:_stringOut ) . -################################ -#### PARAMETERS -################################ + idlab-fn:_path a fno:Parameter ; fno:name "input path" ; diff --git a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala index 2d83f708..8a2f07b6 100644 --- a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala @@ -38,7 +38,6 @@ object MappingExtractor { def apply [T<:Graph](cls: Any): MappingExtractor[Graph] = { cls match{ case RMLMapping => new StdMappingExtractor() - case FunctionMapping => new StdFunctionMappingExtractor() case _ => throw new IllegalArgumentException("Given args can only be subclasses of Mapping") } diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index 19349352..b7b3a765 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -52,11 +52,13 @@ abstract class FunctionLoader extends Logging { functionMetaData match { case functionMetaData: FunctionMetaData => Some(Function(functionMetaData.identifier, functionMetaData)) case loadedFunction: DynamicMethodFunction => Some(loadedFunction) - case _ => None + case _ => throw new FnOException("Can't match the function meta data") } } else { - None + val availableFunctionURIs = functionMap.keys.map(u=>u.toString) + throw new FnOException(s"The function with URI ${uri.toString} can not be found.\n" + + s"The available function URIs are: " + availableFunctionURIs) } } @@ -95,12 +97,13 @@ abstract class FunctionLoader extends Logging { } -object FunctionLoader { +object FunctionLoader extends Logging{ private var singletonFunctionLoader : Option[FunctionLoader] = None private val defaultFunctionDescriptionFilePaths = List( "functions_grel.ttl" + ) /** @@ -113,6 +116,7 @@ object FunctionLoader { if (!functionDescriptionsFile.exists()) throw new RMLException(s"Couldn't find ${functionDescriptionsFile.getName}") + logDebug(s"FunctionLoader is reading function descriptions from : ${filePath}") RDFGraph.fromFile(functionDescriptionsFile, RMLEnvironment.getGeneratorBaseIRI(), Turtle) } diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index 4572b9cb..4630fd05 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -34,13 +34,38 @@ import io.rml.framework.engine.PostProcessor import io.rml.framework.util.TestUtil import io.rml.framework.util.fileprocessing.{ExpectedOutputTestUtil, TripleGeneratorTestUtil} import io.rml.framework.util.logging.Logger +import org.scalatest.BeforeAndAfter import scala.util.control.Exception -class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { +class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour with BeforeAndAfter { + + private def setupFunctionLoader() : Unit = { + // function descriptions + val functionDescriptionFilePaths = List( + "functions_grel.ttl", + "functions_idlab.ttl" + ) + + // function mappings + val grelJavaMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) + val idlabJavaMappingFile = new File(getClass.getClassLoader.getResource("idlab_java_mapping.ttl").getFile) + + // singleton FunctionLoader created and initialized with given function descriptions + val functionLoader = FunctionLoader(functionDescriptionFilePaths) + + // Parse the function mapping files. + // The functionloader will construct a mapping between function uris and the corresponding function meta data objects + functionLoader + .parseFunctionMapping(grelJavaMappingFile) + .parseFunctionMapping(idlabJavaMappingFile) + } + before { + setupFunctionLoader() + } + - val functionFile = new File(getClass.getClassLoader.getResource("functions.ttl").getFile) // dev note: // Explicit type annotation allows to completely comment out the elements of the failing, passing or temp arrays // without causing compilation failures. @@ -63,26 +88,9 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { "Valid mapping file" should behave like validMappingFile("rml-testcases") "Valid mapping output generation" should "match the output from output.ttl" in { - // load functions - // function descriptions - val functionDescriptionFilePaths = List( - "functions_grel.ttl", - "functions_idlab.ttl" - ) - // function mappings - val grelJavaMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) - val idlabJavaMappingFile = new File(getClass.getClassLoader.getResource("idlab_java_mapping.ttl").getFile) - // singleton FunctionLoader created and initialized with given function descriptions - val functionLoader = FunctionLoader(functionDescriptionFilePaths) - - // Parse the function mapping files. - // The functionloader will construct a mapping between function uris and the corresponding function meta data objects - functionLoader - .parseFunctionMapping(grelJavaMappingFile) - .parseFunctionMapping(idlabJavaMappingFile) passing.foreach(test => { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.com/base/")) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 0f41cdfb..e99384fe 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -34,13 +34,12 @@ import io.rml.framework.core.model.FunctionMapping import io.rml.framework.core.util.Util import io.rml.framework.engine.NopPostProcessor import io.rml.framework.util.TestUtil - import io.rml.framework.util.logging.Logger import org.apache.flink.api.scala.ExecutionEnvironment import org.apache.flink.streaming.api.scala._ -import org.scalatest.{FunSuite, Matchers} +import org.scalatest.{DoNotDiscover, FunSuite, Ignore, Matchers} import io.rml.framework.util.logging.Logger - +@DoNotDiscover class SandboxTests extends FunSuite with Matchers { val functionFile = new File(getClass.getClassLoader.getResource("functions.ttl").getFile) diff --git a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala index 400a1162..e04d1d75 100644 --- a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala +++ b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala @@ -9,19 +9,12 @@ import io.rml.framework.core.function.std.StdFunctionLoader import io.rml.framework.core.function.{FunctionLoader, FunctionUtils} import io.rml.framework.core.model.Uri import io.rml.framework.core.vocabulary.{Namespaces, RMLVoc} +import org.scalatest.{DoNotDiscover, Ignore} +@DoNotDiscover class FunctionLoaderTest extends StaticTestSpec { - val functionMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) - "FunctionLoader" should "initialize the transformation lazily and correctly" in { - val loader = FunctionLoader().parseFunctionMapping(functionMappingFile) - assert(loader.isInstanceOf[StdFunctionLoader]) -// val test = Uri("http://users.ugent.be/~bjdmeest/function/grel.ttl#toUpperCase") -// val transformation = loader.loadFunction(test) -// -// assume(transformation.isInstanceOf[Option[DynamicMethodFunction]]) - } } From 39b09e41def521bc14e2a7e425ea3b951455d2e9 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 08:58:56 +0200 Subject: [PATCH 049/169] wip: updated documentation #88 --- documentation/README_Functions.md | 47 ++++++++++++++----------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/documentation/README_Functions.md b/documentation/README_Functions.md index 169e4e3b..3683683b 100644 --- a/documentation/README_Functions.md +++ b/documentation/README_Functions.md @@ -31,49 +31,42 @@ public class IDLabFunctions { Use Maven to build a JAR-file, and move this JAR-file to the RMLStreamer’s `main/resources`. ### Step 2: defining the FnO descriptions -An FnO description represents the abstract definition of a function. - -The testcases mentioned above require a function that returns a valid URL in uppercase, and is described as follows - +An FnO description represents the abstract definition of a function.
+The aforementioned testcases require a function that returns a valid URL in uppercase. + Its description is shown in the following listing, and can be found in `functions_idlab.ttl`. ```Turtle -# source: `functions_idlab.ttl`. -grel:prob_ucase - a fno:Problem ; - fno:name "The ucase problem"^^xsd:string ; - dcterms:description "Converting a string to upper case characters."^^xsd:string . - -grel:toUpperCaseURL +idlab-fn:toUpperCaseURL a fno:Function ; fno:name "toUppercaseURL" ; rdfs:label "toUppercaseURL" ; dcterms:description "Returns an uppercase, valid url." ; fno:solves grel:prob_ucase ; - fno:expects ( grel:valueParam ) ; - fno:returns ( grel:stringOut ) . + fno:expects ( idlab-fn:_str ) ; + fno:returns ( idlab-fn:_stringOut ) . ``` ### Step 3: map FnO descriptions to the corresponding implementations In the previous step, the abstract functions were created. -The current step will define the link between abstract function descriptions and the corresponding implementation. This is illustrated by the following snippet. +The current step will define the link between abstract function descriptions and the corresponding implementation. + This is illustrated by the following listing, extracted from `idlab_java_mapping.ttl`. ```Turtle grelm:IDLabFunctions a fnoi:JavaClass ; doap:download-page "IDLabFunctions.jar" ; fnoi:class-name "io.fno.idlab.IDLabFunctions" . -#UPPERCASERURL + grelm:uppercaseURLMapping a fno:Mapping ; - fno:function grel:toUpperCaseURL ; + fno:function idlab-fn:toUpperCaseURL; fno:implementation grelm:IDLabFunctions ; fno:parameterMapping [ ] ; fno:returnMapping [ ] ; - fno:methodMapping [ - a fnom:StringMethodMapping ; - fnom:method-name "toUpperCaseURL" - ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "toUpperCaseURL" ] ; . + ``` This mapping instructs the RML Streamer to look for a method called `toUpperCaseURL` within the `io.fno.idlab.IDLabFunctions`-class of the `IDLabFunctions.jar`. Make sure that the JAR-file is located in `main/resources`. @@ -82,17 +75,19 @@ This mapping instructs the RML Streamer to look for a method called `toUpperCase The function descriptions and mappings mentioned in the previous steps will be used by the `FunctionLoader`. First, a `FunctionLoader` has to be aware of the available functions. -Therefore, it can be instantiated providing file paths to the function description files. When no such file paths where provided, the default function descriptions are used (e.g. `functions_grel.ttl`). +Therefore, it can be instantiated providing file paths to the function description files. +When no such file paths are provided, the default function descriptions are used (i.e. `functions_grel.ttl`). -Secondly, function URIs are mapped to the corresponding implementations by parsing the function mappings (e.g. `resources/grel_java_mapping.ttl` and `resources/idlab_java_mapping.ttl`). During this step, every function URI is mapped to a `FunctionMetaData`-object which contains the necessary meta data such as: the *download-page* of the library, the *class-name* of the function, the *method-name*, *input parameters* and *output parameters*. +Secondly, function URIs are mapped to the corresponding implementations by parsing the function mappings + (e.g. `resources/grel_java_mapping.ttl` and `resources/idlab_java_mapping.ttl`). + During this step, every function URI is mapped to a `FunctionMetaData`-object which contains the necessary meta data such as: the *download-page* of the library, the *class-name* of the function, the *method-name*, *input parameters* and *output parameters*. ## How the `FunctionLoader` is used -Initially, the `FunctionLoader` is used to read and parse function descriptions and mappings. Afterwards, when running FNOT-testcases, the `FunctionLoader`-instance is used to load and bind every function as specified in the `mapping.ttl`. - +Initially, the `FunctionLoader` is used to read and parse function descriptions and mappings. +Afterwards, when running FNOT-testcases, the `FunctionLoader`-instance is used by `io.rml.framework.engine.statement.FunctionMapGeneratorAssembler` +to load and bind every function as specified in the testcase's `mapping.ttl`. -## Remarks -- When running the `SandboxTests` , make sure to set the *Working Directory* of the *Run-configuration* to the absolute path of `rml-streamer/src/test/resources/sandbox`. From c49f64915caf9c050bb85fed564ce09c3573d134 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 09:47:42 +0200 Subject: [PATCH 050/169] wip: feature function #25: updated IDLabFunctions --- src/main/resources/IDLabFunctions.jar | Bin 2349 -> 2572 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/main/resources/IDLabFunctions.jar b/src/main/resources/IDLabFunctions.jar index 8431970c5c9692e01625fb8a4fe08d4885a6b875..e3b7e8892f319899b7411382d10ff5c8d6894fad 100644 GIT binary patch literal 2572 zcmWIWW@h1H0D--}mjb{HD8UJ&eO*Hwbv^yu^aG&EI2iT-m3_UHQBeq#ZUr)RmQ7$Ewn* zjtTf`?uygAsZg!+h38Rk4^QRJik%EFCo(WJdZYS;8R*2!e7GMl6|h4Tq~#$iy5xgu z3NJ!YW=c+C65Kov29Q#RLeJORm>3vzSs54<(Up3-_#`H|mF6XvWaj4;>m}zT78los zL^RlzFns3%Dt1}k=1pc?~ z6VW&R$8i6TbKmSO0UKIv-n_f{``u5!y8nMaavxBN^L%l%gu__qox?{DA19g3ax=M= z8!H7@wFoS;-J}qBVv@RUdqMaSTfy&=P5r#53&JI>rrxk?p0MfjoQ3AO5jDG`P8B}y zoo4JQ?0I`v+Pmz&hjXR94(dvYwr$*!xVnAXTB*w5(<`H2XXXHCw=&E1r|dt2UYYd(9EzP-zCKN0CFYn^16HD{{iB3;jNlj~3WT-U9+a_*h@ zQ@)!^*Tj~V>`SaTEwRJm`yO$%#r%JHoZnAb^m>}My!bOQ`?V{wd}j6^U*=*n;iEu* z${GdDM;m+8Bc^^7IqzaKePf%*;Sc|r*M#yKpO=+ z0C6UJK`RT#@Q@XbU2It#!s{LXUAo}D>!nQos`FB_mfYu82;6C4sxo<9`>hvCcm8^@ z{Hp%~`46*WRr>`mxfIIIO__T@BhNwMEXOequ8Oyh)I9G^i0pYR#;dICJa6*9yu9D0 z%l|PVav6Gg!4FLI@bV%zu`D$Yo7T)l~|St zH;9AbDlmI)pI!g&E6{*-j0_A$q#0C@pQ~4qo6|bM(EqT3K*wOc>(jr@FTls3Ab zn`2Shp`T6F4=z6SVt%Ai@z%}9-^CW?c4kYv>Hl5R#9hU%G>75l0secky%x1^KQdM& zd|{g*`}{+tUr|i$o}5+NzfQaOugWCx%N)D^tgz_jV7LJc#NUhmHv);O1I-b6P9;-q=`099{eH_GhQX}+(*4bc#Edd4_wis>OU}P9x zP{zv_XkcVu^gs(*jhJ3BzQX&hn1|!r2mXg%`ls}DKlp4sd*-_Ksk0BgbhJ+Tc>Cxv zb}o6MqV{sx)Mu*G8A?T8r>Ra;En)=L5R6PB%(!bippSq+fZ?qph=!+Sgf{H8A4o9> zENN5+l5lNEbs@q8%(@3uIY9u(;!{8-xT-?96umYBRaOuH((oF{1Zsd(T?kFsDldd4 z0bnM8YJyc|Fs;}tGpL0?FIuB(#a6W;`xjd=0dvX!{{}2bAqFcnU~a))Y#=npVrqsL zBDl=}6(a~UCgL;$N1*~U7<;h-GkQtmEz%5z7BYyC!=B?1=F78TgdEiKSRD>BACdn8 Tyjg+T85p>MkPDas-+*}l#)4^R literal 2349 zcmWIWW@h1H0D(<$7XrWxD8UJ&eO*Hwbv^yu^aG&EI2bkpm3_UHQBeq#ZUr)RmQ7$Ewn* zjtTf`?uygAsZg!+h38Rk4^QRJik%EFCo(X!MWFhG8R*2!e7GMl6|h4Tq~#$i0(lfD z4hOtI7SI%sqRf<>#3Z8RUpTs1$(!Au7%>2A!z2uz4 z;^N+*i+MthBDUKD#9oL^5ZfBEW$UFwQFni69c#a2VtDh4i{eZ$&39FIH_KmM ze?WXz#v}G0fyb;JrffS>BL8k@@w0b3%g>!zfB$|xQ$_P%ov;lP-7LF(Z43iWDy_Wk zZ)$h>$+UCZcx}u#ID71!+!*qnvoq@NlnFU)vHcUuQy$3j>&NO_39dWubCJ{fkiF={ zE3YMIhSW+5YxVKG{j9Jh^}6`FzYi}6zPo7fLPL_Ruz5moVzt4CMaw$&ep7GX5M8Wy zBs}rA(uYiQGtv8>%**(>=n)CJ6R=;JT7H2o|{&o4Xo#m2V;hB%8 z(o~M6zLxruyJ_z88M7vEidf9L%w*#*(XiQc&G|aJ*&U3bt9O{VJ>q&Q?@_n!SdpP= zTVn6TGzn$nOD|unujp&tn$UJT=irR&AXiR)$)D%cuJ->&N?GW6gdZ5u@H~>6SeBXx zPZgLMN*Ysfeo?w!YDHphK~5?jjRyENf>Wbz8Z33`W+j#-!cF5~kOt-kpFR__??6*F z0~4q@8KxEF=jv7D=ClT$_dl#4vhVwPg*%OYwlmr`RT$37$@5(P@z;_y$(aiouYEf& z{&L%y=84kxf7k8V)33jLoojPZTy*dw*0Y8|ZnvUlFFW#nclxJ}=}M3HZgy8??#g-W zUBj_ZU*dH_K${c)rv)oYd2i=kd(-&rqN?-s=_*H`d<`}0QK_l#BH$wHLp_3dGkoKOY{8?Ka==$>!#U}oy+v=uC+=Wd!iOc~% z4XI*4n1ERjgGy=$09kwr$OM<$2$!N4?Vyqy0zevG1DVhw8rc?XB{@Qq05DIWmFqD3 zu$Sym3xQs=M%Rk1oJV#Ew( Date: Thu, 18 Jun 2020 13:55:29 +0200 Subject: [PATCH 051/169] Error during merge. Also use ServicesResourceTransformer --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a5275577..3060c298 100644 --- a/pom.xml +++ b/pom.xml @@ -363,7 +363,7 @@ SOFTWARE. to use the transformer to include those files in the fat-jar. --> + implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"> io.rml.framework.Main From 5042062dce8ca5acf69a2f109ff82f5983b67868 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 18 Jun 2020 14:05:56 +0200 Subject: [PATCH 052/169] Updated test reports (and made them compatible with https://rml.io/implementation-report/) --- src/test/resources/report/static/result.csv | 236 ++++++++++---------- src/test/resources/report/stream/result.csv | 236 ++++++++++---------- 2 files changed, 236 insertions(+), 236 deletions(-) diff --git a/src/test/resources/report/static/result.csv b/src/test/resources/report/static/result.csv index 4d3f8064..1d3bcb7a 100644 --- a/src/test/resources/report/static/result.csv +++ b/src/test/resources/report/static/result.csv @@ -1,58 +1,58 @@ testid,result -RMLTC0000-CSV,passing -RMLTC0000-JSON,passing +RMLTC0000-CSV,passed +RMLTC0000-JSON,passed RMLTC0000-MySQL,inapplicable RMLTC0000-PostgreSQL,inapplicable RMLTC0000-SPARQL,inapplicable RMLTC0000-SQLServer,inapplicable -RMLTC0000-XML,passing -RMLTC0001a-CSV,passing -RMLTC0001a-JSON,passing +RMLTC0000-XML,passed +RMLTC0001a-CSV,passed +RMLTC0001a-JSON,passed RMLTC0001a-MySQL,inapplicable RMLTC0001a-PostgreSQL,inapplicable RMLTC0001a-SPARQL,inapplicable RMLTC0001a-SQLServer,inapplicable -RMLTC0001a-XML,passing -RMLTC0001b-CSV,passing -RMLTC0001b-JSON,passing +RMLTC0001a-XML,passed +RMLTC0001b-CSV,passed +RMLTC0001b-JSON,passed RMLTC0001b-MySQL,inapplicable RMLTC0001b-PostgreSQL,inapplicable RMLTC0001b-SPARQL,inapplicable RMLTC0001b-SQLServer,inapplicable -RMLTC0001b-XML,passing -RMLTC0002a-CSV,passing -RMLTC0002a-JSON,passing +RMLTC0001b-XML,passed +RMLTC0002a-CSV,passed +RMLTC0002a-JSON,passed RMLTC0002a-MySQL,inapplicable RMLTC0002a-PostgreSQL,inapplicable RMLTC0002a-SPARQL,inapplicable RMLTC0002a-SQLServer,inapplicable -RMLTC0002a-XML,passing -RMLTC0002b-CSV,passing -RMLTC0002b-JSON,passing +RMLTC0002a-XML,passed +RMLTC0002b-CSV,passed +RMLTC0002b-JSON,passed RMLTC0002b-MySQL,inapplicable RMLTC0002b-PostgreSQL,inapplicable RMLTC0002b-SPARQL,inapplicable RMLTC0002b-SQLServer,inapplicable -RMLTC0002b-XML,passing -RMLTC0002c-CSV,passing -RMLTC0002c-JSON,passing +RMLTC0002b-XML,passed +RMLTC0002c-CSV,passed +RMLTC0002c-JSON,passed RMLTC0002c-MySQL,inapplicable RMLTC0002c-PostgreSQL,inapplicable RMLTC0002c-SQLServer,inapplicable -RMLTC0002c-XML,passing +RMLTC0002c-XML,passed RMLTC0002d-MySQL,inapplicable RMLTC0002d-PostgreSQL,inapplicable RMLTC0002d-SQLServer,inapplicable -RMLTC0002e-CSV,passing -RMLTC0002e-JSON,passing +RMLTC0002e-CSV,passed +RMLTC0002e-JSON,passed RMLTC0002e-MySQL,inapplicable RMLTC0002e-PostgreSQL,inapplicable RMLTC0002e-SQLServer,inapplicable -RMLTC0002e-XML,passing +RMLTC0002e-XML,passed RMLTC0002f-MySQL,inapplicable RMLTC0002f-PostgreSQL,inapplicable RMLTC0002f-SQLServer,inapplicable -RMLTC0002g-JSON,passing +RMLTC0002g-JSON,passed RMLTC0002g-MySQL,inapplicable RMLTC0002g-PostgreSQL,inapplicable RMLTC0002g-SPARQL,inapplicable @@ -73,214 +73,214 @@ RMLTC0003a-SQLServer,inapplicable RMLTC0003b-MySQL,inapplicable RMLTC0003b-PostgreSQL,inapplicable RMLTC0003b-SQLServer,inapplicable -RMLTC0003c-CSV,passing -RMLTC0003c-JSON,passing +RMLTC0003c-CSV,passed +RMLTC0003c-JSON,passed RMLTC0003c-MySQL,inapplicable RMLTC0003c-PostgreSQL,inapplicable RMLTC0003c-SPARQL,inapplicable RMLTC0003c-SQLServer,inapplicable -RMLTC0003c-XML,passing -RMLTC0004a-CSV,passing -RMLTC0004a-JSON,passing +RMLTC0003c-XML,passed +RMLTC0004a-CSV,passed +RMLTC0004a-JSON,passed RMLTC0004a-MySQL,inapplicable RMLTC0004a-PostgreSQL,inapplicable RMLTC0004a-SPARQL,inapplicable RMLTC0004a-SQLServer,inapplicable -RMLTC0004a-XML,passing -RMLTC0004b-CSV,passing -RMLTC0004b-JSON,passing +RMLTC0004a-XML,passed +RMLTC0004b-CSV,passed +RMLTC0004b-JSON,passed RMLTC0004b-MySQL,inapplicable RMLTC0004b-PostgreSQL,inapplicable RMLTC0004b-SPARQL,inapplicable RMLTC0004b-SQLServer,inapplicable -RMLTC0004b-XML,passing -RMLTC0005a-CSV,passing -RMLTC0005a-JSON,passing +RMLTC0004b-XML,passed +RMLTC0005a-CSV,passed +RMLTC0005a-JSON,passed RMLTC0005a-MySQL,inapplicable RMLTC0005a-PostgreSQL,inapplicable RMLTC0005a-SQLServer,inapplicable -RMLTC0005a-XML,passing +RMLTC0005a-XML,passed RMLTC0005b-MySQL,inapplicable RMLTC0005b-PostgreSQL,inapplicable RMLTC0005b-SQLServer,inapplicable -RMLTC0006a-CSV,passing -RMLTC0006a-JSON,passing +RMLTC0006a-CSV,passed +RMLTC0006a-JSON,passed RMLTC0006a-MySQL,inapplicable RMLTC0006a-PostgreSQL,inapplicable RMLTC0006a-SPARQL,inapplicable RMLTC0006a-SQLServer,inapplicable -RMLTC0006a-XML,passing -RMLTC0007a-CSV,passing -RMLTC0007a-JSON,passing +RMLTC0006a-XML,passed +RMLTC0007a-CSV,passed +RMLTC0007a-JSON,passed RMLTC0007a-MySQL,inapplicable RMLTC0007a-PostgreSQL,inapplicable RMLTC0007a-SPARQL,inapplicable RMLTC0007a-SQLServer,inapplicable -RMLTC0007a-XML,passing -RMLTC0007b-CSV,passing -RMLTC0007b-JSON,passing +RMLTC0007a-XML,passed +RMLTC0007b-CSV,passed +RMLTC0007b-JSON,passed RMLTC0007b-MySQL,inapplicable RMLTC0007b-PostgreSQL,inapplicable RMLTC0007b-SPARQL,inapplicable RMLTC0007b-SQLServer,inapplicable -RMLTC0007b-XML,passing -RMLTC0007c-CSV,passing -RMLTC0007c-JSON,passing +RMLTC0007b-XML,passed +RMLTC0007c-CSV,passed +RMLTC0007c-JSON,passed RMLTC0007c-MySQL,inapplicable RMLTC0007c-PostgreSQL,inapplicable RMLTC0007c-SPARQL,inapplicable RMLTC0007c-SQLServer,inapplicable -RMLTC0007c-XML,passing -RMLTC0007d-CSV,passing -RMLTC0007d-JSON,passing +RMLTC0007c-XML,passed +RMLTC0007d-CSV,passed +RMLTC0007d-JSON,passed RMLTC0007d-MySQL,inapplicable RMLTC0007d-PostgreSQL,inapplicable RMLTC0007d-SPARQL,inapplicable RMLTC0007d-SQLServer,inapplicable -RMLTC0007d-XML,passing -RMLTC0007e-CSV,passing -RMLTC0007e-JSON,passing +RMLTC0007d-XML,passed +RMLTC0007e-CSV,passed +RMLTC0007e-JSON,passed RMLTC0007e-MySQL,inapplicable RMLTC0007e-PostgreSQL,inapplicable RMLTC0007e-SPARQL,inapplicable RMLTC0007e-SQLServer,inapplicable -RMLTC0007e-XML,passing -RMLTC0007f-CSV,passing -RMLTC0007f-JSON,passing +RMLTC0007e-XML,passed +RMLTC0007f-CSV,passed +RMLTC0007f-JSON,passed RMLTC0007f-MySQL,inapplicable RMLTC0007f-PostgreSQL,inapplicable RMLTC0007f-SPARQL,inapplicable RMLTC0007f-SQLServer,inapplicable -RMLTC0007f-XML,passing -RMLTC0007g-CSV,passing -RMLTC0007g-JSON,passing +RMLTC0007f-XML,passed +RMLTC0007g-CSV,passed +RMLTC0007g-JSON,passed RMLTC0007g-MySQL,inapplicable RMLTC0007g-PostgreSQL,inapplicable RMLTC0007g-SPARQL,inapplicable RMLTC0007g-SQLServer,inapplicable -RMLTC0007g-XML,passing -RMLTC0007h-CSV,passing -RMLTC0007h-JSON,passing +RMLTC0007g-XML,passed +RMLTC0007h-CSV,passed +RMLTC0007h-JSON,passed RMLTC0007h-MySQL,inapplicable RMLTC0007h-PostgreSQL,inapplicable RMLTC0007h-SPARQL,inapplicable RMLTC0007h-SQLServer,inapplicable -RMLTC0007h-XML,passing -RMLTC0008a-CSV,passing -RMLTC0008a-JSON,passing +RMLTC0007h-XML,passed +RMLTC0008a-CSV,passed +RMLTC0008a-JSON,passed RMLTC0008a-MySQL,inapplicable RMLTC0008a-PostgreSQL,inapplicable RMLTC0008a-SPARQL,inapplicable RMLTC0008a-SQLServer,inapplicable -RMLTC0008a-XML,passing -RMLTC0008b-CSV,passing -RMLTC0008b-JSON,passing +RMLTC0008a-XML,passed +RMLTC0008b-CSV,passed +RMLTC0008b-JSON,passed RMLTC0008b-MySQL,inapplicable RMLTC0008b-PostgreSQL,inapplicable RMLTC0008b-SPARQL,inapplicable RMLTC0008b-SQLServer,inapplicable -RMLTC0008b-XML,passing -RMLTC0008c-CSV,passing -RMLTC0008c-JSON,passing +RMLTC0008b-XML,passed +RMLTC0008c-CSV,passed +RMLTC0008c-JSON,passed RMLTC0008c-MySQL,inapplicable RMLTC0008c-PostgreSQL,inapplicable RMLTC0008c-SPARQL,inapplicable RMLTC0008c-SQLServer,inapplicable -RMLTC0008c-XML,passing -RMLTC0009a-CSV,passing -RMLTC0009a-JSON,passing +RMLTC0008c-XML,passed +RMLTC0009a-CSV,passed +RMLTC0009a-JSON,passed RMLTC0009a-MySQL,inapplicable RMLTC0009a-PostgreSQL,inapplicable RMLTC0009a-SPARQL,inapplicable RMLTC0009a-SQLServer,inapplicable -RMLTC0009a-XML,passing -RMLTC0009b-CSV,passing -RMLTC0009b-JSON,passing +RMLTC0009a-XML,passed +RMLTC0009b-CSV,passed +RMLTC0009b-JSON,passed RMLTC0009b-MySQL,inapplicable RMLTC0009b-PostgreSQL,inapplicable RMLTC0009b-SPARQL,inapplicable RMLTC0009b-SQLServer,inapplicable -RMLTC0009b-XML,passing +RMLTC0009b-XML,passed RMLTC0009c-MySQL,inapplicable RMLTC0009c-PostgreSQL,inapplicable RMLTC0009c-SQLServer,inapplicable RMLTC0009d-MySQL,inapplicable RMLTC0009d-PostgreSQL,inapplicable RMLTC0009d-SQLServer,inapplicable -RMLTC0010a-CSV,passing -RMLTC0010a-JSON,passing +RMLTC0010a-CSV,passed +RMLTC0010a-JSON,passed RMLTC0010a-MySQL,inapplicable RMLTC0010a-PostgreSQL,inapplicable RMLTC0010a-SQLServer,inapplicable -RMLTC0010b-CSV,passing -RMLTC0010b-JSON,passing +RMLTC0010b-CSV,passed +RMLTC0010b-JSON,passed RMLTC0010b-MySQL,inapplicable RMLTC0010b-PostgreSQL,inapplicable RMLTC0010b-SQLServer,inapplicable -RMLTC0010b-XML,passing -RMLTC0010c-CSV,failed -RMLTC0010c-JSON,failed +RMLTC0010b-XML,passed +RMLTC0010c-CSV,passed +RMLTC0010c-JSON,passed RMLTC0010c-MySQL,inapplicable RMLTC0010c-PostgreSQL,inapplicable RMLTC0010c-SQLServer,inapplicable -RMLTC0010c-XML,failed +RMLTC0010c-XML,passed RMLTC0011a-MySQL,inapplicable RMLTC0011a-PostgreSQL,inapplicable RMLTC0011a-SQLServer,inapplicable -RMLTC0011b-CSV,passing -RMLTC0011b-JSON,passing +RMLTC0011b-CSV,passed +RMLTC0011b-JSON,passed RMLTC0011b-MySQL,inapplicable RMLTC0011b-PostgreSQL,inapplicable RMLTC0011b-SQLServer,inapplicable -RMLTC0011b-XML,passing -RMLTC0012a-CSV,passing -RMLTC0012a-JSON,passing +RMLTC0011b-XML,passed +RMLTC0012a-CSV,passed +RMLTC0012a-JSON,passed RMLTC0012a-MySQL,inapplicable RMLTC0012a-PostgreSQL,inapplicable RMLTC0012a-SPARQL,inapplicable RMLTC0012a-SQLServer,inapplicable -RMLTC0012a-XML,passing -RMLTC0012b-CSV,passing -RMLTC0012b-JSON,passing +RMLTC0012a-XML,passed +RMLTC0012b-CSV,passed +RMLTC0012b-JSON,passed RMLTC0012b-MySQL,inapplicable RMLTC0012b-PostgreSQL,inapplicable RMLTC0012b-SPARQL,inapplicable RMLTC0012b-SQLServer,inapplicable -RMLTC0012b-XML,passing -RMLTC0012c-CSV,passing -RMLTC0012c-JSON,passing +RMLTC0012b-XML,passed +RMLTC0012c-CSV,passed +RMLTC0012c-JSON,passed RMLTC0012c-MySQL,inapplicable RMLTC0012c-PostgreSQL,inapplicable RMLTC0012c-SQLServer,inapplicable -RMLTC0012c-XML,passing -RMLTC0012d-CSV,passing -RMLTC0012d-JSON,passing +RMLTC0012c-XML,passed +RMLTC0012d-CSV,passed +RMLTC0012d-JSON,passed RMLTC0012d-MySQL,inapplicable RMLTC0012d-PostgreSQL,inapplicable RMLTC0012d-SQLServer,inapplicable -RMLTC0012d-XML,passing +RMLTC0012d-XML,passed RMLTC0012e-MySQL,inapplicable RMLTC0012e-PostgreSQL,inapplicable RMLTC0012e-SQLServer,inapplicable -RMLTC0013a-JSON,passing +RMLTC0013a-JSON,passed RMLTC0013a-MySQL,inapplicable RMLTC0013a-PostgreSQL,inapplicable RMLTC0013a-SQLServer,inapplicable RMLTC0014d-MySQL,inapplicable RMLTC0014d-PostgreSQL,inapplicable RMLTC0014d-SQLServer,inapplicable -RMLTC0015a-CSV,passing -RMLTC0015a-JSON,passing +RMLTC0015a-CSV,passed +RMLTC0015a-JSON,passed RMLTC0015a-MySQL,inapplicable RMLTC0015a-PostgreSQL,inapplicable RMLTC0015a-SQLServer,inapplicable -RMLTC0015a-XML,passing -RMLTC0015b-CSV,passing -RMLTC0015b-JSON,passing +RMLTC0015a-XML,passed +RMLTC0015b-CSV,passed +RMLTC0015b-JSON,passed RMLTC0015b-MySQL,inapplicable RMLTC0015b-PostgreSQL,inapplicable RMLTC0015b-SQLServer,inapplicable -RMLTC0015b-XML,passing +RMLTC0015b-XML,passed RMLTC0016a-MySQL,inapplicable RMLTC0016a-PostgreSQL,inapplicable RMLTC0016a-SQLServer,inapplicable @@ -299,27 +299,27 @@ RMLTC0016e-SQLServer,inapplicable RMLTC0018a-MySQL,inapplicable RMLTC0018a-PostgreSQL,inapplicable RMLTC0018a-SQLServer,inapplicable -RMLTC0019a-CSV,passing -RMLTC0019a-JSON,passing +RMLTC0019a-CSV,passed +RMLTC0019a-JSON,passed RMLTC0019a-MySQL,inapplicable RMLTC0019a-PostgreSQL,inapplicable RMLTC0019a-SQLServer,inapplicable -RMLTC0019a-XML,passing -RMLTC0019b-CSV,passing -RMLTC0019b-JSON,passing +RMLTC0019a-XML,passed +RMLTC0019b-CSV,passed +RMLTC0019b-JSON,passed RMLTC0019b-MySQL,inapplicable RMLTC0019b-PostgreSQL,inapplicable RMLTC0019b-SQLServer,inapplicable -RMLTC0019b-XML,passing -RMLTC0020a-CSV,passing -RMLTC0020a-JSON,passing +RMLTC0019b-XML,passed +RMLTC0020a-CSV,passed +RMLTC0020a-JSON,passed RMLTC0020a-MySQL,inapplicable RMLTC0020a-PostgreSQL,inapplicable RMLTC0020a-SQLServer,inapplicable -RMLTC0020a-XML,passing -RMLTC0020b-CSV,passing -RMLTC0020b-JSON,passing +RMLTC0020a-XML,passed +RMLTC0020b-CSV,passed +RMLTC0020b-JSON,passed RMLTC0020b-MySQL,inapplicable RMLTC0020b-PostgreSQL,inapplicable RMLTC0020b-SQLServer,inapplicable -RMLTC0020b-XML,passing +RMLTC0020b-XML,passed diff --git a/src/test/resources/report/stream/result.csv b/src/test/resources/report/stream/result.csv index 35d5da09..1d3bcb7a 100644 --- a/src/test/resources/report/stream/result.csv +++ b/src/test/resources/report/stream/result.csv @@ -1,58 +1,58 @@ testid,result -RMLTC0000-CSV,passing -RMLTC0000-JSON,passing +RMLTC0000-CSV,passed +RMLTC0000-JSON,passed RMLTC0000-MySQL,inapplicable RMLTC0000-PostgreSQL,inapplicable RMLTC0000-SPARQL,inapplicable RMLTC0000-SQLServer,inapplicable -RMLTC0000-XML,passing -RMLTC0001a-CSV,passing -RMLTC0001a-JSON,passing +RMLTC0000-XML,passed +RMLTC0001a-CSV,passed +RMLTC0001a-JSON,passed RMLTC0001a-MySQL,inapplicable RMLTC0001a-PostgreSQL,inapplicable RMLTC0001a-SPARQL,inapplicable RMLTC0001a-SQLServer,inapplicable -RMLTC0001a-XML,passing -RMLTC0001b-CSV,passing -RMLTC0001b-JSON,passing +RMLTC0001a-XML,passed +RMLTC0001b-CSV,passed +RMLTC0001b-JSON,passed RMLTC0001b-MySQL,inapplicable RMLTC0001b-PostgreSQL,inapplicable RMLTC0001b-SPARQL,inapplicable RMLTC0001b-SQLServer,inapplicable -RMLTC0001b-XML,passing -RMLTC0002a-CSV,passing -RMLTC0002a-JSON,passing +RMLTC0001b-XML,passed +RMLTC0002a-CSV,passed +RMLTC0002a-JSON,passed RMLTC0002a-MySQL,inapplicable RMLTC0002a-PostgreSQL,inapplicable RMLTC0002a-SPARQL,inapplicable RMLTC0002a-SQLServer,inapplicable -RMLTC0002a-XML,passing -RMLTC0002b-CSV,passing -RMLTC0002b-JSON,passing +RMLTC0002a-XML,passed +RMLTC0002b-CSV,passed +RMLTC0002b-JSON,passed RMLTC0002b-MySQL,inapplicable RMLTC0002b-PostgreSQL,inapplicable RMLTC0002b-SPARQL,inapplicable RMLTC0002b-SQLServer,inapplicable -RMLTC0002b-XML,passing -RMLTC0002c-CSV,passing -RMLTC0002c-JSON,passing +RMLTC0002b-XML,passed +RMLTC0002c-CSV,passed +RMLTC0002c-JSON,passed RMLTC0002c-MySQL,inapplicable RMLTC0002c-PostgreSQL,inapplicable RMLTC0002c-SQLServer,inapplicable -RMLTC0002c-XML,passing +RMLTC0002c-XML,passed RMLTC0002d-MySQL,inapplicable RMLTC0002d-PostgreSQL,inapplicable RMLTC0002d-SQLServer,inapplicable -RMLTC0002e-CSV,passing -RMLTC0002e-JSON,passing +RMLTC0002e-CSV,passed +RMLTC0002e-JSON,passed RMLTC0002e-MySQL,inapplicable RMLTC0002e-PostgreSQL,inapplicable RMLTC0002e-SQLServer,inapplicable -RMLTC0002e-XML,passing +RMLTC0002e-XML,passed RMLTC0002f-MySQL,inapplicable RMLTC0002f-PostgreSQL,inapplicable RMLTC0002f-SQLServer,inapplicable -RMLTC0002g-JSON,passing +RMLTC0002g-JSON,passed RMLTC0002g-MySQL,inapplicable RMLTC0002g-PostgreSQL,inapplicable RMLTC0002g-SPARQL,inapplicable @@ -73,214 +73,214 @@ RMLTC0003a-SQLServer,inapplicable RMLTC0003b-MySQL,inapplicable RMLTC0003b-PostgreSQL,inapplicable RMLTC0003b-SQLServer,inapplicable -RMLTC0003c-CSV,passing -RMLTC0003c-JSON,passing +RMLTC0003c-CSV,passed +RMLTC0003c-JSON,passed RMLTC0003c-MySQL,inapplicable RMLTC0003c-PostgreSQL,inapplicable RMLTC0003c-SPARQL,inapplicable RMLTC0003c-SQLServer,inapplicable -RMLTC0003c-XML,passing -RMLTC0004a-CSV,passing -RMLTC0004a-JSON,passing +RMLTC0003c-XML,passed +RMLTC0004a-CSV,passed +RMLTC0004a-JSON,passed RMLTC0004a-MySQL,inapplicable RMLTC0004a-PostgreSQL,inapplicable RMLTC0004a-SPARQL,inapplicable RMLTC0004a-SQLServer,inapplicable -RMLTC0004a-XML,passing -RMLTC0004b-CSV,passing -RMLTC0004b-JSON,passing +RMLTC0004a-XML,passed +RMLTC0004b-CSV,passed +RMLTC0004b-JSON,passed RMLTC0004b-MySQL,inapplicable RMLTC0004b-PostgreSQL,inapplicable RMLTC0004b-SPARQL,inapplicable RMLTC0004b-SQLServer,inapplicable -RMLTC0004b-XML,passing -RMLTC0005a-CSV,passing -RMLTC0005a-JSON,passing +RMLTC0004b-XML,passed +RMLTC0005a-CSV,passed +RMLTC0005a-JSON,passed RMLTC0005a-MySQL,inapplicable RMLTC0005a-PostgreSQL,inapplicable RMLTC0005a-SQLServer,inapplicable -RMLTC0005a-XML,passing +RMLTC0005a-XML,passed RMLTC0005b-MySQL,inapplicable RMLTC0005b-PostgreSQL,inapplicable RMLTC0005b-SQLServer,inapplicable -RMLTC0006a-CSV,passing -RMLTC0006a-JSON,passing +RMLTC0006a-CSV,passed +RMLTC0006a-JSON,passed RMLTC0006a-MySQL,inapplicable RMLTC0006a-PostgreSQL,inapplicable RMLTC0006a-SPARQL,inapplicable RMLTC0006a-SQLServer,inapplicable -RMLTC0006a-XML,passing -RMLTC0007a-CSV,passing -RMLTC0007a-JSON,passing +RMLTC0006a-XML,passed +RMLTC0007a-CSV,passed +RMLTC0007a-JSON,passed RMLTC0007a-MySQL,inapplicable RMLTC0007a-PostgreSQL,inapplicable RMLTC0007a-SPARQL,inapplicable RMLTC0007a-SQLServer,inapplicable -RMLTC0007a-XML,passing -RMLTC0007b-CSV,passing -RMLTC0007b-JSON,passing +RMLTC0007a-XML,passed +RMLTC0007b-CSV,passed +RMLTC0007b-JSON,passed RMLTC0007b-MySQL,inapplicable RMLTC0007b-PostgreSQL,inapplicable RMLTC0007b-SPARQL,inapplicable RMLTC0007b-SQLServer,inapplicable -RMLTC0007b-XML,passing -RMLTC0007c-CSV,passing -RMLTC0007c-JSON,passing +RMLTC0007b-XML,passed +RMLTC0007c-CSV,passed +RMLTC0007c-JSON,passed RMLTC0007c-MySQL,inapplicable RMLTC0007c-PostgreSQL,inapplicable RMLTC0007c-SPARQL,inapplicable RMLTC0007c-SQLServer,inapplicable -RMLTC0007c-XML,passing -RMLTC0007d-CSV,passing -RMLTC0007d-JSON,passing +RMLTC0007c-XML,passed +RMLTC0007d-CSV,passed +RMLTC0007d-JSON,passed RMLTC0007d-MySQL,inapplicable RMLTC0007d-PostgreSQL,inapplicable RMLTC0007d-SPARQL,inapplicable RMLTC0007d-SQLServer,inapplicable -RMLTC0007d-XML,passing -RMLTC0007e-CSV,passing -RMLTC0007e-JSON,passing +RMLTC0007d-XML,passed +RMLTC0007e-CSV,passed +RMLTC0007e-JSON,passed RMLTC0007e-MySQL,inapplicable RMLTC0007e-PostgreSQL,inapplicable RMLTC0007e-SPARQL,inapplicable RMLTC0007e-SQLServer,inapplicable -RMLTC0007e-XML,passing -RMLTC0007f-CSV,passing -RMLTC0007f-JSON,passing +RMLTC0007e-XML,passed +RMLTC0007f-CSV,passed +RMLTC0007f-JSON,passed RMLTC0007f-MySQL,inapplicable RMLTC0007f-PostgreSQL,inapplicable RMLTC0007f-SPARQL,inapplicable RMLTC0007f-SQLServer,inapplicable -RMLTC0007f-XML,passing -RMLTC0007g-CSV,passing -RMLTC0007g-JSON,passing +RMLTC0007f-XML,passed +RMLTC0007g-CSV,passed +RMLTC0007g-JSON,passed RMLTC0007g-MySQL,inapplicable RMLTC0007g-PostgreSQL,inapplicable RMLTC0007g-SPARQL,inapplicable RMLTC0007g-SQLServer,inapplicable -RMLTC0007g-XML,passing -RMLTC0007h-CSV,passing -RMLTC0007h-JSON,passing +RMLTC0007g-XML,passed +RMLTC0007h-CSV,passed +RMLTC0007h-JSON,passed RMLTC0007h-MySQL,inapplicable RMLTC0007h-PostgreSQL,inapplicable RMLTC0007h-SPARQL,inapplicable RMLTC0007h-SQLServer,inapplicable -RMLTC0007h-XML,passing -RMLTC0008a-CSV,passing -RMLTC0008a-JSON,passing +RMLTC0007h-XML,passed +RMLTC0008a-CSV,passed +RMLTC0008a-JSON,passed RMLTC0008a-MySQL,inapplicable RMLTC0008a-PostgreSQL,inapplicable RMLTC0008a-SPARQL,inapplicable RMLTC0008a-SQLServer,inapplicable -RMLTC0008a-XML,passing -RMLTC0008b-CSV,inapplicable -RMLTC0008b-JSON,inapplicable +RMLTC0008a-XML,passed +RMLTC0008b-CSV,passed +RMLTC0008b-JSON,passed RMLTC0008b-MySQL,inapplicable RMLTC0008b-PostgreSQL,inapplicable RMLTC0008b-SPARQL,inapplicable RMLTC0008b-SQLServer,inapplicable -RMLTC0008b-XML,inapplicable -RMLTC0008c-CSV,passing -RMLTC0008c-JSON,passing +RMLTC0008b-XML,passed +RMLTC0008c-CSV,passed +RMLTC0008c-JSON,passed RMLTC0008c-MySQL,inapplicable RMLTC0008c-PostgreSQL,inapplicable RMLTC0008c-SPARQL,inapplicable RMLTC0008c-SQLServer,inapplicable -RMLTC0008c-XML,passing -RMLTC0009a-CSV,inapplicable -RMLTC0009a-JSON,inapplicable +RMLTC0008c-XML,passed +RMLTC0009a-CSV,passed +RMLTC0009a-JSON,passed RMLTC0009a-MySQL,inapplicable RMLTC0009a-PostgreSQL,inapplicable RMLTC0009a-SPARQL,inapplicable RMLTC0009a-SQLServer,inapplicable -RMLTC0009a-XML,inapplicable -RMLTC0009b-CSV,inapplicable -RMLTC0009b-JSON,inapplicable +RMLTC0009a-XML,passed +RMLTC0009b-CSV,passed +RMLTC0009b-JSON,passed RMLTC0009b-MySQL,inapplicable RMLTC0009b-PostgreSQL,inapplicable RMLTC0009b-SPARQL,inapplicable RMLTC0009b-SQLServer,inapplicable -RMLTC0009b-XML,inapplicable +RMLTC0009b-XML,passed RMLTC0009c-MySQL,inapplicable RMLTC0009c-PostgreSQL,inapplicable RMLTC0009c-SQLServer,inapplicable RMLTC0009d-MySQL,inapplicable RMLTC0009d-PostgreSQL,inapplicable RMLTC0009d-SQLServer,inapplicable -RMLTC0010a-CSV,passing -RMLTC0010a-JSON,passing +RMLTC0010a-CSV,passed +RMLTC0010a-JSON,passed RMLTC0010a-MySQL,inapplicable RMLTC0010a-PostgreSQL,inapplicable RMLTC0010a-SQLServer,inapplicable -RMLTC0010b-CSV,passing -RMLTC0010b-JSON,passing +RMLTC0010b-CSV,passed +RMLTC0010b-JSON,passed RMLTC0010b-MySQL,inapplicable RMLTC0010b-PostgreSQL,inapplicable RMLTC0010b-SQLServer,inapplicable -RMLTC0010b-XML,passing -RMLTC0010c-CSV,inapplicable -RMLTC0010c-JSON,inapplicable +RMLTC0010b-XML,passed +RMLTC0010c-CSV,passed +RMLTC0010c-JSON,passed RMLTC0010c-MySQL,inapplicable RMLTC0010c-PostgreSQL,inapplicable RMLTC0010c-SQLServer,inapplicable -RMLTC0010c-XML,inapplicable +RMLTC0010c-XML,passed RMLTC0011a-MySQL,inapplicable RMLTC0011a-PostgreSQL,inapplicable RMLTC0011a-SQLServer,inapplicable -RMLTC0011b-CSV,passing -RMLTC0011b-JSON,passing +RMLTC0011b-CSV,passed +RMLTC0011b-JSON,passed RMLTC0011b-MySQL,inapplicable RMLTC0011b-PostgreSQL,inapplicable RMLTC0011b-SQLServer,inapplicable -RMLTC0011b-XML,passing -RMLTC0012a-CSV,passing -RMLTC0012a-JSON,passing +RMLTC0011b-XML,passed +RMLTC0012a-CSV,passed +RMLTC0012a-JSON,passed RMLTC0012a-MySQL,inapplicable RMLTC0012a-PostgreSQL,inapplicable RMLTC0012a-SPARQL,inapplicable RMLTC0012a-SQLServer,inapplicable -RMLTC0012a-XML,passing -RMLTC0012b-CSV,passing -RMLTC0012b-JSON,passing +RMLTC0012a-XML,passed +RMLTC0012b-CSV,passed +RMLTC0012b-JSON,passed RMLTC0012b-MySQL,inapplicable RMLTC0012b-PostgreSQL,inapplicable RMLTC0012b-SPARQL,inapplicable RMLTC0012b-SQLServer,inapplicable -RMLTC0012b-XML,passing -RMLTC0012c-CSV,passing -RMLTC0012c-JSON,passing +RMLTC0012b-XML,passed +RMLTC0012c-CSV,passed +RMLTC0012c-JSON,passed RMLTC0012c-MySQL,inapplicable RMLTC0012c-PostgreSQL,inapplicable RMLTC0012c-SQLServer,inapplicable -RMLTC0012c-XML,passing -RMLTC0012d-CSV,passing -RMLTC0012d-JSON,passing +RMLTC0012c-XML,passed +RMLTC0012d-CSV,passed +RMLTC0012d-JSON,passed RMLTC0012d-MySQL,inapplicable RMLTC0012d-PostgreSQL,inapplicable RMLTC0012d-SQLServer,inapplicable -RMLTC0012d-XML,passing +RMLTC0012d-XML,passed RMLTC0012e-MySQL,inapplicable RMLTC0012e-PostgreSQL,inapplicable RMLTC0012e-SQLServer,inapplicable -RMLTC0013a-JSON,passing +RMLTC0013a-JSON,passed RMLTC0013a-MySQL,inapplicable RMLTC0013a-PostgreSQL,inapplicable RMLTC0013a-SQLServer,inapplicable RMLTC0014d-MySQL,inapplicable RMLTC0014d-PostgreSQL,inapplicable RMLTC0014d-SQLServer,inapplicable -RMLTC0015a-CSV,passing -RMLTC0015a-JSON,passing +RMLTC0015a-CSV,passed +RMLTC0015a-JSON,passed RMLTC0015a-MySQL,inapplicable RMLTC0015a-PostgreSQL,inapplicable RMLTC0015a-SQLServer,inapplicable -RMLTC0015a-XML,passing -RMLTC0015b-CSV,passing -RMLTC0015b-JSON,passing +RMLTC0015a-XML,passed +RMLTC0015b-CSV,passed +RMLTC0015b-JSON,passed RMLTC0015b-MySQL,inapplicable RMLTC0015b-PostgreSQL,inapplicable RMLTC0015b-SQLServer,inapplicable -RMLTC0015b-XML,passing +RMLTC0015b-XML,passed RMLTC0016a-MySQL,inapplicable RMLTC0016a-PostgreSQL,inapplicable RMLTC0016a-SQLServer,inapplicable @@ -299,27 +299,27 @@ RMLTC0016e-SQLServer,inapplicable RMLTC0018a-MySQL,inapplicable RMLTC0018a-PostgreSQL,inapplicable RMLTC0018a-SQLServer,inapplicable -RMLTC0019a-CSV,passing -RMLTC0019a-JSON,passing +RMLTC0019a-CSV,passed +RMLTC0019a-JSON,passed RMLTC0019a-MySQL,inapplicable RMLTC0019a-PostgreSQL,inapplicable RMLTC0019a-SQLServer,inapplicable -RMLTC0019a-XML,passing -RMLTC0019b-CSV,passing -RMLTC0019b-JSON,passing +RMLTC0019a-XML,passed +RMLTC0019b-CSV,passed +RMLTC0019b-JSON,passed RMLTC0019b-MySQL,inapplicable RMLTC0019b-PostgreSQL,inapplicable RMLTC0019b-SQLServer,inapplicable -RMLTC0019b-XML,passing -RMLTC0020a-CSV,passing -RMLTC0020a-JSON,passing +RMLTC0019b-XML,passed +RMLTC0020a-CSV,passed +RMLTC0020a-JSON,passed RMLTC0020a-MySQL,inapplicable RMLTC0020a-PostgreSQL,inapplicable RMLTC0020a-SQLServer,inapplicable -RMLTC0020a-XML,passing -RMLTC0020b-CSV,passing -RMLTC0020b-JSON,passing +RMLTC0020a-XML,passed +RMLTC0020b-CSV,passed +RMLTC0020b-JSON,passed RMLTC0020b-MySQL,inapplicable RMLTC0020b-PostgreSQL,inapplicable RMLTC0020b-SQLServer,inapplicable -RMLTC0020b-XML,passing +RMLTC0020b-XML,passed From c88e2ac9aacf5c5af18fa1341f190dd6ac66b979 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 15:41:09 +0200 Subject: [PATCH 053/169] wip: function feature added bugs directory to passing --- src/test/scala/io/rml/framework/OutputGenerationTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index 4630fd05..c0301da2 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -75,7 +75,7 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour with "negative_test_cases" ) val passing : Array[Tuple2[String,String]] =Array( -// ("bugs","noopt"), + ("bugs","noopt"), ("rml-testcases","noopt"), ("fno-testcases", "noopt") ) From 20c1a6c2db8f05b603390bd5b9382f1d8243dd1b Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 17:01:03 +0200 Subject: [PATCH 054/169] wip: function feature -- preparing for merge with dev: cleaning + refactoring --- documentation/README_Functions.md | 4 +- .../core/function/FunctionLoader.scala | 41 +++++++------------ .../model/DynamicMethodFunction.scala | 2 +- .../core/function/std/StdFunctionLoader.scala | 15 +------ .../statement/ObjectGeneratorAssembler.scala | 2 - 5 files changed, 19 insertions(+), 45 deletions(-) diff --git a/documentation/README_Functions.md b/documentation/README_Functions.md index 3683683b..ee6792b9 100644 --- a/documentation/README_Functions.md +++ b/documentation/README_Functions.md @@ -68,7 +68,7 @@ grelm:uppercaseURLMapping . ``` -This mapping instructs the RML Streamer to look for a method called `toUpperCaseURL` within the `io.fno.idlab.IDLabFunctions`-class of the `IDLabFunctions.jar`. Make sure that the JAR-file is located in `main/resources`. +This mapping instructs the RML Streamer to look for a method called `toUpperCaseURL` within the `io.fno.idlab.IDLabFunctions`-class of the `IDLabFunctions.jar`. Make sure the JAR-file is located in `main/resources`. ## How the `FunctionLoader` works @@ -80,7 +80,7 @@ When no such file paths are provided, the default function descriptions are used Secondly, function URIs are mapped to the corresponding implementations by parsing the function mappings (e.g. `resources/grel_java_mapping.ttl` and `resources/idlab_java_mapping.ttl`). - During this step, every function URI is mapped to a `FunctionMetaData`-object which contains the necessary meta data such as: the *download-page* of the library, the *class-name* of the function, the *method-name*, *input parameters* and *output parameters*. + During this step, every function URI is mapped to a `FunctionMetaData`-object which contains the necessary metadata such as: the *download-page* of the library, the *class-name* of the function, the *method-name*, *input parameters* and *output parameters*. ## How the `FunctionLoader` is used diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index b7b3a765..c46cc91d 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -17,45 +17,34 @@ import scala.collection.mutable.{MutableList, Map => MutableMap} abstract class FunctionLoader extends Logging { /** - * Map string value of classes to library path - */ - protected val classLibraryMap: MutableMap[String, String] = MutableMap() - - /** - * Map names of [[Function]] to concrete [[Function]] object + * Map Function Uri to FunctionMetaData object */ protected val functionMap: MutableMap[Uri, FunctionMetaData] = MutableMap() - def getClassLibraryMap: ImmutableMap[String, String] = classLibraryMap.toMap - - def getFunctionMap = functionMap.toMap - - /** - * Given the [[Uri]] representation of the transformation, the [[FunctionLoader]] - * will search for the transformation in the [[functionMap]] and dynamically load - * the transformation. + * Searches for the given function uri in the function map and dynamically load + * that function, if present. * - * @param uri Uri representing a transformation - * @return [[Option]] of dynamically loaded transformation + * @param uri Function Uri + * @return [[Option]] of dynamically loaded function */ def loadFunction(uri: Uri): Option[Function] = { logDebug(s"loadFunction: ${uri.uri}") - val optFunction = functionMap.get(uri) - - if (optFunction.isDefined) { - val functionMetaData = optFunction.get + val optFunctionMetaData = functionMap.get(uri) + if (optFunctionMetaData.isDefined) { + val functionMetaData = optFunctionMetaData.get logDebug(s"Dynamically loading function: $uri, ${functionMetaData.toString}" ) - - functionMetaData match { - case functionMetaData: FunctionMetaData => Some(Function(functionMetaData.identifier, functionMetaData)) - case loadedFunction: DynamicMethodFunction => Some(loadedFunction) - case _ => throw new FnOException("Can't match the function meta data") - } + Some(Function(functionMetaData.identifier, functionMetaData)) +// optFunctionMetaData.get match { +// case functionMetaData: FunctionMetaData => Some(Function(functionMetaData.identifier, functionMetaData)) +// case loadedFunction: DynamicMethodFunction => Some(loadedFunction) +// case _ => throw new FnOException("Can't match the function meta data") +// } } else { + // when the function uri is not present in the function map, val availableFunctionURIs = functionMap.keys.map(u=>u.toString) throw new FnOException(s"The function with URI ${uri.toString} can not be found.\n" + s"The available function URIs are: " + availableFunctionURIs) diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala index 4f656d5c..7936c29d 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala @@ -29,7 +29,7 @@ case class DynamicMethodFunction(identifier: String, metaData: FunctionMetaData) if(optMethod.isEmpty) { logDebug("optMethod is empty -> loading method from jar %s".format(metaData.source)) - val jarFile = getClass.getClassLoader.getResource(metaData.source.toString).getFile + val jarFile = getClass.getClassLoader.getResource(metaData.source).getFile val classOfMethod = FunctionUtils.loadClassFromJar(new File(jarFile), metaData.className) val method = classOfMethod.getDeclaredMethod(metaData.methodName, metaData.inputParam.map(_.paramType): _*) diff --git a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala index d28253f9..b820f5ee 100644 --- a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala @@ -19,12 +19,6 @@ case class StdFunctionLoader(functionDescriptionTriplesGraph : RDFGraph) extends override def parseFunctionMapping(graph: RDFGraph): FunctionLoader = { logDebug("parsing functions the new way (i.e. using StdFunctionLoader)") - // a fnoi:Mapping - // property: fno:function - // property: fno:implementation - // an fno:implementation resource have type a like - // - fnoi:JavaClass - // val fnoFunctionProperty = Uri(RMLVoc.Property.FNO_FUNCTION) // subject resources with fno:function property @@ -74,13 +68,6 @@ case class StdFunctionLoader(functionDescriptionTriplesGraph : RDFGraph) extends case e@(_: RMLException | _: FnOException) => logError(e.getMessage) } - - } - - logDebug(s"${this.functionMap.size} functions are parsed. The function maps contains the following functions") - this.functionMap.foreach{ - kv => - logDebug(s"\t${kv._1}") } this } @@ -94,7 +81,7 @@ case class StdFunctionLoader(functionDescriptionTriplesGraph : RDFGraph) extends } override def parseParameter(inputNode: RDFNode, pos: Int): Parameter = { - val inputResource = inputNode.asInstanceOf[JenaResource] + val inputResource = inputNode.asInstanceOf[RDFResource] val paramType = inputResource.listProperties(RMLVoc.Property.FNO_TYPE).headOption val paramUri = inputResource.listProperties(RMLVoc.Property.FNO_PREDICATE).headOption diff --git a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala index adeb2487..baa8f4d9 100644 --- a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala @@ -45,8 +45,6 @@ class ObjectGeneratorAssembler extends TermMapGeneratorAssembler { termTypeString match { case RMLVoc.Class.IRI => item.map(iter => iter.map(elem => Uri(elem.toString))) case _ => item.map(iter => iter.flatMap(elem => { - //val castedResult = FunctionUtils.typeCastDataType(elem, objectMap.datatype) - //castedResult.map(v => Literal(v.toString, objectMap.datatype, objectMap.language)) Some(Literal(elem.identifier, objectMap.datatype, objectMap.language)) })) } From d20e31c978ffcdaae425394973ff8124e74f513b Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 17:42:10 +0200 Subject: [PATCH 055/169] wip: feature function: refactoring --- .../core/function/FunctionLoader.scala | 29 +++++-------------- ...odFunction.scala => DynamicFunction.scala} | 19 +++--------- .../core/function/model/Function.scala | 2 +- .../model/function/FunctionLoaderTest.scala | 2 +- 4 files changed, 14 insertions(+), 38 deletions(-) rename src/main/scala/io/rml/framework/core/function/model/{DynamicMethodFunction.scala => DynamicFunction.scala} (70%) diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index c46cc91d..eb0e3638 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -1,19 +1,16 @@ package io.rml.framework.core.function -import java.io.File +import java.io.{File, FileNotFoundException, IOException} import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.model.{DynamicMethodFunction, Function, FunctionMetaData, Parameter} +import io.rml.framework.core.function.model.{Function, FunctionMetaData, Parameter} import io.rml.framework.core.function.std.StdFunctionLoader import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode} import io.rml.framework.core.util.Turtle -import io.rml.framework.shared.{FnOException, RMLException} -import scala.collection.immutable.{Map => ImmutableMap} -import scala.collection.mutable -import scala.collection.mutable.{MutableList, Map => MutableMap} +import scala.collection.mutable.{Map => MutableMap} abstract class FunctionLoader extends Logging { /** @@ -37,16 +34,10 @@ abstract class FunctionLoader extends Logging { val functionMetaData = optFunctionMetaData.get logDebug(s"Dynamically loading function: $uri, ${functionMetaData.toString}" ) Some(Function(functionMetaData.identifier, functionMetaData)) -// optFunctionMetaData.get match { -// case functionMetaData: FunctionMetaData => Some(Function(functionMetaData.identifier, functionMetaData)) -// case loadedFunction: DynamicMethodFunction => Some(loadedFunction) -// case _ => throw new FnOException("Can't match the function meta data") -// } - } else { - // when the function uri is not present in the function map, + // when the function uri is not present in the function map, complain. val availableFunctionURIs = functionMap.keys.map(u=>u.toString) - throw new FnOException(s"The function with URI ${uri.toString} can not be found.\n" + + throw new IOException(s"The function with URI ${uri.toString} can not be found.\n" + s"The available function URIs are: " + availableFunctionURIs) } } @@ -82,17 +73,14 @@ abstract class FunctionLoader extends Logging { */ def parseParameter(rdfNode: RDFNode, pos: Int): Parameter - } object FunctionLoader extends Logging{ - private var singletonFunctionLoader : Option[FunctionLoader] = None private val defaultFunctionDescriptionFilePaths = List( "functions_grel.ttl" - ) /** @@ -103,7 +91,7 @@ object FunctionLoader extends Logging{ private def readFunctionDescriptionsFromFile(filePath : String): RDFGraph = { val functionDescriptionsFile = new File(getClass.getClassLoader.getResource(filePath).getFile) if (!functionDescriptionsFile.exists()) - throw new RMLException(s"Couldn't find ${functionDescriptionsFile.getName}") + throw new FileNotFoundException(s"Couldn't find ${functionDescriptionsFile.getName}") logDebug(s"FunctionLoader is reading function descriptions from : ${filePath}") RDFGraph.fromFile(functionDescriptionsFile, RMLEnvironment.getGeneratorBaseIRI(), Turtle) @@ -111,7 +99,7 @@ object FunctionLoader extends Logging{ /** * Construction of the (singleton) FunctionLoader instance. - * When the funcitonDescriptionFilePaths-list is empty, the default function descriptions are used. + * When the functionDescriptionFilePaths-list is empty, the default function descriptions are used. * @param functionDescriptionFilePaths filepaths to the function descriptions. Default value is an empty list. * @return FunctionLoader */ @@ -124,7 +112,6 @@ object FunctionLoader extends Logging{ // default function description files (i.e. defaultFunctionDescriptionFilePaths) val fdit = if(functionDescriptionFilePaths.isEmpty) defaultFunctionDescriptionFilePaths.iterator else functionDescriptionFilePaths.iterator - // construct the initial functionDescriptionTriplesGraph using the first functiondescription filepath val functionDescriptionsGraph : Option[RDFGraph] = if(fdit.hasNext) @@ -143,7 +130,7 @@ object FunctionLoader extends Logging{ if(functionDescriptionsGraph.isDefined) singletonFunctionLoader = Some(StdFunctionLoader(functionDescriptionsGraph.get)) else - throw new FnOException("No function description functionMappingGraph was created...") + throw new Exception("Function description graph is none...") } singletonFunctionLoader.get } diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala similarity index 70% rename from src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala rename to src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala index 7936c29d..e5198d98 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala @@ -8,13 +8,11 @@ import io.rml.framework.core.model.{Entity, Literal, Uri} /** - * A dynamic transformer which will use the functions of a class specified in an external jar - * The information needed to do reflection is contained inside the variable 'transientTransformation' of type [[FunctionMetaData]] - * - * @param identifier [[String]] used to identify this DynamicTransformation - * @param metaData contains information required for method reflection + * A dynamic function is loaded from an external jar at-runtime. + * @param identifier [[String]] used to identify this DynamicFunction + * @param metaData contains information required for loading, initializing the function */ -case class DynamicMethodFunction(identifier: String, metaData: FunctionMetaData) extends Function { +case class DynamicFunction(identifier: String, metaData: FunctionMetaData) extends Function { @transient private var optMethod: Option[Method] = None @@ -25,10 +23,7 @@ case class DynamicMethodFunction(identifier: String, metaData: FunctionMetaData) } override def initialize(): Function = { - logDebug("intializing function (identifier: %s)".format(this.identifier)) - if(optMethod.isEmpty) { - logDebug("optMethod is empty -> loading method from jar %s".format(metaData.source)) val jarFile = getClass.getClassLoader.getResource(metaData.source).getFile val classOfMethod = FunctionUtils.loadClassFromJar(new File(jarFile), metaData.className) @@ -44,15 +39,9 @@ case class DynamicMethodFunction(identifier: String, metaData: FunctionMetaData) in.defaultReadObject() optMethod = None initialize() - } override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { - logDebug("execute") - if (optMethod.isEmpty) { - throw new IllegalStateException(s"DynamicTransformation doesn't have the reflected method yet: ${this.identifier}") - } - val inputParams = metaData.inputParam // casted to List[AnyRef] since method.invoke(...) only accepts reference type but not primitive type of Scala val paramsOrdered = inputParams diff --git a/src/main/scala/io/rml/framework/core/function/model/Function.scala b/src/main/scala/io/rml/framework/core/function/model/Function.scala index 6373dea3..52a446a6 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Function.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Function.scala @@ -26,6 +26,6 @@ object Function extends Logging{ def apply(identifier:String, functionMetaData: FunctionMetaData): Function={ logDebug("Companion: Function - apply(identifier, functionMetaData)") - DynamicMethodFunction(identifier, functionMetaData) + DynamicFunction(identifier, functionMetaData) } } diff --git a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala index e04d1d75..26a798d3 100644 --- a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala +++ b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala @@ -4,7 +4,7 @@ import java.io.File import io.rml.framework.StaticTestSpec import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.model.{DynamicMethodFunction, Function} +import io.rml.framework.core.function.model.{DynamicFunction, Function} import io.rml.framework.core.function.std.StdFunctionLoader import io.rml.framework.core.function.{FunctionLoader, FunctionUtils} import io.rml.framework.core.model.Uri From 270d7a34fb5273259a449cc8cef47eea7f24a525 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 17:53:38 +0200 Subject: [PATCH 056/169] wip: feature function: refactoring --- .../io/rml/framework/api/RMLEnvironment.scala | 16 ++-------------- .../core/model/PredicateObjectMap.scala | 2 -- .../PredicateObjectGeneratorAssembler.scala | 5 +---- .../statement/SubjectGeneratorAssembler.scala | 2 -- 4 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala index 2d3278da..77a2034a 100644 --- a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala +++ b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala @@ -35,7 +35,7 @@ import scala.collection.mutable.{Map => MutableMap} object RMLEnvironment { - private val transformations: MutableMap[Uri, Transformation] = MutableMap() + private val sources: MutableMap[Uri, Iterable[Item]] = MutableMap() private var generatorBaseIRI: Option[String] = None private var mappingFileBaseIRI: Option[String] = None @@ -65,9 +65,6 @@ object RMLEnvironment { def executeTriplesMap(): Unit = ??? - def registerTransformation(transformation: Transformation): Unit = { - transformations.put(transformation.name, transformation) - } def registerSource(uri: Uri, iterable: Iterable[Item]): Unit = { require(sources.isEmpty, "Processing of only one source supported in API mode.") @@ -77,18 +74,9 @@ object RMLEnvironment { def getSource(uri: Uri): Option[Iterable[Item]] = { sources.get(uri) } - - def getTransformation(uri: Uri): Option[Transformation] = { - transformations.get(uri) - } - - def hasTransformationRegistered(uri: Uri): Boolean = { - transformations.contains(uri) - } - + def reset(): Unit = { sources.clear() - transformations.clear() } } diff --git a/src/main/scala/io/rml/framework/core/model/PredicateObjectMap.scala b/src/main/scala/io/rml/framework/core/model/PredicateObjectMap.scala index 6c1e3109..f4dc257e 100644 --- a/src/main/scala/io/rml/framework/core/model/PredicateObjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/PredicateObjectMap.scala @@ -43,8 +43,6 @@ import io.rml.framework.core.model.std.StdPredicateObjectMap trait PredicateObjectMap extends Node { def objectMaps: List[ObjectMap] - //def functionMaps: List[FunctionMap] - def predicateMaps: List[PredicateMap] def graphMap: Option[GraphMap] diff --git a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala index ad84b908..93b39b3a 100644 --- a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala @@ -31,7 +31,6 @@ import io.rml.framework.flink.item.Item import io.rml.framework.core.internal.Logging class PredicateObjectGeneratorAssembler(predicateGeneratorAssembler: PredicateGeneratorAssembler, objectGeneratorAssembler: ObjectGeneratorAssembler, - functionMapGeneratorAssembler: FunctionMapGeneratorAssembler, graphGeneratorAssembler: GraphGeneratorAssembler) extends Logging{ def assemble(predicateObjectMap: PredicateObjectMap) @@ -57,10 +56,8 @@ object PredicateObjectGeneratorAssembler { def apply( predicateGeneratorAssembler: PredicateGeneratorAssembler = PredicateGeneratorAssembler(), objectGeneratorAssembler: ObjectGeneratorAssembler = ObjectGeneratorAssembler(), - functionMapGeneratorAssembler: FunctionMapGeneratorAssembler = FunctionMapGeneratorAssembler(), graphGeneratorAssembler: GraphGeneratorAssembler = GraphGeneratorAssembler()) : PredicateObjectGeneratorAssembler = new PredicateObjectGeneratorAssembler(predicateGeneratorAssembler, - objectGeneratorAssembler, - functionMapGeneratorAssembler, graphGeneratorAssembler) + objectGeneratorAssembler, graphGeneratorAssembler) } diff --git a/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala index ef9a028f..25053311 100644 --- a/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala @@ -51,8 +51,6 @@ class SubjectGeneratorAssembler extends TermMapGeneratorAssembler { }) }else { - - /** * Tried implementing literal check in subject map extractor but it was assumed * that the extractor would just extract subject maps even if it is typed to be literal. From 7294b38d46f1ca097100309cfd4d680b394fd7cb Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 18:12:50 +0200 Subject: [PATCH 057/169] added FnO implementation report #91 --- .../resources/report/static-fno/result.csv | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/test/resources/report/static-fno/result.csv diff --git a/src/test/resources/report/static-fno/result.csv b/src/test/resources/report/static-fno/result.csv new file mode 100644 index 00000000..64c53797 --- /dev/null +++ b/src/test/resources/report/static-fno/result.csv @@ -0,0 +1,30 @@ +testid,result +RMLFNOTC0000-CSV,failed +RMLFNOTC0001-CSV,passed +RMLFNOTC0002-CSV,passed +RMLFNOTC0003-CSV,passed +RMLFNOTC0004-CSV,passed +RMLFNOTC0005-CSV,passed +RMLFNOTC0006-CSV,passed +RMLFNOTC0007-CSV,failed +RMLFNOTC0008-CSV,failed +RMLFNOTC0009-CSV,failed +RMLFNOTC0010-CSV,failed +RMLFNOTC0011-CSV,failed +RMLFNOTC0012-CSV,failed +RMLFNOTC0013-CSV,passed +RMLFNOTC0014-CSV,failed +RMLFNOTC0015-CSV,failed +RMLFNOTC0016-CSV,failed +RMLFNOTC0017-CSV,failed +RMLFNOTC0018-CSV,passed +RMLFNOTC0019-CSV,failed +RMLFNOTC0020-JSON,failed +RMLFNOTC0021-JSON,failed +RMLFNOTC0022-CSV,failed +RMLFNOTC0023-CSV,failed +RMLFNOTCA001,failed +RMLFNOTCA004,failed +RMLFNOTCA004b,failed +RMLFNOTCA005,failed +RMLFNOTCA006,failed From 538e3061daaebeb2d92aba4d2633f1c4743a3098 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 19:01:42 +0200 Subject: [PATCH 058/169] wip: feature function #25 - RMLFNOTCA004 working IDLabFunctions.jar: added method trueCondition functions_idlab.ttl + idlab_java_mapping: added function description + mapping for trueCondition method --- src/main/resources/IDLabFunctions.jar | Bin 2572 -> 2659 bytes src/main/resources/functions_idlab.ttl | 9 ++++ src/main/resources/idlab_java_mapping.ttl | 11 ++++ .../fno-testcases/RMLFNOTCA004/mapping.ttl | 48 ++++++++++++++++++ .../fno-testcases/RMLFNOTCA004/output.ttl | 1 + .../fno-testcases/RMLFNOTCA004/student.csv | 2 + 6 files changed, 71 insertions(+) create mode 100644 src/test/resources/fno-testcases/RMLFNOTCA004/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTCA004/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTCA004/student.csv diff --git a/src/main/resources/IDLabFunctions.jar b/src/main/resources/IDLabFunctions.jar index e3b7e8892f319899b7411382d10ff5c8d6894fad..eb9fcaee531f0e415e0e6bfba197f211fc72247f 100644 GIT binary patch delta 1490 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 diff --git a/src/main/resources/functions_idlab.ttl b/src/main/resources/functions_idlab.ttl index 450354e2..2ed50c1e 100644 --- a/src/main/resources/functions_idlab.ttl +++ b/src/main/resources/functions_idlab.ttl @@ -62,6 +62,15 @@ idlab-fn:toUpperCaseURL fno:returns ( idlab-fn:_stringOut ) . +idlab-fn:trueCondition + a fno:Function ; + fno:name "True condition" ; + rdfs:label "True condition" ; + dcterms:description "Returns the value if the given boolean is true, else null" ; + fno:expects ( idlab-fn:_strBoolean idlab-fn:_str ) ; + fno:returns ( idlab-fn:_stringOut ) . + + idlab-fn:_path a fno:Parameter ; fno:name "input path" ; diff --git a/src/main/resources/idlab_java_mapping.ttl b/src/main/resources/idlab_java_mapping.ttl index d05ddecf..25be1f8e 100644 --- a/src/main/resources/idlab_java_mapping.ttl +++ b/src/main/resources/idlab_java_mapping.ttl @@ -71,3 +71,14 @@ grelm:uppercaseURLMapping fnom:method-name "toUpperCaseURL" ] ; . +grelm:trueConditionMapping + a fno:Mapping ; + fno:function idlab-fn:trueCondition; + fno:implementation grelm:IDLabFunctions ; + fno:parameterMapping [ ] ; + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "trueCondition" ] ; +. + + diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTCA004/mapping.ttl new file mode 100644 index 00000000..9bb5550c --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTCA004/mapping.ttl @@ -0,0 +1,48 @@ +# test true condition + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:trueCondition ] + ]; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:strBoolean ; + rr:objectMap [ rr:constant "true"] + ] ; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] + ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004/output.ttl b/src/test/resources/fno-testcases/RMLFNOTCA004/output.ttl new file mode 100644 index 00000000..de68d8c0 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTCA004/output.ttl @@ -0,0 +1 @@ + "Venus". \ No newline at end of file diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004/student.csv b/src/test/resources/fno-testcases/RMLFNOTCA004/student.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTCA004/student.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A From 9762870474e767089c252b18483a7fa71b83f7e3 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 19:07:16 +0200 Subject: [PATCH 059/169] wip: feature function #25 - RMLFNOTCA004b working --- .../fno-testcases/RMLFNOTCA004b/mapping.ttl | 48 +++++++++++++++++++ .../fno-testcases/RMLFNOTCA004b/output.ttl | 0 .../fno-testcases/RMLFNOTCA004b/student.csv | 2 + 3 files changed, 50 insertions(+) create mode 100644 src/test/resources/fno-testcases/RMLFNOTCA004b/mapping.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTCA004b/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTCA004b/student.csv diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004b/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTCA004b/mapping.ttl new file mode 100644 index 00000000..7d22945c --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTCA004b/mapping.ttl @@ -0,0 +1,48 @@ +# test true condition + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:trueCondition ] + ]; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:strBoolean ; + rr:objectMap [ rr:constant "false"] + ] ; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] + ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004b/output.ttl b/src/test/resources/fno-testcases/RMLFNOTCA004b/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004b/student.csv b/src/test/resources/fno-testcases/RMLFNOTCA004b/student.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTCA004b/student.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A From ba60228af34166839316d5f0cf9e2dd5651780b7 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 18 Jun 2020 19:40:06 +0200 Subject: [PATCH 060/169] updated implementation report --- src/test/resources/report/static-fno/result.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/resources/report/static-fno/result.csv b/src/test/resources/report/static-fno/result.csv index 64c53797..b02e7b7d 100644 --- a/src/test/resources/report/static-fno/result.csv +++ b/src/test/resources/report/static-fno/result.csv @@ -24,7 +24,7 @@ RMLFNOTC0021-JSON,failed RMLFNOTC0022-CSV,failed RMLFNOTC0023-CSV,failed RMLFNOTCA001,failed -RMLFNOTCA004,failed -RMLFNOTCA004b,failed +RMLFNOTCA004,passed +RMLFNOTCA004b,passed RMLFNOTCA005,failed RMLFNOTCA006,failed From b50f56ffac6883c557d18bb7481fea2666326685 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Fri, 19 Jun 2020 08:54:01 +0200 Subject: [PATCH 061/169] update flink version for docker --- docker/docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 021210b1..667d6190 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: jobmanager: - image: flink:1.10.0-scala_2.11 + image: flink:1.10.1-scala_2.11 expose: - "6123" ports: @@ -14,7 +14,7 @@ services: - data:/mnt/data taskmanager: - image: flink:1.10.0-scala_2.11 + image: flink:1.10.1-scala_2.11 expose: - "6121" - "6122" From 87e02250779031259ab1ff4815dd15360adbc19c Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Fri, 19 Jun 2020 08:55:36 +0200 Subject: [PATCH 062/169] update flink version for docker --- docker/docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 021210b1..667d6190 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: jobmanager: - image: flink:1.10.0-scala_2.11 + image: flink:1.10.1-scala_2.11 expose: - "6123" ports: @@ -14,7 +14,7 @@ services: - data:/mnt/data taskmanager: - image: flink:1.10.0-scala_2.11 + image: flink:1.10.1-scala_2.11 expose: - "6121" - "6122" From 664936e6f76c9e38fc98175373ecb2cadec6c4c4 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 19 Jun 2020 12:22:19 +0200 Subject: [PATCH 063/169] wip: feature function - refactoring StdFunctionmapExtractor not used --- .../std/StdFunctionMappingExtractor.scala | 23 ------------------- 1 file changed, 23 deletions(-) delete mode 100644 src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala deleted file mode 100644 index 9b096fea..00000000 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala +++ /dev/null @@ -1,23 +0,0 @@ -package io.rml.framework.core.extractors.std - -import io.rml.framework.core.extractors.MappingExtractor -import io.rml.framework.core.function.FunctionLoader -import io.rml.framework.core.model.FunctionMapping -import io.rml.framework.core.model.rdf.RDFGraph - - -class StdFunctionMappingExtractor extends MappingExtractor[FunctionMapping] { - /** - * Extract. - * - * @param node Node to extract from. - * @return - */ - override def extract(node: RDFGraph): FunctionMapping = { - val loader = FunctionLoader() - - loader.parseFunctionMapping(node) - - FunctionMapping("defaulty", loader) - } -} From c9ca635cbda0fcd61d3c778e130e795e37efea58 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 19 Jun 2020 14:00:15 +0200 Subject: [PATCH 064/169] wip: refactoring deleted sandbox tests --- .../RMLFNOTC0000-CSV/mapping.ttl | 36 --------- .../RMLFNOTC0000-CSV/mapping_explicit.ttl | 37 --------- .../fno-testcases/RMLFNOTC0000-CSV/output.ttl | 1 - .../RMLFNOTC0001-CSV/mapping.ttl | 39 --------- .../RMLFNOTC0001-CSV/mapping_explicit.ttl | 40 ---------- .../fno-testcases/RMLFNOTC0001-CSV/output.ttl | 1 - .../RMLFNOTC0002-CSV/mapping.ttl | 39 --------- .../RMLFNOTC0003-CSV/mapping.ttl | 42 ---------- .../fno-testcases/RMLFNOTC0004-CSV/output.ttl | 1 - .../RMLFNOTC0005-CSV/mapping.ttl | 38 --------- .../fno-testcases/RMLFNOTC0005-CSV/output.ttl | 1 - .../RMLFNOTC0005-CSV/student.csv | 2 - .../fno-testcases/RMLFNOTC0006-CSV/output.nq | 1 - .../RMLFNOTC0007-CSV/mapping.ttl | 39 --------- .../fno-testcases/RMLFNOTC0007-CSV/output.ttl | 0 .../RMLFNOTC0008-CSV/mapping.ttl | 39 --------- .../fno-testcases/RMLFNOTC0008-CSV/output.ttl | 1 - .../RMLFNOTC0011-CSV/mapping.ttl | 40 ---------- .../fno-testcases/RMLFNOTC0011-CSV/output.ttl | 0 .../RMLFNOTC0012-CSV/mapping.ttl | 36 --------- .../fno-testcases/RMLFNOTC0012-CSV/output.ttl | 0 .../RMLFNOTC0013-CSV/mapping.ttl | 39 --------- .../fno-testcases/RMLFNOTC0013-CSV/output.ttl | 1 - .../RMLFNOTC0014-CSV/mapping.ttl | 38 --------- .../fno-testcases/RMLFNOTC0014-CSV/output.ttl | 1 - .../RMLFNOTC0015-CSV/mapping.ttl | 40 ---------- .../fno-testcases/RMLFNOTC0015-CSV/output.ttl | 1 - .../RMLFNOTC0016-CSV/mapping.ttl | 41 ---------- .../fno-testcases/RMLFNOTC0016-CSV/output.nq | 1 - .../fno-testcases/RMLFNOTC0018-CSV/data.csv | 2 - .../RMLFNOTC0018-CSV/mapping.ttl | 52 ------------ .../fno-testcases/RMLFNOTC0018-CSV/output.ttl | 1 - .../RMLFNOTC0021-JSON/books.json | 8 -- .../RMLFNOTC0021-JSON/mapping.ttl | 33 -------- .../RMLFNOTC0021-JSON/output.ttl | 7 -- .../sandbox/fno-testcases/student.csv | 2 - .../RMLTC0011b-CSV-small/mapping.ttl | 80 ------------------- .../RMLTC0011b-CSV-small/mapping.ttl.bak | 79 ------------------ .../RMLTC0011b-CSV-small/output.ttl | 4 - .../RMLTC0011b-CSV-small/sport.csv | 4 - .../RMLTC0011b-CSV-small/student.csv | 4 - .../RMLTC0011b-CSV-small/student_sport.csv | 5 -- .../rml-testcases/RMLTC0011b-CSV/mapping.ttl | 79 ------------------ .../RMLTC0011b-CSV/mapping.ttl.bak | 79 ------------------ .../rml-testcases/RMLTC0011b-CSV/output.ttl | 17 ---- .../rml-testcases/RMLTC0011b-CSV/sport.csv | 4 - .../rml-testcases/RMLTC0011b-CSV/student.csv | 4 - .../RMLTC0011b-CSV/student_sport.csv | 5 -- 48 files changed, 1064 deletions(-) delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/output.nq delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/output.nq delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/data.csv delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/books.json delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/output.ttl delete mode 100644 src/test/resources/sandbox/fno-testcases/student.csv delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl.bak delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/output.ttl delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/sport.csv delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student.csv delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student_sport.csv delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/output.ttl delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/sport.csv delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student.csv delete mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student_sport.csv diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl deleted file mode 100644 index 0c188516..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl +++ /dev/null @@ -1,36 +0,0 @@ -# Function on object, 0 parameters - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:random ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl deleted file mode 100644 index 9314fa88..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl +++ /dev/null @@ -1,37 +0,0 @@ -# Function on object, 0 parameters - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - a fnml:FunctionTermMap ; - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:random ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/output.ttl deleted file mode 100644 index f8633b11..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0000-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - "random" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl deleted file mode 100644 index e7a1c7bf..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl +++ /dev/null @@ -1,39 +0,0 @@ -# Function on object, 1 reference parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "Name" ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl deleted file mode 100644 index 78900620..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl +++ /dev/null @@ -1,40 +0,0 @@ -# Function on object, 1 reference parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - a fnml:FunctionTermMap ; - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "Name" ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/output.ttl deleted file mode 100644 index b0369690..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - "VENUS" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl deleted file mode 100644 index e2bd587c..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl +++ /dev/null @@ -1,39 +0,0 @@ -# Function on object, 1 constant parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rr:constant "name" ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl deleted file mode 100644 index 06823449..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl +++ /dev/null @@ -1,42 +0,0 @@ -# Function on object, 2 parameters - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:escape ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "Comment" ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:modeParameter ; - rr:objectMap [ rr:constant "html" ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/output.ttl deleted file mode 100644 index 4aa4759e..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl deleted file mode 100644 index 49423171..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl +++ /dev/null @@ -1,38 +0,0 @@ -# Function on predicate, 1 parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "url" ] ] - ] ; - rr:termType rr:IRI - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "Name"] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/output.ttl deleted file mode 100644 index 80493637..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - "Venus" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv deleted file mode 100644 index c33048c8..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0005-CSV/student.csv +++ /dev/null @@ -1,2 +0,0 @@ -Id,Name,url -1,Venus,www.example.com diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/output.nq b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/output.nq deleted file mode 100644 index 2258872a..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/output.nq +++ /dev/null @@ -1 +0,0 @@ - "Venus" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl deleted file mode 100644 index 2019aab7..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl +++ /dev/null @@ -1,39 +0,0 @@ -# Function on object, 1 false reference parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "WrongReference" ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0007-CSV/output.ttl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl deleted file mode 100644 index 4dff2794..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl +++ /dev/null @@ -1,39 +0,0 @@ -# Function on object, 1 template parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rr:template "Name: {Name}" ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/output.ttl deleted file mode 100644 index 9020be0f..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0008-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - "NAME: VENUS" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl deleted file mode 100644 index 68ac38aa..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl +++ /dev/null @@ -1,40 +0,0 @@ -# Function on object, 1 reference parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "Name" ] ] - ] ; - rr:datatype xsd:positiveInteger - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0011-CSV/output.ttl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl deleted file mode 100644 index 03a48120..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl +++ /dev/null @@ -1,36 +0,0 @@ -# Function on object returns null - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:generateNull ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0012-CSV/output.ttl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl deleted file mode 100644 index e0d25a62..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl +++ /dev/null @@ -1,39 +0,0 @@ -# Function on object returns empty string - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rr:constant "" ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/output.ttl deleted file mode 100644 index 6629e021..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0013-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - "" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl deleted file mode 100644 index 8e805fa2..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl +++ /dev/null @@ -1,38 +0,0 @@ -# Function on predicate, 1 parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "Name" ] ] - ] ; - rr:termType rr:IRI - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "Name"] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/output.ttl deleted file mode 100644 index 037f691d..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0014-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - "Venus" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl deleted file mode 100644 index 0c9872aa..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl +++ /dev/null @@ -1,40 +0,0 @@ -# Function on predicate, 1 parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "Name" ] ] - ] ; - rr:termType rr:IRI - ]; - rr:objectMap [ rr:constant foaf:name ; rr:termType rr:IRI ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/output.ttl deleted file mode 100644 index 4aa4759e..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0015-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl deleted file mode 100644 index 142874f1..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl +++ /dev/null @@ -1,41 +0,0 @@ -# Function on graph, 1 parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "Name"] ; - rr:graphMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "Name" ] ] - ] ; - rr:termType rr:IRI - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/output.nq b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/output.nq deleted file mode 100644 index 2258872a..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0016-CSV/output.nq +++ /dev/null @@ -1 +0,0 @@ - "Venus" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/data.csv b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/data.csv deleted file mode 100644 index 12614593..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/data.csv +++ /dev/null @@ -1,2 +0,0 @@ -id,name -0,ben & pieter \ No newline at end of file diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl deleted file mode 100644 index b1360640..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl +++ /dev/null @@ -1,52 +0,0 @@ -# Function on object, 1 reference parameter - -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/RMLFNOTC0018-CSV/data.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{id}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:escape ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ - fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCase ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "name" ] ] - ] - ] ; - ]; - rr:predicateObjectMap [ - rr:predicate grel:modeParameter ; - rr:objectMap [ rr:constant "html" ] ] - ] - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/output.ttl deleted file mode 100644 index 2296c1ec..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0018-CSV/output.ttl +++ /dev/null @@ -1 +0,0 @@ - "BEN & PIETER" . diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/books.json b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/books.json deleted file mode 100644 index 9856321f..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/books.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "books": [ - {"title": "The adventure of young turtle", "authors": ["John"]}, - {"title": "The big rabbit's trip", "authors": ["Edward", "Steve"]}, - {"title": "A new horizon at the end of the night", "authors": []}, - {"title": "The past comes back in the future"} - ] -} diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl deleted file mode 100644 index 79dc1b02..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl +++ /dev/null @@ -1,33 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix fnml: . -@prefix fno: . -@prefix grel: . -@prefix idlab-fn: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "fno-testcases/RMLFNOTC0021-JSON/books.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.books[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/book/{title}"; - rr:class ex:Book - ]; - - rr:predicateObjectMap [ - rr:predicate ex:writtenBy; - rr:objectMap [ - rml:reference "authors[*]" - ] - ]. diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/output.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/output.ttl deleted file mode 100644 index 445fac6f..00000000 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0021-JSON/output.ttl +++ /dev/null @@ -1,7 +0,0 @@ - . - "John" . - . - "Edward" . - "Steve" . - . - . diff --git a/src/test/resources/sandbox/fno-testcases/student.csv b/src/test/resources/sandbox/fno-testcases/student.csv deleted file mode 100644 index 052b9915..00000000 --- a/src/test/resources/sandbox/fno-testcases/student.csv +++ /dev/null @@ -1,2 +0,0 @@ -Id,Name,Comment,Class -1,Venus,A&B,A diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl deleted file mode 100644 index 964e6d31..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl +++ /dev/null @@ -1,80 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - -# -# a rr:TriplesMap; - -# rml:logicalSource [ -# rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; -# rml:referenceFormulation ql:CSV -# ]; - -# rr:subjectMap [ -# rr:template "http://example.com/student/{ID}"; -# ]; - -# rr:predicateObjectMap [ -# rr:predicate ex:firstName; -# rr:objectMap [ -# rml:reference "FirstName" -# ] -# ]; - -# rr:predicateObjectMap [ -# rr:predicate ex:lastName; -# rr:objectMap [ -# rml:reference "LastName" -# ] -# ]. - -# -# a rr:TriplesMap; - -# rml:logicalSource [ -# rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; -# rml:referenceFormulation ql:CSV -# ]; - -# rr:subjectMap [ -# rr:template "http://example.com/sport/{ID}"; -# ]; - -# rr:predicateObjectMap [ -# rr:predicate ex:id; -# rr:objectMap [ -# rml:reference "ID" -# ] -# ]; - -# rr:predicateObjectMap [ -# rr:predicate ex:description; -# rr:objectMap [ -# rml:reference "Description" -# ] -# ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID_Student}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:plays; - rr:objectMap [ - rr:template "http://example.com/sport/{ID_Sport}"; - - ] - ]. diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl.bak b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl.bak deleted file mode 100644 index 7021f6f4..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl.bak +++ /dev/null @@ -1,79 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:firstName; - rr:objectMap [ - rml:reference "FirstName" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:lastName; - rr:objectMap [ - rml:reference "LastName" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/sport/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id; - rr:objectMap [ - rml:reference "ID" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:description; - rr:objectMap [ - rml:reference "Description" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID_Student}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:plays; - rr:objectMap [ - rr:template "http://example.com/sport/{ID_Sport}" - ] - ]. diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/output.ttl b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/output.ttl deleted file mode 100644 index 7754ec89..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/output.ttl +++ /dev/null @@ -1,4 +0,0 @@ - . - . - . - . diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/sport.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/sport.csv deleted file mode 100644 index 98446d06..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/sport.csv +++ /dev/null @@ -1,4 +0,0 @@ -ID,Description -110,Tennis -111,Football -112,Formula1 diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student.csv deleted file mode 100644 index acf08c28..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student.csv +++ /dev/null @@ -1,4 +0,0 @@ -ID,FirstName,LastName -10,Venus,Williams -11,Fernando,Alonso -12,David,Villa diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student_sport.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student_sport.csv deleted file mode 100644 index 381e9213..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student_sport.csv +++ /dev/null @@ -1,5 +0,0 @@ -ID_Student,ID_Sport -10,110 -11,111 -11,112 -12,111 diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl deleted file mode 100644 index 7021f6f4..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl +++ /dev/null @@ -1,79 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:firstName; - rr:objectMap [ - rml:reference "FirstName" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:lastName; - rr:objectMap [ - rml:reference "LastName" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/sport/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id; - rr:objectMap [ - rml:reference "ID" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:description; - rr:objectMap [ - rml:reference "Description" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID_Student}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:plays; - rr:objectMap [ - rr:template "http://example.com/sport/{ID_Sport}" - ] - ]. diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak deleted file mode 100644 index 7021f6f4..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak +++ /dev/null @@ -1,79 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:firstName; - rr:objectMap [ - rml:reference "FirstName" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:lastName; - rr:objectMap [ - rml:reference "LastName" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/sport/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id; - rr:objectMap [ - rml:reference "ID" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:description; - rr:objectMap [ - rml:reference "Description" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID_Student}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:plays; - rr:objectMap [ - rr:template "http://example.com/sport/{ID_Sport}" - ] - ]. diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/output.ttl b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/output.ttl deleted file mode 100644 index d2759cec..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/output.ttl +++ /dev/null @@ -1,17 +0,0 @@ - "Williams" . - "Venus" . - "Villa" . - "David" . - "Alonso" . - "Fernando" . - "Tennis" . - "110" . - "Football" . - "111" . - "Formula1" . - "112" . - . - . - . - . - diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/sport.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/sport.csv deleted file mode 100644 index 98446d06..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/sport.csv +++ /dev/null @@ -1,4 +0,0 @@ -ID,Description -110,Tennis -111,Football -112,Formula1 diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student.csv deleted file mode 100644 index acf08c28..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student.csv +++ /dev/null @@ -1,4 +0,0 @@ -ID,FirstName,LastName -10,Venus,Williams -11,Fernando,Alonso -12,David,Villa diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student_sport.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student_sport.csv deleted file mode 100644 index 381e9213..00000000 --- a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student_sport.csv +++ /dev/null @@ -1,5 +0,0 @@ -ID_Student,ID_Sport -10,110 -11,111 -11,112 -12,111 From 3cabbddfbf675cf47f500b2739988941fac85877 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 19 Jun 2020 14:34:23 +0200 Subject: [PATCH 065/169] wip: feature function - sandbox: equal & not equal --- src/main/resources/IDLabFunctions.jar | Bin 2659 -> 3237 bytes src/main/resources/functions_idlab.ttl | 15 +++++++++ src/main/resources/idlab_java_mapping.ttl | 22 +++++++++++++ .../equal}/mapping.ttl | 22 +++++++++---- .../sandbox/function_related/equal/output.nq | 1 + .../notEqual}/mapping.ttl | 31 +++++++++++------- .../function_related/notEqual/output.nq | 1 + .../scala/io/rml/framework/SandboxTests.scala | 13 ++++++++ 8 files changed, 87 insertions(+), 18 deletions(-) rename src/test/resources/sandbox/{fno-testcases/RMLFNOTC0006-CSV => function_related/equal}/mapping.ttl (72%) create mode 100644 src/test/resources/sandbox/function_related/equal/output.nq rename src/test/resources/sandbox/{fno-testcases/RMLFNOTC0004-CSV => function_related/notEqual}/mapping.ttl (58%) create mode 100644 src/test/resources/sandbox/function_related/notEqual/output.nq diff --git a/src/main/resources/IDLabFunctions.jar b/src/main/resources/IDLabFunctions.jar index eb9fcaee531f0e415e0e6bfba197f211fc72247f..9461a502c2c4b72b4f145d69a4cf15ed90a6b11b 100644 GIT binary patch delta 2156 zcmZWq3pf*M1Kw(c zkE2U72Uky*#rgv!6zCP^5%DW|>nr2t&9_>oWImsV%$ z7@^nqL@NjKkkX!-LW6ubI&-T8liem{EVi(waqhyiMoC6y!R`BwDlL&(8)OQO*topI zO3?U$IhvRXu0MUQvatJ37WtsDQc02>o8oR@H_!Lii(7<(Rio<8(w)=JZ0o!XYHvvoCCkkMa#G}d@ii+zxIL7Z?lc{k*JSkwkpd7N?5P$ z_>0_sUuJrlCFK&dXE>Tpk5-8LaTz*=q=@^QawE7SLuc8*1>{Vh==~2{(<0{w3EakfUQ{PG3_>S~Y&Hhmg-<5{Regom>H+ivu@ zaivE?tYrMIe*g3A^$MPTkA@toOUt;%_8!ttnvoW4rj*any~uylbB3@TVT0~2g{VrL zVx}qOXNWVJTZ7@I9h7k2Gj_=tjI?oOIQ9}(?2qlW7movrRs>l5FHTYITi0 zji=5w@j9TU6Ec#QU_vr0DCfd-{4Xpn%J2|+S7m({p9DFC*aq+z1ObDe`aN8{`D^yD z$ep?{fA4E{1p15GLQ&~(ct3Wwr?kSO{4tVk$h)V&F2|lNiBPpz6Wlixe0HTjwsrhe zQ>9MdKT`*18g}#I50@o8I8V$BeDH|IGLQGk9jfk_tl>Mz#psNhO%J$7e=1HcSDa)e zt9-g^mmmUTPN4DigZkEnMJB(WmtK)Z$DJ<2&OlU_fEj)ZVx~(4+Rcni@7b0&(P?v8 zjf;Tq=Sa-8GHH{bSgsK>|Cd(IIzV9!*CKd8Vzi z4oYr%U5JRmWrj>30}suFN!yakQfD%JL_SuQc9yx{7Hn?34dv+zPqQNE%cl{2vG5@a z?N(O0Kx=g2@|mhhLd!|kZCa!6oU+_BGecTIBr#>`4RZ7b`OQ0m*ViiWIZrK;SVJ;# zR#Ouw!_|3GnsTIlT4RL&Ls>;FVS%o+L>3+k)3lseUn^@Icmh0}nNSqfdQjLN z{#99y+pPb|G4gt+@s+~V7W{Zjf-o%K{BnG%qPjzK4I!H+KN8hR8*;LjyU~;_KjT@} zhD=( zGE4nxC6D@Zyl=m8!j1gij(LMie^JoZ4hy=P?BY;M5=s7KlTKTH`QJts0N|8@cY-$T zlhX#qZs97JAlI;Am95)ctAc<4Km-T?z;On_J2-0M2+ngUNm>f~NN5rU-ue8CLUN2} zm=|BUa;z;IJ$UA2{kyyMh@gB_FmQFjLt0FJl5%!2Ui4PPBF=T1ecV%u=lUtOYe3_6 zrxkk_-)qdVuXvc(}`h1n~CZ2U^}#sP-UIWVO6HJ`UXA zkTP>)_)XOZX&3$mb95OmR>`%s2=Xp+0ZcI&Hk<2s_pv_m&qrh5R;ePz@F#UrbQWku zO=I;ao7ls@9U$LzYCA>l<4%1y{@y9wm-6Li#OW_n{Zxxja&8I+XwA*ki1e|GR#KwdN#hUoiwXKQwfRLC0g(9O*+je z;uC4O3l#w>X}!`s>F`)@aV5mVZ7EvYByCxT`8?U^Is* zaf}wdr^j_kug?Wj=ZeAC$I1FxDkBHXm?;W^f^u%xkwh|!&Sy_^O zVQ0`|fLFIl6w^y&5L?r10(~D=2yWf;%&7rt}D8$VM}q+VPpdz6004>;*EiPV3@E|p h{!RJkC8IZ%#%xrRpD2wGj-xo1V-4LYks`G@^B+7QttS8g delta 1521 zcmZ1~`B;QEz?+$civa{8rd^uItHK-(q)ZktH+o;1cwG)m{ZIl4PL^fV5CYNxdJCD& z_?a0PSlJjD6d5L;=2EWj4T<&_4ixyum$Q4Rj`-KihkXw>`b(lrwpzrE&4I*|%@rudn~ZWYAk8 z5iY==sMAyE!(k-Z)}`sVY<3~LvC+FWL8q7r)rohGGb`HiJPhR6{AkXEdPDWchRy}& zHt>|sTWBbCJ88nCvOeQ2nQceI_c*m#OIICJ@paj}dDqUR)@>HyQzy+f_u^rmmAHEM zw6#)}!RJ?;?w&O-^3$3%**C&84_RGQ>f zx!dKSgzC92o?27K>m}Ep_PMTG6L9`rb5Z*n-F1&YF3Ek$6R36guvO{b^rbq71^jN$ zoBY(f?M3eKn`VAp)?7+25?)kEpWU6e@k?P=&9BRARvlY3`Qwd_o=R5#4KHU3b%5iTTk!PVr2c4~=ms21M~NBxg#Umj+C{Ura1Pw0N1NsaSjGckQ< zuioi`KYFZ>G-(UhUn)PrJ7cOElc?ec;e~IVO}=`jw)|#FH4)Z#wp{T_S+}Hb{)&EK zsb&5O0%|+bygU~EiPoHJwtt;P=r#wbiEnHwzf4*te|^Oz#b5jntW++2Nt&>v!9(2K zL&$a6NjsmT8XgbT+&ETqZa0Y1&F?(Ndqi1jp+~l4?tI1m+QuV%=afvdjvRltuHx}F z`B)Do_b=wJejoqGh?27=C$MQT19RBqUN%E8eUQyfaPHJg0gJRUmVO21zIBWY3`UdB zv+30rI8k`C$ssFqsmPJ48+os^HY(rt{q)&$ z?lvvvN85IP-@E&A^68Dam*Onfuhk6nGn%5MyynU>y^F`+vDzQnW!AxUtx1BN;~wkrTW3er(Ud&G%DV@ zdHFlvqTJ4GX}9%%*EDfg@hiCpXP|H=R2tp`a$b#u)!7vC2iqgZRTRu z^y?1WOFTbQoc~O~hMVtZQ8}q`FB9+7$0=yZSM3~_PVF0*9gc6)Udh$|EWpF8Y zn$sRsC{E_((gV|WTt;B=VlE3l)Y5VCPA*4qRR86YX6j^_EX6Gg=2~$}Gi_s;e1T13 zay~Z?Sf~yt^a>=TKlv0lmjXt*KyuBJMq^f>Lfy%VJi-d_AOb2V2VzSUg%xaIg^fIN JY|iW;836d*m&X7A diff --git a/src/main/resources/functions_idlab.ttl b/src/main/resources/functions_idlab.ttl index 2ed50c1e..78885c4b 100644 --- a/src/main/resources/functions_idlab.ttl +++ b/src/main/resources/functions_idlab.ttl @@ -70,6 +70,21 @@ idlab-fn:trueCondition fno:expects ( idlab-fn:_strBoolean idlab-fn:_str ) ; fno:returns ( idlab-fn:_stringOut ) . +idlab-fn:equal + a fno:Function ; + fno:name "equal" ; + rdfs:label "equal" ; + dcterms:description "Returns true if strings are equal." ; + fno:expects ( grel:valueParam grel:valueParam2 ) ; + fno:returns ( grel:stringOut ) . + +idlab-fn:notEqual + a fno:Function ; + fno:name "not equal" ; + rdfs:label "not equal" ; + dcterms:description "Returns true if strings are not equal." ; + fno:expects ( grel:valueParam grel:valueParam2 ) ; + fno:returns ( grel:stringOut ) . idlab-fn:_path a fno:Parameter ; diff --git a/src/main/resources/idlab_java_mapping.ttl b/src/main/resources/idlab_java_mapping.ttl index 25be1f8e..a835998e 100644 --- a/src/main/resources/idlab_java_mapping.ttl +++ b/src/main/resources/idlab_java_mapping.ttl @@ -82,3 +82,25 @@ grelm:trueConditionMapping . +grelm:equalMapping + a fno:Mapping ; + fno:function idlab-fn:equal; + fno:implementation grelm:IDLabFunctions ; + fno:parameterMapping [ ] ; + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "equal" ] ; +. + + +grelm:notEqualMapping + a fno:Mapping ; + fno:function idlab-fn:notEqual; + fno:implementation grelm:IDLabFunctions ; + fno:parameterMapping [ ] ; + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "notEqual" ] ; +. + + diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/sandbox/function_related/equal/mapping.ttl similarity index 72% rename from src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl rename to src/test/resources/sandbox/function_related/equal/mapping.ttl index bfff3dcc..668fdcff 100644 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl +++ b/src/test/resources/sandbox/function_related/equal/mapping.ttl @@ -8,6 +8,7 @@ @prefix ql: . @prefix fnml: . @prefix fno: . +@prefix idlab-fn: . @prefix grel: . @base . @@ -25,17 +26,24 @@ ]; rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "Name"] ; - rr:graphMap [ + rr:predicate ex:isEqual; + rr:objectMap [ fnml:functionValue [ rr:predicateObjectMap [ rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; + rr:objectMap [ rr:constant idlab-fn:equal ] ] ; + rr:predicateObjectMap [ rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "Name" ] ] + rr:objectMap [ rml:reference "Name" ] ]; + + rr:predicateObjectMap [ + rr:predicate grel:valueParameter2 ; + rr:objectMap [ rr:constant "Venus" ] ] + ] ; - rr:termType rr:IRI - ] + + + ] ; + ]. diff --git a/src/test/resources/sandbox/function_related/equal/output.nq b/src/test/resources/sandbox/function_related/equal/output.nq new file mode 100644 index 00000000..d031e746 --- /dev/null +++ b/src/test/resources/sandbox/function_related/equal/output.nq @@ -0,0 +1 @@ + "true" . \ No newline at end of file diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/sandbox/function_related/notEqual/mapping.ttl similarity index 58% rename from src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl rename to src/test/resources/sandbox/function_related/notEqual/mapping.ttl index 4901ced9..f8ee063a 100644 --- a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl +++ b/src/test/resources/sandbox/function_related/notEqual/mapping.ttl @@ -1,4 +1,4 @@ -# Function on predicate, 1 parameter +# Function on graph, 1 parameter @prefix rr: . @prefix foaf: . @@ -8,6 +8,7 @@ @prefix ql: . @prefix fnml: . @prefix fno: . +@prefix idlab-fn: . @prefix grel: . @base . @@ -25,16 +26,24 @@ ]; rr:predicateObjectMap [ - rr:predicateMap [ + rr:predicate ex:isNotEqual; + rr:objectMap [ fnml:functionValue [ - rr:predicateObjectMap [ - rr:predicate fno:executes ; - rr:objectMap [ rr:constant grel:toUpperCaseURL ] ] ; - rr:predicateObjectMap [ - rr:predicate grel:valueParameter ; - rr:objectMap [ rml:reference "Name" ] ] + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:notEqual ] ] ; + + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ]; + + rr:predicateObjectMap [ + rr:predicate grel:valueParameter2 ; + rr:objectMap [ rr:constant "notVENUS" ] ] + ] ; - rr:termType rr:IRI - ]; - rr:objectMap [ rr:constant foaf:name ; rr:termType rr:IRI ] + + + ] ; + ]. diff --git a/src/test/resources/sandbox/function_related/notEqual/output.nq b/src/test/resources/sandbox/function_related/notEqual/output.nq new file mode 100644 index 00000000..3537f9a8 --- /dev/null +++ b/src/test/resources/sandbox/function_related/notEqual/output.nq @@ -0,0 +1 @@ + "true" . \ No newline at end of file diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 74c688f4..d8edf64f 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -92,6 +92,19 @@ class SandboxTests extends FunSuite with Matchers { } } } + + // Example + test("sandbox/function_related/equal") { + + executeTest("sandbox/function_related/equal/mapping.ttl") + } + + + + test("sandbox/function_related/notEqual") { + + executeTest("sandbox/function_related/notEqual/mapping.ttl") + } // Example // test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { // pending From 88d3c524ef040150b4abe42ed3e2c466cac91c2d Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 19 Jun 2020 19:36:30 +0200 Subject: [PATCH 066/169] wip: feature function: grel:contains works --- .../core/function/model/Parameter.scala | 3 ++ .../function_related/contains/mapping.ttl | 49 +++++++++++++++++++ .../function_related/contains/output.nq | 1 + .../scala/io/rml/framework/SandboxTests.scala | 16 +++--- 4 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 src/test/resources/sandbox/function_related/contains/mapping.ttl create mode 100644 src/test/resources/sandbox/function_related/contains/output.nq diff --git a/src/main/scala/io/rml/framework/core/function/model/Parameter.scala b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala index b8b6279a..79db9b14 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Parameter.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala @@ -50,8 +50,11 @@ abstract class Parameter extends Node { val DoubleString = classOf[Double].getName val ListString = classOf[List[_]].getName val ArrayString = classOf[Array[_]].getName + + val BooleanString = classOf[Boolean].getName try { paramType.getName match { + case BooleanString |"boolean" => Some(paraValue) case ScalaString | "java.lang.String" => Some(paraValue.toString) case IntegerString | "int" => Some(paraValue.toString.toInt) case DoubleString | "double" => Some(paraValue.toString.toDouble) diff --git a/src/test/resources/sandbox/function_related/contains/mapping.ttl b/src/test/resources/sandbox/function_related/contains/mapping.ttl new file mode 100644 index 00000000..b216cd68 --- /dev/null +++ b/src/test/resources/sandbox/function_related/contains/mapping.ttl @@ -0,0 +1,49 @@ +# Function on graph, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix idlab-fn: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate ex:contains_us; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:string_contains ] ] ; + + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ]; + + rr:predicateObjectMap [ + rr:predicate grel:string_sub ; + rr:objectMap [ rr:constant "us" ] ] + + ] ; + + + ] ; + + ]. diff --git a/src/test/resources/sandbox/function_related/contains/output.nq b/src/test/resources/sandbox/function_related/contains/output.nq new file mode 100644 index 00000000..5c813d81 --- /dev/null +++ b/src/test/resources/sandbox/function_related/contains/output.nq @@ -0,0 +1 @@ + "true" . \ No newline at end of file diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index d8edf64f..231a47b4 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -93,23 +93,19 @@ class SandboxTests extends FunSuite with Matchers { } } - // Example - test("sandbox/function_related/equal") { + test("sandbox/function_related/equal") { executeTest("sandbox/function_related/equal/mapping.ttl") } - - test("sandbox/function_related/notEqual") { - executeTest("sandbox/function_related/notEqual/mapping.ttl") } - // Example -// test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { -// pending -// executeTest("sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl") -// } + + test("sandbox/function_related/contains") { + executeTest("sandbox/function_related/contains/mapping.ttl") + } + From dfc33ac81a250a427b6eafb30aa3da313f80c88c Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 19 Jun 2020 20:35:28 +0200 Subject: [PATCH 067/169] equal and not equal using different student data --- src/test/resources/sandbox/function_related/equal/mapping.ttl | 2 +- src/test/resources/sandbox/function_related/equal/output.nq | 3 ++- .../resources/sandbox/function_related/notEqual/mapping.ttl | 4 ++-- .../resources/sandbox/function_related/notEqual/output.nq | 3 ++- src/test/resources/sandbox/function_related/student.csv | 3 +++ 5 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 src/test/resources/sandbox/function_related/student.csv diff --git a/src/test/resources/sandbox/function_related/equal/mapping.ttl b/src/test/resources/sandbox/function_related/equal/mapping.ttl index 668fdcff..1404099b 100644 --- a/src/test/resources/sandbox/function_related/equal/mapping.ttl +++ b/src/test/resources/sandbox/function_related/equal/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "sandbox/function_related/student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/function_related/equal/output.nq b/src/test/resources/sandbox/function_related/equal/output.nq index d031e746..995fc00c 100644 --- a/src/test/resources/sandbox/function_related/equal/output.nq +++ b/src/test/resources/sandbox/function_related/equal/output.nq @@ -1 +1,2 @@ - "true" . \ No newline at end of file + "true". + "false". \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/notEqual/mapping.ttl b/src/test/resources/sandbox/function_related/notEqual/mapping.ttl index f8ee063a..72420105 100644 --- a/src/test/resources/sandbox/function_related/notEqual/mapping.ttl +++ b/src/test/resources/sandbox/function_related/notEqual/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "sandbox/function_related/student.csv"; rml:referenceFormulation ql:CSV ]; @@ -39,7 +39,7 @@ rr:predicateObjectMap [ rr:predicate grel:valueParameter2 ; - rr:objectMap [ rr:constant "notVENUS" ] ] + rr:objectMap [ rr:constant "Venus" ] ] ] ; diff --git a/src/test/resources/sandbox/function_related/notEqual/output.nq b/src/test/resources/sandbox/function_related/notEqual/output.nq index 3537f9a8..caa1c8fe 100644 --- a/src/test/resources/sandbox/function_related/notEqual/output.nq +++ b/src/test/resources/sandbox/function_related/notEqual/output.nq @@ -1 +1,2 @@ - "true" . \ No newline at end of file + "false". + "true". \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/student.csv b/src/test/resources/sandbox/function_related/student.csv new file mode 100644 index 00000000..fdc5dc5c --- /dev/null +++ b/src/test/resources/sandbox/function_related/student.csv @@ -0,0 +1,3 @@ +Id,Name,Comment,Class +1,Venus,A&B,A +2,Algebra,NoComment,B From 1765836e7c273b02bc55b0989529d6f87dc15843 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 19 Jun 2020 20:55:18 +0200 Subject: [PATCH 068/169] wip: feature function generate triple when true condition (equal) is met --- .../using_trueCondition_and_equal/mapping.ttl | 67 +++++++++++++++++++ .../using_trueCondition_and_equal/output.ttl | 1 + .../using_trueCondition_and_equal/student.csv | 2 + .../scala/io/rml/framework/SandboxTests.scala | 3 + 4 files changed, 73 insertions(+) create mode 100644 src/test/resources/sandbox/function_related/using_trueCondition_and_equal/mapping.ttl create mode 100644 src/test/resources/sandbox/function_related/using_trueCondition_and_equal/output.ttl create mode 100644 src/test/resources/sandbox/function_related/using_trueCondition_and_equal/student.csv diff --git a/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/mapping.ttl b/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/mapping.ttl new file mode 100644 index 00000000..1ca5a8ba --- /dev/null +++ b/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/mapping.ttl @@ -0,0 +1,67 @@ +# generate triples using trueCondition and Equal + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "sandbox/function_related/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:trueCondition ] + ]; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:strBoolean ; + rr:objectMap + ] ; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] + ] + ] + ] + ]. + + + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:equal ] + ]; + + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:constant "Venus"] + ] ; + + rr:predicateObjectMap [ + rr:predicate grel:valueParameter2 ; + rr:objectMap [ rml:reference "Name" ] + ] + ] +. \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/output.ttl b/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/output.ttl new file mode 100644 index 00000000..8d800662 --- /dev/null +++ b/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/output.ttl @@ -0,0 +1 @@ + "Venus". diff --git a/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/student.csv b/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/student.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/student.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 231a47b4..958f4574 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -106,6 +106,9 @@ class SandboxTests extends FunSuite with Matchers { executeTest("sandbox/function_related/contains/mapping.ttl") } + test("sandbox/function_related/using_trueCondition_and_equal") { + executeTest("sandbox/function_related/using_trueCondition_and_equal/mapping.ttl") + } From 52c0fe25b37a0885bbd3a0c8acfb470591dc4560 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 19 Jun 2020 21:11:26 +0200 Subject: [PATCH 069/169] wip: feature function generate triple when true condition is met trueCondition's argument is the result of the contains function --- .../mapping.ttl | 65 +++++++++++++++++++ .../output.ttl | 1 + .../scala/io/rml/framework/SandboxTests.scala | 5 ++ 3 files changed, 71 insertions(+) create mode 100644 src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl create mode 100644 src/test/resources/sandbox/function_related/using_trueCondition_and_contains/output.ttl diff --git a/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl b/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl new file mode 100644 index 00000000..f68f4c3e --- /dev/null +++ b/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl @@ -0,0 +1,65 @@ +# generate triples using trueCondition and Equal + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "sandbox/function_related/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:trueCondition ] + ]; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:strBoolean ; + rr:objectMap + ] ; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] + ] + ] + ] + ]. + + + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:string_contains ] ] ; + + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ]; + + rr:predicateObjectMap [ + rr:predicate grel:string_sub ; + rr:objectMap [ rr:constant "us" ] ] + + ] ; +. \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/output.ttl b/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/output.ttl new file mode 100644 index 00000000..8d800662 --- /dev/null +++ b/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/output.ttl @@ -0,0 +1 @@ + "Venus". diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 958f4574..8fde19ef 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -111,6 +111,11 @@ class SandboxTests extends FunSuite with Matchers { } + test("sandbox/function_related/using_trueCondition_and_contains") { + executeTest("sandbox/function_related/using_trueCondition_and_contains/mapping.ttl") + } + + From a759aa4c3366d38afb847d313731daafa7702976 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sat, 20 Jun 2020 00:17:53 +0200 Subject: [PATCH 070/169] Made sandboxtests discoverable so that they are also evaluated during testing --- src/test/scala/io/rml/framework/SandboxTests.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 8fde19ef..89e2c6c6 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -35,7 +35,7 @@ import io.rml.framework.util.logging.Logger import org.apache.flink.api.scala.ExecutionEnvironment import org.apache.flink.streaming.api.scala._ import org.scalatest.{DoNotDiscover, FunSuite, Matchers} -@DoNotDiscover + class SandboxTests extends FunSuite with Matchers { val functionFile = new File(getClass.getClassLoader.getResource("functions.ttl").getFile) From eb3dc1e2b3c921a894235a5866d43f5776723673 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 08:57:52 +0200 Subject: [PATCH 071/169] wip: function feature: grel:controls_if functions_grel.ttl & grel_java_mapping.ttl: added output parameter definition for the controls_if function and fixed metadata mixup DynamicFunction: - added private findMethod for finding the requested method. If the method can't be found directly (using `getDeclaredMethod`) ; then a second "manual" attempt will be made to find the method by name. The way this second attempt is performed can be improved (currently the first method with the same name is chosen) RMLVoc: added rdf:Object Parameter: can cast parameter value to object SandboxTests: added two sandbox testcases (controls_if_true, controls_if_false) along with their resources --- src/main/resources/functions_grel.ttl | 10 ++++ src/main/resources/grel_java_mapping.ttl | 4 +- .../core/function/FunctionUtils.scala | 1 + .../core/function/model/DynamicFunction.scala | 53 ++++++++++++++++-- .../core/function/model/Parameter.scala | 21 +++++-- .../framework/core/vocabulary/RMLVoc.scala | 1 + .../controls_if_false/mapping.ttl | 55 +++++++++++++++++++ .../controls_if_false/output.nq | 2 + .../controls_if_true/mapping.ttl | 55 +++++++++++++++++++ .../controls_if_true/output.nq | 2 + .../scala/io/rml/framework/SandboxTests.scala | 8 +++ 11 files changed, 198 insertions(+), 14 deletions(-) create mode 100644 src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl create mode 100644 src/test/resources/sandbox/function_related/controls_if_false/output.nq create mode 100644 src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl create mode 100644 src/test/resources/sandbox/function_related/controls_if_true/output.nq diff --git a/src/main/resources/functions_grel.ttl b/src/main/resources/functions_grel.ttl index 15ec66e8..23dedb56 100644 --- a/src/main/resources/functions_grel.ttl +++ b/src/main/resources/functions_grel.ttl @@ -197,6 +197,15 @@ grel:param_false fno:type xsd:any ; fno:required "true"^^xsd:boolean . + +grel:output_any + a fno:Parameter ; + #fno:name "" ; + #rdfs:label "" ; + fno:predicate grel:any_output ; + fno:type rdf:object; + fno:required "true"^^xsd:boolean . + grel:prob_string a fno:Problem ; fno:name "The string problem"^^xsd:string ; @@ -494,6 +503,7 @@ grel:output_array fno:predicate grel:o_array ; fno:type rdf:List . + grel:param_regex a fno:Parameter ; fno:name "p" ; diff --git a/src/main/resources/grel_java_mapping.ttl b/src/main/resources/grel_java_mapping.ttl index e1c7970c..ba3c6341 100644 --- a/src/main/resources/grel_java_mapping.ttl +++ b/src/main/resources/grel_java_mapping.ttl @@ -152,13 +152,13 @@ grelm:javaControls grelm:ifthenelseMapping a fno:Mapping ; fno:function grel:controls_if ; - fno:implementation grelm:javaBoolean ; + fno:implementation grelm:javaControls ; # TODO if not clear fno:parameterMapping [ ] ; # TODO if not clear fno:returnMapping [ ] ; fno:methodMapping [ a fnom:StringMethodMapping ; - fnom:method-name "xor" ] ; + fnom:method-name "ifThenElse" ] ; . grelm:javaString diff --git a/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala index 36515a43..aae8c1d9 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala @@ -69,6 +69,7 @@ object FunctionUtils extends Logging { case Uri(RMLVoc.Type.XSD_BOOLEAN) => classOf[Boolean] case Uri(RMLVoc.Type.RDF_LIST) => classOf[List[_]] case Uri(RMLVoc.Type.XSD_ANY) => classOf[Any] + case Uri(RMLVoc.Type.RDF_OBJECT) => classOf[Any] case _ => throw new RMLException(s"Type $uri not supported for parameter") } } diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala index e5198d98..1207f6bf 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala @@ -22,16 +22,35 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten out.defaultWriteObject() } + private def findMethod(classObject : Class[_], inputParameters : List[Parameter]) : Option[Method] = { + try { + Some(classObject.getDeclaredMethod(metaData.methodName, metaData.inputParam.map(_.paramType): _*)) + }catch{ + case e : NoSuchMethodException => { + this.logWarning(s"Unable to exactly match the function ${metaData.methodName} in ${metaData.className}.\n" + + s"Let's try to find the method ourself by filtering on method-name ONLY. [TODO]") + // try to find the method ourselfs + val declaredMethods = classObject.getDeclaredMethods + // first filter out methods with the same name + val filteredMethods = declaredMethods.filter(_.getName == metaData.methodName) + // Currently, just return the first available method and assume (hope) it will be correct // TODO: more specific method search + val candidateMethod = filteredMethods.head + filteredMethods.headOption + } + } + + + + } + override def initialize(): Function = { if(optMethod.isEmpty) { val jarFile = getClass.getClassLoader.getResource(metaData.source).getFile val classOfMethod = FunctionUtils.loadClassFromJar(new File(jarFile), metaData.className) - val method = classOfMethod.getDeclaredMethod(metaData.methodName, metaData.inputParam.map(_.paramType): _*) - optMethod = Some(method) + optMethod = findMethod(classOfMethod, metaData.inputParam) } this - } @throws(classOf[IOException]) @throws(classOf[ClassNotFoundException]) @@ -58,12 +77,34 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten if (paramsOrdered.size == inputParams.size) { val definiteMethod = optMethod.get - val output = definiteMethod.invoke(null, paramsOrdered: _*) - val result = outputParams.flatMap(elem => elem.getValue(output))map(elem => Literal(elem.toString)) + // let's cast every input parameter value to the corresponding parameter type of the method parameters + val castedParameterValues = + definiteMethod + .getParameterTypes + .zip(paramsOrdered) + .map( + pair => { + val t = pair._1.getName + val v = pair._2 + t match { + case "java.lang.Boolean"|"Boolean" => v.toString.toBoolean + case _ => v + } + } + ) + .map(_.asInstanceOf[AnyRef]) + .toList + + val output = definiteMethod.invoke(null, castedParameterValues: _*) - Some(result) + if(output!=null) { + val result = outputParams.flatMap(elem => elem.getValue(output)) map (elem => Literal(elem.toString)) + Some(result) + }else + None } else { + //TODO: complain about inputparams size != params ordered None } } diff --git a/src/main/scala/io/rml/framework/core/function/model/Parameter.scala b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala index 79db9b14..5dfcc09a 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Parameter.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala @@ -44,20 +44,26 @@ abstract class Parameter extends Node { * @return value of the parameter of type specified by [[paramType]] */ + def getValue(paraValue: Any): Option[Any] = { val ScalaString = classOf[String].getName val IntegerString = classOf[Int].getName val DoubleString = classOf[Double].getName val ListString = classOf[List[_]].getName val ArrayString = classOf[Array[_]].getName - + val ObjectString = classOf[Object].getName val BooleanString = classOf[Boolean].getName - try { + + if(paramType== null) + throw new NullPointerException("parameter type is null..") + else{ paramType.getName match { case BooleanString |"boolean" => Some(paraValue) case ScalaString | "java.lang.String" => Some(paraValue.toString) case IntegerString | "int" => Some(paraValue.toString.toInt) case DoubleString | "double" => Some(paraValue.toString.toDouble) + case ObjectString|"java.lang.Object" => Some(paraValue) + case ListString | ArrayString | "java.util.List" => val parsedListEither = JSON.parseFull(paraValue.toString).toRight("Value can't be parsed as List") @@ -70,17 +76,20 @@ abstract class Parameter extends Node { case _ => None } - case Left(exMessage) => throw new IllegalArgumentException(exMessage) + + + case Left(exMessage) => throw new IllegalArgumentException(exMessage) } - case _ => None + case _ => throw new Error(s"Couldn't derive type: ${paramType.getName}") } - }catch { - case _: Throwable => None } } + + + } /** diff --git a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala index cf456ca3..b88d38f6 100644 --- a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala +++ b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala @@ -43,6 +43,7 @@ object RMLVoc { val XSD_BOOLEAN = Namespaces("xsd", "boolean") val XSD_ANY = Namespaces("xsd", "any") + val RDF_OBJECT = Namespaces("rdf", "object") } diff --git a/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl new file mode 100644 index 00000000..bd0b7447 --- /dev/null +++ b/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl @@ -0,0 +1,55 @@ +# Function on graph, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix idlab-fn: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "sandbox/function_related/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate ex:if_false_example; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:controls_if ] ] ; + + rr:predicateObjectMap [ + rr:predicate grel:bool_b ; + rr:object "false" + + ]; + + rr:predicateObjectMap [ + rr:predicate grel:any_true ; + rr:objectMap [ rml:reference "Name"; rr:datatype xsd:string ] ]; + + rr:predicateObjectMap [ + rr:predicate grel:any_false ; + rr:objectMap [ rr:constant "IF_CLAUSE_WAS_FALSE" ] ] + + ] ; + + + ] ; + + ]. diff --git a/src/test/resources/sandbox/function_related/controls_if_false/output.nq b/src/test/resources/sandbox/function_related/controls_if_false/output.nq new file mode 100644 index 00000000..97d867eb --- /dev/null +++ b/src/test/resources/sandbox/function_related/controls_if_false/output.nq @@ -0,0 +1,2 @@ + "IF_CLAUSE_WAS_FALSE" . + "IF_CLAUSE_WAS_FALSE" . \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl new file mode 100644 index 00000000..580c7dfd --- /dev/null +++ b/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl @@ -0,0 +1,55 @@ +# Function on graph, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix idlab-fn: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "sandbox/function_related/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate ex:contains_us; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:controls_if ] ] ; + + rr:predicateObjectMap [ + rr:predicate grel:bool_b ; + rr:object "true" + + ]; + + rr:predicateObjectMap [ + rr:predicate grel:any_true ; + rr:objectMap [ rml:reference "Name"; rr:datatype xsd:string ] ]; + + rr:predicateObjectMap [ + rr:predicate grel:any_false ; + rr:objectMap [ rr:constant "us" ] ] + + ] ; + + + ] ; + + ]. diff --git a/src/test/resources/sandbox/function_related/controls_if_true/output.nq b/src/test/resources/sandbox/function_related/controls_if_true/output.nq new file mode 100644 index 00000000..1406dc9b --- /dev/null +++ b/src/test/resources/sandbox/function_related/controls_if_true/output.nq @@ -0,0 +1,2 @@ + "Algebra" . + "Venus" . \ No newline at end of file diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 89e2c6c6..da787d22 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -115,6 +115,14 @@ class SandboxTests extends FunSuite with Matchers { executeTest("sandbox/function_related/using_trueCondition_and_contains/mapping.ttl") } + test("sandbox/function_related/controls_if_true") { + executeTest("sandbox/function_related/controls_if_true/mapping.ttl") + } + + test("sandbox/function_related/controls_if_false") { + executeTest("sandbox/function_related/controls_if_false/mapping.ttl") + } + From a7597724496d4bf9ce570f35db50ca67ac58425f Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 09:03:38 +0200 Subject: [PATCH 072/169] removed unused variable --- .../io/rml/framework/core/function/model/DynamicFunction.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala index 1207f6bf..8875864b 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala @@ -34,7 +34,6 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten // first filter out methods with the same name val filteredMethods = declaredMethods.filter(_.getName == metaData.methodName) // Currently, just return the first available method and assume (hope) it will be correct // TODO: more specific method search - val candidateMethod = filteredMethods.head filteredMethods.headOption } } From 0148f2085de5b9ad0d74d8e196addee81cc8379c Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 10:59:57 +0200 Subject: [PATCH 073/169] fix: resources aren't necessarily a TriplesMap when having a log source --- .../framework/core/extractors/std/StdTriplesMapExtractor.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala index fa8ad98e..56c7dd7d 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala @@ -69,8 +69,7 @@ class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, // filter all triple map resources from the graph val typeUri = Uri(RMLVoc.Class.TRIPLESMAP) - val triplesMapResources = (graph.filterResources(typeUri) ++ - graph.filterProperties(Uri(RMLVoc.Property.LOGICALSOURCE))).distinct + val triplesMapResources = graph.filterResources(typeUri) // debug log, inside check for performance From 8e0c0b0142df97a252deccdca762fffe17db15b7 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 12:25:30 +0200 Subject: [PATCH 074/169] fix: resource now correctly inferred as TriplesMap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, a resource was being classified as a TriplesMaps when it had the TriplesMap-class or when the resource contained the logical source property. However, containing a logical source property isn't sufficient → it should have 3 properties logical source, subjectMaps, predicateObjectMaps, --- .../std/StdTriplesMapExtractor.scala | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala index 56c7dd7d..8c228880 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala @@ -42,6 +42,30 @@ class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, extends TriplesMapExtractor with Logging { + /** + * Helper method for inferring whether the given resource is a TriplesMap. + * A resource can be considered a TriplesMap when any of the following conditions are met + * 1. (trival case) the resource has the TriplesMap type + * 2. the resource has the properties: logicalSource, subjectMap, predicateObjectMap + * @param resource + * @return [Boolean] indicating whether the resource is a TriplesMap + */ + private def isTriplesMap(resource : RDFResource) : Boolean = { + val logicalSourceProperty = RMLVoc.Property.LOGICALSOURCE + val subjectMapProperty = RMLVoc.Property.SUBJECTMAP + val predicateObjectMapProperty =RMLVoc.Property.PREDICATEOBJECTMAP + + val isTriplesMap = resource.getType == Some(Uri(RMLVoc.Class.TRIPLESMAP)) + + + val hasLogicalSource = !resource.listProperties(logicalSourceProperty).isEmpty + val hasSubjectMap = !resource.listProperties(subjectMapProperty).isEmpty + val hasPredicateObjectMap = !resource.listProperties(predicateObjectMapProperty).isEmpty + + + val resourceIsTriplesMap = isTriplesMap|(hasLogicalSource&hasSubjectMap&hasPredicateObjectMap) + resourceIsTriplesMap + } /** * Extracts a set of triple maps from a graph. * If extraction for a triple map fails, this triple map will be skipped. @@ -50,7 +74,6 @@ class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, * @return */ override def extract(graph: RDFGraph): List[TriplesMap] = { - val triplesMapResources = filterTriplesMaps(graph) // iterate over each triple map resource @@ -69,7 +92,10 @@ class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, // filter all triple map resources from the graph val typeUri = Uri(RMLVoc.Class.TRIPLESMAP) - val triplesMapResources = graph.filterResources(typeUri) + val logicalSourcePropertyUri = Uri(RMLVoc.Property.LOGICALSOURCE) + val potentialTriplesMapResources = graph.filterProperties(logicalSourcePropertyUri) + //val triplesMapResources = graph.filterResources(typeUri) + val triplesMapResources = potentialTriplesMapResources.filter(isTriplesMap) // debug log, inside check for performance From cc4c84527971e60b35c5ba297dbd3ca3b494e4cf Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 12:33:31 +0200 Subject: [PATCH 075/169] fix:filterTriplesMaps -- code cleanup --- .../core/extractors/std/StdTriplesMapExtractor.scala | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala index 8c228880..db1ff2b2 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala @@ -55,14 +55,15 @@ class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, val subjectMapProperty = RMLVoc.Property.SUBJECTMAP val predicateObjectMapProperty =RMLVoc.Property.PREDICATEOBJECTMAP + // trivial case val isTriplesMap = resource.getType == Some(Uri(RMLVoc.Class.TRIPLESMAP)) - + // required properties for being a triplesmap val hasLogicalSource = !resource.listProperties(logicalSourceProperty).isEmpty val hasSubjectMap = !resource.listProperties(subjectMapProperty).isEmpty val hasPredicateObjectMap = !resource.listProperties(predicateObjectMapProperty).isEmpty - + // infer whether the resource is a triples map val resourceIsTriplesMap = isTriplesMap|(hasLogicalSource&hasSubjectMap&hasPredicateObjectMap) resourceIsTriplesMap } @@ -88,16 +89,11 @@ class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, * @param graph */ private def filterTriplesMaps(graph: RDFGraph): List[RDFResource] = { - - // filter all triple map resources from the graph - val typeUri = Uri(RMLVoc.Class.TRIPLESMAP) val logicalSourcePropertyUri = Uri(RMLVoc.Property.LOGICALSOURCE) val potentialTriplesMapResources = graph.filterProperties(logicalSourcePropertyUri) - //val triplesMapResources = graph.filterResources(typeUri) val triplesMapResources = potentialTriplesMapResources.filter(isTriplesMap) - // debug log, inside check for performance if (isDebugEnabled) { logDebug(graph.uri + ": Extracting triple maps from graph.") From 05a2d6cda303516f6a34bad50225437dc8686647 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 12:36:16 +0200 Subject: [PATCH 076/169] wip: feature function: added sandbox testcases --- .../condition-on-po/mapping.rml.ttl | 84 ++++++++++++++++++ .../condition-on-po/mapping.yml | 17 ++++ .../condition-on-po/output.ttl | 1 + .../function_related/condition-on-po/test.csv | 3 + .../controls_if_contains/mapping.ttl | 80 +++++++++++++++++ .../controls_if_contains/output.nq | 2 + .../mapping.ttl | 86 +++++++++++++++++++ .../output.nq | 2 + .../controls_if_true/mapping.ttl | 2 +- .../scala/io/rml/framework/SandboxTests.scala | 14 +++ 10 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/sandbox/function_related/condition-on-po/mapping.rml.ttl create mode 100644 src/test/resources/sandbox/function_related/condition-on-po/mapping.yml create mode 100644 src/test/resources/sandbox/function_related/condition-on-po/output.ttl create mode 100644 src/test/resources/sandbox/function_related/condition-on-po/test.csv create mode 100644 src/test/resources/sandbox/function_related/controls_if_contains/mapping.ttl create mode 100644 src/test/resources/sandbox/function_related/controls_if_contains/output.nq create mode 100644 src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl create mode 100644 src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/output.nq diff --git a/src/test/resources/sandbox/function_related/condition-on-po/mapping.rml.ttl b/src/test/resources/sandbox/function_related/condition-on-po/mapping.rml.ttl new file mode 100644 index 00000000..4689487b --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-on-po/mapping.rml.ttl @@ -0,0 +1,84 @@ +@prefix rr: . +@prefix rdf: . +@prefix rdfs: . +@prefix fnml: . +@prefix fno: . +@prefix rml: . +@prefix ql: . +@prefix : . +@prefix grel: . +@prefix idlab-fn: . + +:map_person_0 rml:logicalSource :source_0. +:source_0 a rml:LogicalSource; + rml:source "sandbox/function_related/condition-on-po/test.csv"; + rml:referenceFormulation ql:CSV. +:map_person_0 a rr:TriplesMap; + rdfs:label "person". + +:s_0 a rr:SubjectMap. +:map_person_0 rr:subjectMap :s_0. +:s_0 rr:template "http://example.org/{firstname}". + +:pom_0 a rr:PredicateObjectMap. +:map_person_0 rr:predicateObjectMap :pom_0. + +:pm_0 a rr:PredicateMap. +:pom_0 rr:predicateMap :pm_0. +:pm_0 rr:constant . +:pom_0 rr:objectMap :om_0. + + + +:om_0 a fnml:FunctionTermMap; + rr:termType rr:Literal; + fnml:functionValue :fn_0. +:fn_0 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_0. +:pomexec_0 rr:predicateMap :pmexec_0. +:pmexec_0 rr:constant fno:executes. +:pomexec_0 rr:objectMap :omexec_0. +:omexec_0 rr:constant "http://example.com/idlab/function/trueCondition"; + rr:termType rr:IRI. +:fn_0 rr:predicateObjectMap :pom_1. +:pom_1 a rr:PredicateObjectMap; + rr:predicateMap :pm_1. +:pm_1 a rr:PredicateMap; + rr:constant idlab-fn:strBoolean. +:pom_1 rr:objectMap :om_1. +:om_1 a rr:ObjectMap; + fnml:functionValue :fn_1. +:fn_1 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_1. +:pomexec_1 rr:predicateMap :pmexec_1. +:pmexec_1 rr:constant fno:executes. +:pomexec_1 rr:objectMap :omexec_1. +:omexec_1 rr:constant "http://example.com/idlab/function/equal"; + rr:termType rr:IRI. +:fn_1 rr:predicateObjectMap :pom_2. +:pom_2 a rr:PredicateObjectMap; + rr:predicateMap :pm_2. +:pm_2 a rr:PredicateMap; + rr:constant grel:valueParameter. +:pom_2 rr:objectMap :om_2. +:om_2 a rr:ObjectMap; + rml:reference "firstname"; + rr:termType rr:Literal. +:fn_1 rr:predicateObjectMap :pom_3. +:pom_3 a rr:PredicateObjectMap; + rr:predicateMap :pm_3. +:pm_3 a rr:PredicateMap; + rr:constant grel:valueParameter2. +:pom_3 rr:objectMap :om_3. +:om_3 a rr:ObjectMap; + rr:constant "test"; + rr:termType rr:Literal. +:fn_0 rr:predicateObjectMap :pom_4. +:pom_4 a rr:PredicateObjectMap; + rr:predicateMap :pm_4. +:pm_4 a rr:PredicateMap; + rr:constant idlab-fn:str. +:pom_4 rr:objectMap :om_4. +:om_4 a rr:ObjectMap; + rml:reference "firstname"; + rr:termType rr:Literal. diff --git a/src/test/resources/sandbox/function_related/condition-on-po/mapping.yml b/src/test/resources/sandbox/function_related/condition-on-po/mapping.yml new file mode 100644 index 00000000..466e07b2 --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-on-po/mapping.yml @@ -0,0 +1,17 @@ +prefixes: + grel: http://users.ugent.be/~bjdmeest/function/grel.ttl# + idlab-fn: http://example.com/idlab/function/ + +mappings: + person: + sources: + - [test.csv~csv] + subject: http://example.org/$(firstname) + predicateobjects: + - predicates: foaf:firstName + objects: $(firstname) + condition: + function: idlab-fn:equal + parameters: + - [grel:valueParameter, $(firstname)] + - [grel:valueParameter2, "test"] diff --git a/src/test/resources/sandbox/function_related/condition-on-po/output.ttl b/src/test/resources/sandbox/function_related/condition-on-po/output.ttl new file mode 100644 index 00000000..cf12a8bc --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-on-po/output.ttl @@ -0,0 +1 @@ + "test". \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/condition-on-po/test.csv b/src/test/resources/sandbox/function_related/condition-on-po/test.csv new file mode 100644 index 00000000..27c5d022 --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-on-po/test.csv @@ -0,0 +1,3 @@ +firstname +test, +test2 diff --git a/src/test/resources/sandbox/function_related/controls_if_contains/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_contains/mapping.ttl new file mode 100644 index 00000000..58007c7b --- /dev/null +++ b/src/test/resources/sandbox/function_related/controls_if_contains/mapping.ttl @@ -0,0 +1,80 @@ +# Generate literals using grel:controls_if and grel:string_contains + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix idlab-fn: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "sandbox/function_related/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate ex:contains_us; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:controls_if ] ] ; + + rr:predicateObjectMap [ + rr:predicate grel:bool_b ; + rr:objectMap + + ]; + + rr:predicateObjectMap [ + rr:predicate grel:any_true ; + rr:objectMap [ + rr:template "{Name} contains us" ; + rr:termType rr:Literal + ] + ]; + + rr:predicateObjectMap [ + rr:predicate grel:any_false ; + rr:objectMap [ + rr:template "{Name} does NOT contain us" ; + rr:termType rr:Literal; + ] + ] + + ] ; + + + ] ; + + ]. + +fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:string_contains ] ] ; + + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ]; + + rr:predicateObjectMap [ + rr:predicate grel:string_sub ; + rr:objectMap [ rr:constant "us" ] ] + + ] . + + diff --git a/src/test/resources/sandbox/function_related/controls_if_contains/output.nq b/src/test/resources/sandbox/function_related/controls_if_contains/output.nq new file mode 100644 index 00000000..076406d8 --- /dev/null +++ b/src/test/resources/sandbox/function_related/controls_if_contains/output.nq @@ -0,0 +1,2 @@ + "Algebra does NOT contain us" . + "Venus contains us" . \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl new file mode 100644 index 00000000..f406fa85 --- /dev/null +++ b/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl @@ -0,0 +1,86 @@ +# Generate [TODO] using grel:controls_if and grel:string_contains + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix idlab-fn: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "sandbox/function_related/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate ex:contains_us; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:controls_if ] ] ; + + rr:predicateObjectMap [ + rr:predicate grel:bool_b ; + rr:objectMap + + ]; + + rr:predicateObjectMap [ + rr:predicate grel:any_true ; + rr:objectMap + + + ]; + + rr:predicateObjectMap [ + rr:predicate grel:any_false ; + rr:objectMap [ + rr:template "{Name} does NOT contain us" ; + rr:termType rr:Literal; + ] + ] + + ] ; + + + ] ; + + ]. + +fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:string_contains ] ] ; + + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ]; + + rr:predicateObjectMap [ + rr:predicate grel:string_sub ; + rr:objectMap [ rr:constant "us" ] ] + + ] . + + + + + +rr:predicateObjectMap [ + rr:predicate ex:testje; + rr:object "TRUEMAP"; + ]. \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/output.nq b/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/output.nq new file mode 100644 index 00000000..1406dc9b --- /dev/null +++ b/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/output.nq @@ -0,0 +1,2 @@ + "Algebra" . + "Venus" . \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl index 580c7dfd..2bf0db03 100644 --- a/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl +++ b/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl @@ -45,7 +45,7 @@ rr:predicateObjectMap [ rr:predicate grel:any_false ; - rr:objectMap [ rr:constant "us" ] ] + rr:objectMap [ rr:constant "IF_CLAUSE_WAS_FALSE" ] ] ] ; diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index da787d22..5f6522fc 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -123,6 +123,20 @@ class SandboxTests extends FunSuite with Matchers { executeTest("sandbox/function_related/controls_if_false/mapping.ttl") } + test("sandbox/function_related/controls_if_contains") { + executeTest("sandbox/function_related/controls_if_contains/mapping.ttl") + } + + test("sandbox/function_related/controls_if_contains_true_execute_triplesmap") { + pending + executeTest("sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl") + } + test("sandbox/function_related/condition-on-po") { + + executeTest("sandbox/function_related/condition-on-po/mapping.rml.ttl") + } + + From a0f13e61fe67c5ea975dd538c96d7b092ad6651e Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 14:13:44 +0200 Subject: [PATCH 077/169] wip: function feature: add sandbox test: condition function on po this testcase originates from the yarrrml-parser repository --- src/main/resources/functions_idlab.ttl | 8 ++ src/main/resources/idlab_java_mapping.ttl | 10 ++ .../condition-function-on-po/data.json | 16 +++ .../condition-function-on-po/mapping.ttl | 126 ++++++++++++++++++ .../condition-function-on-po/mapping.ttl.bak | 126 ++++++++++++++++++ .../condition-function-on-po/mapping.yarrrml | 24 ++++ .../condition-function-on-po/output.ttl | 5 + .../scala/io/rml/framework/SandboxTests.scala | 9 +- 8 files changed, 323 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/sandbox/function_related/condition-function-on-po/data.json create mode 100644 src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl create mode 100644 src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl.bak create mode 100644 src/test/resources/sandbox/function_related/condition-function-on-po/mapping.yarrrml create mode 100644 src/test/resources/sandbox/function_related/condition-function-on-po/output.ttl diff --git a/src/main/resources/functions_idlab.ttl b/src/main/resources/functions_idlab.ttl index 78885c4b..f97b29ef 100644 --- a/src/main/resources/functions_idlab.ttl +++ b/src/main/resources/functions_idlab.ttl @@ -86,6 +86,14 @@ idlab-fn:notEqual fno:expects ( grel:valueParam grel:valueParam2 ) ; fno:returns ( grel:stringOut ) . +idlab-fn:stringContainsOtherString + a fno:Function ; + fno:name "stringContainsOtherString" ; + rdfs:label "stringContainsOtherString" ; + dcterms:description "Returns true if a string is found in a delimited string." ; + fno:expects ( idlab-fn:_str idlab-fn:_otherStr idlab-fn:_delimiter ) ; + fno:returns ( idlab-fn:_stringOut ) . + idlab-fn:_path a fno:Parameter ; fno:name "input path" ; diff --git a/src/main/resources/idlab_java_mapping.ttl b/src/main/resources/idlab_java_mapping.ttl index a835998e..511da284 100644 --- a/src/main/resources/idlab_java_mapping.ttl +++ b/src/main/resources/idlab_java_mapping.ttl @@ -103,4 +103,14 @@ grelm:notEqualMapping fnom:method-name "notEqual" ] ; . +grelm:stringContainsOtherStringMapping + a fno:Mapping ; + fno:function idlab-fn:stringContainsOtherString; + fno:implementation grelm:IDLabFunctions ; + fno:parameterMapping [ ] ; + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "stringContainsOtherString" ] ; +. + diff --git a/src/test/resources/sandbox/function_related/condition-function-on-po/data.json b/src/test/resources/sandbox/function_related/condition-function-on-po/data.json new file mode 100644 index 00000000..3fb4e6cd --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-function-on-po/data.json @@ -0,0 +1,16 @@ +{ + "persons": [ + { + "firstname": "John", + "lastname": "Doe" + }, + { + "firstname": "Jane", + "lastname": "Smith" + }, + { + "firstname": "Sarah", + "lastname": "Bladinck" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl new file mode 100644 index 00000000..382c995c --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl @@ -0,0 +1,126 @@ +# NOTE: this mapping file was initially generated by the yarrrml-parser. +# However, rml:parentTermMap :ptm_0 was replaced with a constant. +# +# More specifically, the following +# :om_7 a rr:ObjectMap; +# rml:parentTermMap :ptm_0. +# :ptm_0 rml:reference "firstname". +# +# has been replaced with +# :om_7 a rr:ObjectMap; +# rml:reference "firstname". + +@prefix rr: . +@prefix rdf: . +@prefix rdfs: . +@prefix fnml: . +@prefix fno: . +@prefix d2rq: . +@prefix rml: . +@prefix ql: . +@prefix : . +@prefix ex: . +@prefix idlab-fn: . +@prefix grel: . + +:map_person_0 rml:logicalSource :source_0. +:source_0 a rml:LogicalSource; + rml:source "sandbox/function_related/condition-function-on-po/data.json"; + rml:iterator "$.persons[*]"; + rml:referenceFormulation ql:JSONPath. +:map_person_0 a rr:TriplesMap; + rdfs:label "person". +:s_0 a rr:SubjectMap. +:map_person_0 rr:subjectMap :s_0. +:s_0 rr:template "http://example.com/{firstname}". +:pom_0 a rr:PredicateObjectMap. +:map_person_0 rr:predicateObjectMap :pom_0. +:pm_0 a rr:PredicateMap. +:pom_0 rr:predicateMap :pm_0. +:pm_0 rr:constant rdf:type. +:pom_0 rr:objectMap :om_0. +:om_0 a rr:ObjectMap; + rr:constant "http://xmlns.com/foaf/0.1/Person"; + rr:termType rr:IRI. +:pom_1 a rr:PredicateObjectMap. +:map_person_0 rr:predicateObjectMap :pom_1. +:pm_1 a rr:PredicateMap. +:pom_1 rr:predicateMap :pm_1. +:pm_1 rr:constant . +:pom_1 rr:objectMap :om_1. +:om_1 a fnml:FunctionTermMap; + rr:termType rr:Literal; + fnml:functionValue :fn_0. +:fn_0 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_0. +:pomexec_0 rr:predicateMap :pmexec_0. +:pmexec_0 rr:constant fno:executes. +:pomexec_0 rr:objectMap :omexec_0. +:omexec_0 rr:constant "http://example.com/idlab/function/trueCondition"; + rr:termType rr:IRI. +:fn_0 rr:predicateObjectMap :pom_2. +:pom_2 a rr:PredicateObjectMap; + rr:predicateMap :pm_2. +:pm_2 a rr:PredicateMap; + rr:constant idlab-fn:strBoolean. +:pom_2 rr:objectMap :om_2. +:om_2 a rr:ObjectMap, fnml:FunctionTermMap; + fnml:functionValue :fn_1. +:fn_1 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_1. +:pomexec_1 rr:predicateMap :pmexec_1. +:pmexec_1 rr:constant fno:executes. +:pomexec_1 rr:objectMap :omexec_1. +:omexec_1 rr:constant "http://example.com/idlab/function/stringContainsOtherString"; + rr:termType rr:IRI. +:fn_1 rr:predicateObjectMap :pom_3. +:pom_3 a rr:PredicateObjectMap; + rr:predicateMap :pm_3. +:pm_3 a rr:PredicateMap; + rr:constant idlab-fn:str. +:pom_3 rr:objectMap :om_3. +:om_3 a rr:ObjectMap; + rml:reference "firstname"; + rr:termType rr:Literal. +:fn_1 rr:predicateObjectMap :pom_4. +:pom_4 a rr:PredicateObjectMap; + rr:predicateMap :pm_4. +:pm_4 a rr:PredicateMap; + rr:constant idlab-fn:otherStr. +:pom_4 rr:objectMap :om_4. +:om_4 a rr:ObjectMap; + rr:constant "J"; + rr:termType rr:Literal. +:fn_1 rr:predicateObjectMap :pom_5. +:pom_5 a rr:PredicateObjectMap; + rr:predicateMap :pm_5. +:pm_5 a rr:PredicateMap; + rr:constant idlab-fn:delimiter. +:pom_5 rr:objectMap :om_5. +:om_5 a rr:ObjectMap; + rr:constant ""; + rr:termType rr:Literal. +:fn_0 rr:predicateObjectMap :pom_6. +:pom_6 a rr:PredicateObjectMap; + rr:predicateMap :pm_6. +:pm_6 a rr:PredicateMap; + rr:constant idlab-fn:str. +:pom_6 rr:objectMap :om_6. +:om_6 a rr:ObjectMap, fnml:FunctionTermMap; + fnml:functionValue :fn_2. +:fn_2 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_2. +:pomexec_2 rr:predicateMap :pmexec_2. +:pmexec_2 rr:constant fno:executes. +:pomexec_2 rr:objectMap :omexec_2. +:omexec_2 rr:constant "http://users.ugent.be/~bjdmeest/function/grel.ttl#toUpperCase"; + rr:termType rr:IRI. +:fn_2 rr:predicateObjectMap :pom_7. +:pom_7 a rr:PredicateObjectMap; + rr:predicateMap :pm_7. +:pm_7 a rr:PredicateMap; + rr:constant grel:valueParameter. +:pom_7 rr:objectMap :om_7. +:om_7 a rr:ObjectMap; + rml:reference "firstname". + diff --git a/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl.bak b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl.bak new file mode 100644 index 00000000..382c995c --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl.bak @@ -0,0 +1,126 @@ +# NOTE: this mapping file was initially generated by the yarrrml-parser. +# However, rml:parentTermMap :ptm_0 was replaced with a constant. +# +# More specifically, the following +# :om_7 a rr:ObjectMap; +# rml:parentTermMap :ptm_0. +# :ptm_0 rml:reference "firstname". +# +# has been replaced with +# :om_7 a rr:ObjectMap; +# rml:reference "firstname". + +@prefix rr: . +@prefix rdf: . +@prefix rdfs: . +@prefix fnml: . +@prefix fno: . +@prefix d2rq: . +@prefix rml: . +@prefix ql: . +@prefix : . +@prefix ex: . +@prefix idlab-fn: . +@prefix grel: . + +:map_person_0 rml:logicalSource :source_0. +:source_0 a rml:LogicalSource; + rml:source "sandbox/function_related/condition-function-on-po/data.json"; + rml:iterator "$.persons[*]"; + rml:referenceFormulation ql:JSONPath. +:map_person_0 a rr:TriplesMap; + rdfs:label "person". +:s_0 a rr:SubjectMap. +:map_person_0 rr:subjectMap :s_0. +:s_0 rr:template "http://example.com/{firstname}". +:pom_0 a rr:PredicateObjectMap. +:map_person_0 rr:predicateObjectMap :pom_0. +:pm_0 a rr:PredicateMap. +:pom_0 rr:predicateMap :pm_0. +:pm_0 rr:constant rdf:type. +:pom_0 rr:objectMap :om_0. +:om_0 a rr:ObjectMap; + rr:constant "http://xmlns.com/foaf/0.1/Person"; + rr:termType rr:IRI. +:pom_1 a rr:PredicateObjectMap. +:map_person_0 rr:predicateObjectMap :pom_1. +:pm_1 a rr:PredicateMap. +:pom_1 rr:predicateMap :pm_1. +:pm_1 rr:constant . +:pom_1 rr:objectMap :om_1. +:om_1 a fnml:FunctionTermMap; + rr:termType rr:Literal; + fnml:functionValue :fn_0. +:fn_0 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_0. +:pomexec_0 rr:predicateMap :pmexec_0. +:pmexec_0 rr:constant fno:executes. +:pomexec_0 rr:objectMap :omexec_0. +:omexec_0 rr:constant "http://example.com/idlab/function/trueCondition"; + rr:termType rr:IRI. +:fn_0 rr:predicateObjectMap :pom_2. +:pom_2 a rr:PredicateObjectMap; + rr:predicateMap :pm_2. +:pm_2 a rr:PredicateMap; + rr:constant idlab-fn:strBoolean. +:pom_2 rr:objectMap :om_2. +:om_2 a rr:ObjectMap, fnml:FunctionTermMap; + fnml:functionValue :fn_1. +:fn_1 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_1. +:pomexec_1 rr:predicateMap :pmexec_1. +:pmexec_1 rr:constant fno:executes. +:pomexec_1 rr:objectMap :omexec_1. +:omexec_1 rr:constant "http://example.com/idlab/function/stringContainsOtherString"; + rr:termType rr:IRI. +:fn_1 rr:predicateObjectMap :pom_3. +:pom_3 a rr:PredicateObjectMap; + rr:predicateMap :pm_3. +:pm_3 a rr:PredicateMap; + rr:constant idlab-fn:str. +:pom_3 rr:objectMap :om_3. +:om_3 a rr:ObjectMap; + rml:reference "firstname"; + rr:termType rr:Literal. +:fn_1 rr:predicateObjectMap :pom_4. +:pom_4 a rr:PredicateObjectMap; + rr:predicateMap :pm_4. +:pm_4 a rr:PredicateMap; + rr:constant idlab-fn:otherStr. +:pom_4 rr:objectMap :om_4. +:om_4 a rr:ObjectMap; + rr:constant "J"; + rr:termType rr:Literal. +:fn_1 rr:predicateObjectMap :pom_5. +:pom_5 a rr:PredicateObjectMap; + rr:predicateMap :pm_5. +:pm_5 a rr:PredicateMap; + rr:constant idlab-fn:delimiter. +:pom_5 rr:objectMap :om_5. +:om_5 a rr:ObjectMap; + rr:constant ""; + rr:termType rr:Literal. +:fn_0 rr:predicateObjectMap :pom_6. +:pom_6 a rr:PredicateObjectMap; + rr:predicateMap :pm_6. +:pm_6 a rr:PredicateMap; + rr:constant idlab-fn:str. +:pom_6 rr:objectMap :om_6. +:om_6 a rr:ObjectMap, fnml:FunctionTermMap; + fnml:functionValue :fn_2. +:fn_2 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_2. +:pomexec_2 rr:predicateMap :pmexec_2. +:pmexec_2 rr:constant fno:executes. +:pomexec_2 rr:objectMap :omexec_2. +:omexec_2 rr:constant "http://users.ugent.be/~bjdmeest/function/grel.ttl#toUpperCase"; + rr:termType rr:IRI. +:fn_2 rr:predicateObjectMap :pom_7. +:pom_7 a rr:PredicateObjectMap; + rr:predicateMap :pm_7. +:pm_7 a rr:PredicateMap; + rr:constant grel:valueParameter. +:pom_7 rr:objectMap :om_7. +:om_7 a rr:ObjectMap; + rml:reference "firstname". + diff --git a/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.yarrrml b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.yarrrml new file mode 100644 index 00000000..4594ba8d --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.yarrrml @@ -0,0 +1,24 @@ +prefixes: + ex: "http://example.com/" + idlab-fn: http://example.com/idlab/function/ + grel: http://users.ugent.be/~bjdmeest/function/grel.ttl# + +mappings: + person: + sources: + - ['sandbox/function_related/condition-function-on-po/data.json~jsonpath', '$.persons[*]'] + s: http://example.com/$(firstname) + po: + - [a, foaf:Person] + - predicates: foaf:firstName + objects: + - function: grel:toUpperCase + parameters: + - parameter: grel:valueParameter + value: $(firstname) + condition: + function: idlab-fn:stringContainsOtherString + parameters: + - [idlab-fn:str, $(firstname)] + - [idlab-fn:otherStr, "J"] + - [idlab-fn:delimiter, ""] diff --git a/src/test/resources/sandbox/function_related/condition-function-on-po/output.ttl b/src/test/resources/sandbox/function_related/condition-function-on-po/output.ttl new file mode 100644 index 00000000..f8319922 --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-function-on-po/output.ttl @@ -0,0 +1,5 @@ + . + "JOHN". + . + "JANE". + . diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 5f6522fc..c0316f84 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -131,11 +131,18 @@ class SandboxTests extends FunSuite with Matchers { pending executeTest("sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl") } - test("sandbox/function_related/condition-on-po") { + test("sandbox/function_related/condition-on-po") { executeTest("sandbox/function_related/condition-on-po/mapping.rml.ttl") } + test("sandbox/function_related/condition-function-on-po") { + executeTest("sandbox/function_related/condition-function-on-po/mapping.ttl") + } + + + + From 942b5b4817630a0aeab8a324ce6e8757a8757d37 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 14:30:52 +0200 Subject: [PATCH 078/169] wip: feature func: logging to error when input parameter inconsistencies --- .../io/rml/framework/core/function/model/DynamicFunction.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala index 8875864b..cf49c974 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala @@ -104,6 +104,7 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten None } else { //TODO: complain about inputparams size != params ordered + logError(s"Not all input parameters for ${metaData.methodName} could be bound...") None } } From 9e27ec3a4748a5131bd7af8a36364820c5b92f21 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 14:55:36 +0200 Subject: [PATCH 079/169] wip: function feature: added test case: condition on mapping subject --- .../input.csv | 4 + .../mapping.ttl | 82 +++++++++++++++++++ .../output.ttl | 2 + .../scala/io/rml/framework/SandboxTests.scala | 4 + 4 files changed, 92 insertions(+) create mode 100644 src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/input.csv create mode 100644 src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl create mode 100644 src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/output.ttl diff --git a/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/input.csv b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/input.csv new file mode 100644 index 00000000..a87b05fc --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/input.csv @@ -0,0 +1,4 @@ +id +0 +"" +1 diff --git a/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl new file mode 100644 index 00000000..2b604e79 --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl @@ -0,0 +1,82 @@ +@prefix rr: . +@prefix rdf: . +@prefix rdfs: . +@prefix fnml: . +@prefix fno: . +@prefix d2rq: . +@prefix rml: . +@prefix ql: . +@prefix : . +@prefix grel: . +@prefix idlab-fn: . + +:map_person_0 rml:logicalSource :source_0. +:source_0 a rml:LogicalSource; + rml:source "sandbox/function_related/condition-on-mapping-subject-function/input.csv"; + rml:referenceFormulation ql:CSV. +:map_person_0 a rr:TriplesMap; + rdfs:label "person". +:s_0 a rr:SubjectMap. +:map_person_0 rr:subjectMap :s_0. +:s_0 a fnml:FunctionTermMap; + rr:termType rr:IRI; + fnml:functionValue :fn_0. +:fn_0 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_0. +:pomexec_0 rr:predicateMap :pmexec_0. +:pmexec_0 rr:constant fno:executes. +:pomexec_0 rr:objectMap :omexec_0. +:omexec_0 rr:constant "http://example.com/idlab/function/trueCondition"; + rr:termType rr:IRI. +:fn_0 rr:predicateObjectMap :pom_0. +:pom_0 a rr:PredicateObjectMap; + rr:predicateMap :pm_0. +:pm_0 a rr:PredicateMap; + rr:constant idlab-fn:strBoolean. +:pom_0 rr:objectMap :om_0. +:om_0 a rr:ObjectMap, fnml:FunctionTermMap; + fnml:functionValue :fn_1. +:fn_1 rml:logicalSource :source_0; + rr:predicateObjectMap :pomexec_1. +:pomexec_1 rr:predicateMap :pmexec_1. +:pmexec_1 rr:constant fno:executes. +:pomexec_1 rr:objectMap :omexec_1. +:omexec_1 rr:constant "http://example.com/idlab/function/notEqual"; + rr:termType rr:IRI. +:fn_1 rr:predicateObjectMap :pom_1. +:pom_1 a rr:PredicateObjectMap; + rr:predicateMap :pm_1. +:pm_1 a rr:PredicateMap; + rr:constant grel:valueParameter. +:pom_1 rr:objectMap :om_1. +:om_1 a rr:ObjectMap; + rml:reference "id"; + rr:termType rr:Literal. +:fn_1 rr:predicateObjectMap :pom_2. +:pom_2 a rr:PredicateObjectMap; + rr:predicateMap :pm_2. +:pm_2 a rr:PredicateMap; + rr:constant grel:valueParameter2. +:pom_2 rr:objectMap :om_2. +:om_2 a rr:ObjectMap; + rr:constant ""; + rr:termType rr:Literal. +:fn_0 rr:predicateObjectMap :pom_3. +:pom_3 a rr:PredicateObjectMap; + rr:predicateMap :pm_3. +:pm_3 a rr:PredicateMap; + rr:constant idlab-fn:str. +:pom_3 rr:objectMap :om_3. +:om_3 a rr:ObjectMap; + rr:template "http://world.org/person/{id}"; + rr:termType rr:Literal. +:pom_4 a rr:PredicateObjectMap. +:map_person_0 rr:predicateObjectMap :pom_4. +:pm_4 a rr:PredicateMap. +:pom_4 rr:predicateMap :pm_4. +:pm_4 rr:constant rdf:type. +:pom_4 rr:objectMap :om_4. +:om_4 a rr:ObjectMap; + rr:constant "http://schema.org/Person"; + rr:termType rr:IRI. + diff --git a/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/output.ttl b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/output.ttl new file mode 100644 index 00000000..5a58c399 --- /dev/null +++ b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/output.ttl @@ -0,0 +1,2 @@ + . + . diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index c0316f84..a80a41a9 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -140,6 +140,10 @@ class SandboxTests extends FunSuite with Matchers { executeTest("sandbox/function_related/condition-function-on-po/mapping.ttl") } + test("sandbox/function_related/condition-on-mapping-subject-function") { + executeTest("sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl") + } + From 7f823d7894e976ae7c1deae7983116b1be01b0b5 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 15:20:29 +0200 Subject: [PATCH 080/169] wip: #25 - RMLFNOTC0008-CSV working note: It was required to add the term type to the valueparameter's object. rr:objectMap [ rr:template "Name: {Name}" ; rr:termType rr:Literal ] ] Otherwise, the object's value would resolve to an invalid IRI. --- .../{failing => }/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl | 4 ++-- .../{failing => }/fno-testcases/RMLFNOTC0008-CSV/output.ttl | 0 .../fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak | 0 src/test/resources/report/static-fno/result.csv | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl (88%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0008-CSV/output.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak (100%) diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl similarity index 88% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl index 4dff2794..7cef47eb 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl @@ -7,7 +7,7 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . @base . @@ -33,7 +33,7 @@ rr:objectMap [ rr:constant grel:toUpperCase ] ] ; rr:predicateObjectMap [ rr:predicate grel:valueParameter ; - rr:objectMap [ rr:template "Name: {Name}" ] ] + rr:objectMap [ rr:template "Name: {Name}" ; rr:termType rr:Literal ] ] ] ] ]. diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak rename to src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak diff --git a/src/test/resources/report/static-fno/result.csv b/src/test/resources/report/static-fno/result.csv index b02e7b7d..3311ea7a 100644 --- a/src/test/resources/report/static-fno/result.csv +++ b/src/test/resources/report/static-fno/result.csv @@ -7,7 +7,7 @@ RMLFNOTC0004-CSV,passed RMLFNOTC0005-CSV,passed RMLFNOTC0006-CSV,passed RMLFNOTC0007-CSV,failed -RMLFNOTC0008-CSV,failed +RMLFNOTC0008-CSV,passed RMLFNOTC0009-CSV,failed RMLFNOTC0010-CSV,failed RMLFNOTC0011-CSV,failed From ecaa676f3761a75041cf27548f216bc61b28ec95 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 16:03:32 +0200 Subject: [PATCH 081/169] renamed doc header --- .../condition-on-mapping-subject-function/mapping.ttl | 1 + .../sandbox/function_related/controls_if_false/mapping.ttl | 2 -- .../sandbox/function_related/controls_if_true/mapping.ttl | 2 -- src/test/resources/sandbox/function_related/equal/mapping.ttl | 2 -- .../resources/sandbox/function_related/notEqual/mapping.ttl | 2 -- .../using_trueCondition_and_contains/mapping.ttl | 2 +- 6 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl index 2b604e79..97d49db0 100644 --- a/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl +++ b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl @@ -1,3 +1,4 @@ +# condition on subject map (id notEqual "") @prefix rr: . @prefix rdf: . @prefix rdfs: . diff --git a/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl index bd0b7447..6f5d517f 100644 --- a/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl +++ b/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl @@ -1,5 +1,3 @@ -# Function on graph, 1 parameter - @prefix rr: . @prefix foaf: . @prefix ex: . diff --git a/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl index 2bf0db03..4639c64e 100644 --- a/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl +++ b/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl @@ -1,5 +1,3 @@ -# Function on graph, 1 parameter - @prefix rr: . @prefix foaf: . @prefix ex: . diff --git a/src/test/resources/sandbox/function_related/equal/mapping.ttl b/src/test/resources/sandbox/function_related/equal/mapping.ttl index 1404099b..da3a3e3b 100644 --- a/src/test/resources/sandbox/function_related/equal/mapping.ttl +++ b/src/test/resources/sandbox/function_related/equal/mapping.ttl @@ -1,5 +1,3 @@ -# Function on graph, 1 parameter - @prefix rr: . @prefix foaf: . @prefix ex: . diff --git a/src/test/resources/sandbox/function_related/notEqual/mapping.ttl b/src/test/resources/sandbox/function_related/notEqual/mapping.ttl index 72420105..9dc4ac7f 100644 --- a/src/test/resources/sandbox/function_related/notEqual/mapping.ttl +++ b/src/test/resources/sandbox/function_related/notEqual/mapping.ttl @@ -1,5 +1,3 @@ -# Function on graph, 1 parameter - @prefix rr: . @prefix foaf: . @prefix ex: . diff --git a/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl b/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl index f68f4c3e..1878791c 100644 --- a/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl +++ b/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl @@ -1,4 +1,4 @@ -# generate triples using trueCondition and Equal +# generate triples using trueCondition and contains @prefix rr: . @prefix foaf: . From b34325b7d4b1c460f9e1f09b0f60ae41341d6ed8 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 16:04:03 +0200 Subject: [PATCH 082/169] updated README_Functions --- documentation/README_Functions.md | 61 +++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/documentation/README_Functions.md b/documentation/README_Functions.md index ee6792b9..fc0c0be7 100644 --- a/documentation/README_Functions.md +++ b/documentation/README_Functions.md @@ -1,10 +1,58 @@ +# README: Functions +## Test Cases +### FnO Tests +The official FnO testcases that are working can be found at `test/resources/fno-testcases`. + +### SandboxTests +> These tests are still experimental. + +The resources can be found at `test/resources/sandbox/function_related` and are executed from `io.rml.framework.SandboxTests`. +Every test output is compared to the RMLMapper's output (e.g. `output.ttl`) for that test. A test passes when its output is equal to the RMLMapper's output. +Tests marked as `pending` should be considered as not working.
+ +The sandbox testcases are +- `condition-function-on-po`: uses the functions + - `idlab-fn:trueCondition` + - `idlab-fn:stringContainsOtherString` + - `grel:toUpperCase` + +- `condition-on-mapping-subject-function`: uses the functions + - `idlab-fn:trueCondition` + - `idlab-fn:notEqual` + +- `condition-on-po`: uses the functions + - `idlab-fn:trueCondition` + - `idlab-fn:equal` + + +- `contains` uses function `grel:string_contains` + +- `controls_if_contains`: uses the functions + - `grel:controls_if` + - `grel:string_contains` + +- `controls_if_true`: uses the functions `grel:controls_if`. + +- `controls_if_false`: uses the functions `grel:controls_if` + +- `equal`: uses function `idlab-fn:equal` + +- `notEqual`: uses function `idlab-fn:notEqual` + +- `using_trueCondition_and_contains` + - `idlab-fn:trueCondition` + - `grel:string_contains` + +- `using_trueCondition_and_equal` + - `idlab-fn:trueCondition` + - `idlab-fn:equal` + + # Tutorial -> Under construction ## Using a function from a local JAR -The following testcases use the function `toUpperCaseURL`, which isn’t implemented yet: - +The following FnO-testcases use the function `toUpperCaseURL` - RMLFNOTC0004-CSV - RMLFNOTC0005-CSV - RMLFNOTC0006-CSV @@ -12,10 +60,12 @@ The following testcases use the function `toUpperCaseURL`, which isn’t impleme The following steps show how to integrate the `toUpperCaseURL` function in the RML Streamer. ### Step 1: creating the JAR -This step is based on best-practice example `grel-functions-java`. +This step is based on the best-practice example [`grel-functions-java`](https://github.com/FnOio/grel-functions-java). - Create package `io.fno.idlab` and within that package, create the class `IDLabFunctions` - For these testcases, we need a function that returns the given URL in uppercase. +- Make sure to set the Maven's compiler to a version compatible with the RMLStreamer's version. +The following listing serves a minimalistic example that shows a possible implementation of the `toUpperCaseURL`-function. ```Java package io.fno.idlab; @@ -91,3 +141,6 @@ to load and bind every function as specified in the testcase's `mapping.ttl`. +# Remarks +- When the RMLStreamer is unable to find a function description or function mapping, bind method parameters to values, it will be logged as an error to the console. + \ No newline at end of file From cced9d7ca5c7094dbc2699508c5d51202eb44732 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 16:08:21 +0200 Subject: [PATCH 083/169] added functions_idlab.ttl to default function description files --- .../scala/io/rml/framework/core/function/FunctionLoader.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index eb0e3638..f7698f1d 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -80,7 +80,8 @@ object FunctionLoader extends Logging{ private var singletonFunctionLoader : Option[FunctionLoader] = None private val defaultFunctionDescriptionFilePaths = List( - "functions_grel.ttl" + "functions_grel.ttl", + "functions_idlab.ttl" ) /** From 5505a6f65fac1e85832dd7356d77194f4ad523b8 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 16:16:50 +0200 Subject: [PATCH 084/169] update functions readme --- documentation/README_Functions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/README_Functions.md b/documentation/README_Functions.md index fc0c0be7..27bff65c 100644 --- a/documentation/README_Functions.md +++ b/documentation/README_Functions.md @@ -48,9 +48,9 @@ The sandbox testcases are - `idlab-fn:equal` -# Tutorial -## Using a function from a local JAR + +## Tutorial: Using a function from a local JAR The following FnO-testcases use the function `toUpperCaseURL` - RMLFNOTC0004-CSV @@ -63,7 +63,7 @@ The following steps show how to integrate the `toUpperCaseURL` function in the R This step is based on the best-practice example [`grel-functions-java`](https://github.com/FnOio/grel-functions-java). - Create package `io.fno.idlab` and within that package, create the class `IDLabFunctions` - For these testcases, we need a function that returns the given URL in uppercase. -- Make sure to set the Maven's compiler to a version compatible with the RMLStreamer's version. +- Make sure to set the Maven compiler to a version compatible with the RMLStreamer's version. The following listing serves a minimalistic example that shows a possible implementation of the `toUpperCaseURL`-function. ```Java From 583e354b50eaa8758d0d1c61e8cce0f0438c11ff Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Sun, 21 Jun 2020 16:35:34 +0200 Subject: [PATCH 085/169] prep for merge with development #25 constructor can be set to private (singleton) removed unused classes --- .../extractors/FunctionMapExtractor.scala | 2 - .../std/StdFunctionMapExtractor.scala | 4 +- .../core/function/model/Parameter.scala | 2 +- .../core/function/std/StdFunctionLoader.scala | 2 +- .../core/model/FunctionMapping.scala | 44 ------------------- .../core/model/std/StdFunctionMapping.scala | 7 --- .../rml/framework/engine/Transformation.scala | 37 ---------------- .../FunctionMapGeneratorAssembler.scala | 1 - .../scala/io/rml/framework/SandboxTests.scala | 3 -- 9 files changed, 3 insertions(+), 99 deletions(-) delete mode 100644 src/main/scala/io/rml/framework/core/model/FunctionMapping.scala delete mode 100644 src/main/scala/io/rml/framework/core/model/std/StdFunctionMapping.scala delete mode 100644 src/main/scala/io/rml/framework/engine/Transformation.scala diff --git a/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala index 126922cb..9fb1d071 100644 --- a/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala @@ -38,8 +38,6 @@ trait FunctionMapExtractor extends TermMapExtractor[List[FunctionMap]] { override def extract(node: RDFResource): List[FunctionMap] - - def loadFunctionsIntoEnvironment():Unit } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala index dd569fbf..31f0a2fd 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala @@ -49,7 +49,5 @@ class StdFunctionMapExtractor(subjectMapExtractor: SubjectMapExtractor, result } - override def loadFunctionsIntoEnvironment(): Unit = { - throw new NotImplementedError() - } + } diff --git a/src/main/scala/io/rml/framework/core/function/model/Parameter.scala b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala index 5dfcc09a..1852f714 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Parameter.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala @@ -21,7 +21,7 @@ abstract class Parameter extends Node { * Models the parameters used by the functions. * * `paramType` type of the parameter - * `paramUri` Uri representation of the parameter (as defined in functions.ttl) + * `paramUri` Uri representation of the parameter * `paraValue` [[String]] representation of the parameter * `position` [[Int]] position of the parameter in the argument of the function needed for reflection * diff --git a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala index 3c38e7a8..941e24b9 100644 --- a/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala @@ -9,7 +9,7 @@ import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.shared.{FnOException, RMLException} -case class StdFunctionLoader(functionDescriptionTriplesGraph : RDFGraph) extends FunctionLoader { +case class StdFunctionLoader private (functionDescriptionTriplesGraph : RDFGraph) extends FunctionLoader { override def parseFunctionMapping(graph: RDFGraph): FunctionLoader = { logDebug("parsing functions the new way (i.e. using StdFunctionLoader)") diff --git a/src/main/scala/io/rml/framework/core/model/FunctionMapping.scala b/src/main/scala/io/rml/framework/core/model/FunctionMapping.scala deleted file mode 100644 index 73c4eb02..00000000 --- a/src/main/scala/io/rml/framework/core/model/FunctionMapping.scala +++ /dev/null @@ -1,44 +0,0 @@ -package io.rml.framework.core.model - -import io.rml.framework.core.function.FunctionLoader -import io.rml.framework.core.model.std.StdFunctionMapping - - -trait FunctionMapping extends Graph { - - /** - * A transformation loader object which contains information - * in the mapping document to load function dynamically. - * - * Note: Functions are not loaded from the libraries - * at the moment of initialization of the [[FunctionLoader]]. - * It only has information on library path and classes containing - * the function. - * Functions will be loaded on demand when reading through the - * RML mapping file. - * - * @return - */ - def functionLoader: FunctionLoader - - -} - -object FunctionMapping { - - //TODO: Temporary solution to passing the mapping object to function map extractors! - // Need refactoring! - private var mapping: Option[FunctionMapping] = None - - - def getOpt: Option[FunctionMapping] = { - mapping - } - - def apply(identifier: String, functionLoader: FunctionLoader): FunctionMapping = { - val defMapping = StdFunctionMapping(identifier, functionLoader) - mapping = Some(defMapping) - defMapping - - } -} diff --git a/src/main/scala/io/rml/framework/core/model/std/StdFunctionMapping.scala b/src/main/scala/io/rml/framework/core/model/std/StdFunctionMapping.scala deleted file mode 100644 index 7a21f235..00000000 --- a/src/main/scala/io/rml/framework/core/model/std/StdFunctionMapping.scala +++ /dev/null @@ -1,7 +0,0 @@ -package io.rml.framework.core.model.std - -import io.rml.framework.core.function.FunctionLoader -import io.rml.framework.core.model.FunctionMapping - -case class StdFunctionMapping(identifier: String, functionLoader: FunctionLoader) extends FunctionMapping { -} diff --git a/src/main/scala/io/rml/framework/engine/Transformation.scala b/src/main/scala/io/rml/framework/engine/Transformation.scala deleted file mode 100644 index 87f403de..00000000 --- a/src/main/scala/io/rml/framework/engine/Transformation.scala +++ /dev/null @@ -1,37 +0,0 @@ -/** - * MIT License - * - * Copyright (C) 2017 - 2020 RDF Mapping Language (RML) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **/ -package io.rml.framework.engine - -import io.rml.framework.core.model.{Entity, Parameters, Uri} - -trait Transformation { - - def name: Uri - - def execute(parameters: Parameters): Option[Entity] - -} - - diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index eb4b28c2..7c17df54 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -97,7 +97,6 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { parameterName -> parameterValue }) .toMap - //throw new NotImplementedError() function.initialize() function.execute(args) } diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index a80a41a9..c1e0e8c0 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -38,9 +38,6 @@ import org.scalatest.{DoNotDiscover, FunSuite, Matchers} class SandboxTests extends FunSuite with Matchers { - val functionFile = new File(getClass.getClassLoader.getResource("functions.ttl").getFile) - - private def executeTest(mappingFile: String): Unit = { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.org/base/")) implicit val env = ExecutionEnvironment.getExecutionEnvironment From 90f0804cb494f65cab2e594586f88ba3e1535689 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 23 Jun 2020 11:51:33 +0200 Subject: [PATCH 086/169] CR: MappingExtractor, unused cls argument RQ: Why has cls the Any type if it's supposed to be a mapper? And is that argument used at all? RA: The `cls` argument seems to be pointless, actually. CR: unused FunctionMapExtractor argument RQ: Is there ever a FunctionMapExtractor given as argument, or would that be so in the future? If not, maybe add it as constructor in the next line ... RA: I think I added this with the idea to support both old and new FnO versions. The argument can be removed as it isn't really used. CR: adding classname to debug statements isn't necessary RQ: A general comment to statements like this one: is it necessary to add the classname? I guess log4j can be configured to print it.. RA: Indeed, I wasn't aware of that when I was writing that :p CR: analoguous to ff9443a34a843f2ee6de86cb58a6f9a620100468 CR: checking whether a resource is a Triples Map RQ: Be careful here: a predicate-object map is not required for a triples map, according to the spec. So if this code is used to check if a mapping is correct, then the code is wrong. If the code is only used to check wheter triples will be generated, then this is correct behaviour (since no triples will be generated if no predicate-object map is present, so this triples map can be omitted). However, please adjust the comments to clarify if the latter is the case. RA: The idea was to filter out triples maps resources from a given RDFGraph because, initially, the method `filterTriplesMaps` filtered triples maps in a graph based on two conditions; 1. the resource's class is a TriplesMap, 2. the resource has a logical source property. ```scala val typeUri = Uri(RMLVoc.Class.TRIPLESMAP) val triplesMapResources = (graph.filterResources(typeUri) ++ graph.filterProperties(Uri(RMLVoc.Property.LOGICALSOURCE))).distinct ``` However, this resulted in errors when processing a Function Map, because a Function Map can also have a logical source property defined. In a later processing step this would cause errors because the RML Streamer would try to extract a subject map from the so-called Triples Map. > In the case of [r2]rml, Term Maps determine how to generate an rdf term relying on references to raw data. Therefore, a new type of Term Map was introduced, the Function Map (`fnml:FunctionMap`, Listing 3: line 10). A Function Map is a Term Map generated by executing a function, instead of using a constant or a reference to the raw data values. In contrast to an RDF Term Map that uses values referenced from a Logical Source to generate an rdf term, a Function Map uses values referenced from a Logical Source to execute a function. Article: [Declarative Data Transformations for Linked Data Generation: the case of DBpedia](https://biblio.ugent.be/publication/8525863/file/8525869) Therefore, I changed `filterTriplesMaps` to do the following 1. filter out resources having a logical source (these are the `potentialTriplesMapResources`) 2. filter out resources that meet the requirements of a Triples Maps defined by the spec ```scala val logicalSourcePropertyUri = Uri(RMLVoc.Property.LOGICALSOURCE) val potentialTriplesMapResources = graph.filterProperties(logicalSourcePropertyUri) val triplesMapResources = potentialTriplesMapResources.filter(isTriplesMap) ``` However, as you suggested, the check in `isTriplesMap` regarding the predicate-object maps was not correct. You are right about the predicate-object maps. A triples map can indeed contain zero or more predicate-object maps. Fix: `isTriplesMap` doesn't check the presence of predicate-object map resources because a triples map can contain zero or more. Furthermore, the checks for logical source and subject subjectmap are now more stringent by checking whether there's exactly one of both. Also, the shortcut for subjectmap is also being detected now. CR: removed unused commented code CR: removal of xsd:number RQ: If XML Schema doesn't define a xsd:number then remove it. Maybe grel.ttl needs an update. Or maybe a number is defined in another namespace? Anyway, I think number and decimal are the same in this case. CR: unused class --- .../core/extractors/MappingExtractor.scala | 10 --- .../core/extractors/MappingReader.scala | 7 +- .../core/extractors/ObjectMapExtractor.scala | 4 +- .../extractors/PredicateMapExtractor.scala | 3 +- .../std/StdFunctionMapExtractor.scala | 2 +- .../std/StdObjectMapExtractor.scala | 2 +- .../std/StdPredicateObjectMapExtractor.scala | 10 +-- .../std/StdTriplesMapExtractor.scala | 18 +++-- .../core/function/FunctionUtils.scala | 1 - .../function/model/FunctionMetaData.scala | 7 +- .../core/model/rdf/jena/JenaResource.scala | 9 +-- .../framework/core/vocabulary/RMLVoc.scala | 4 +- .../PredicateObjectGeneratorAssembler.scala | 2 +- .../statement/StatementsAssembler.scala | 2 +- .../framework/flink/sink/FlinkResource.scala | 70 ------------------- 15 files changed, 26 insertions(+), 125 deletions(-) delete mode 100644 src/main/scala/io/rml/framework/flink/sink/FlinkResource.scala diff --git a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala index d8dd4e86..8cc44527 100644 --- a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala @@ -31,15 +31,5 @@ import io.rml.framework.core.model.{Graph, RMLMapping} trait MappingExtractor [+T<: Graph]extends GraphExtractor[T] object MappingExtractor { - - // todo: can this be safely deleted? def apply(): MappingExtractor[RMLMapping] = new StdMappingExtractor() - - def apply [T<:Graph](cls: Any): MappingExtractor[Graph] = { - cls match{ - case RMLMapping => new StdMappingExtractor() - case _ => throw new IllegalArgumentException("Given args can only be subclasses of Mapping") - } - - } } diff --git a/src/main/scala/io/rml/framework/core/extractors/MappingReader.scala b/src/main/scala/io/rml/framework/core/extractors/MappingReader.scala index 1255b6de..d3ed1f04 100644 --- a/src/main/scala/io/rml/framework/core/extractors/MappingReader.scala +++ b/src/main/scala/io/rml/framework/core/extractors/MappingReader.scala @@ -63,16 +63,11 @@ trait MappingReader[+OUT] { * Object with factory apply method for MappingReader. */ object MappingReader { - def apply(mappingExtractor: MappingExtractor[Graph] = MappingExtractor(RMLMapping)): MappingReader[Graph] = { + def apply(mappingExtractor: MappingExtractor[Graph] = MappingExtractor()) = { lazy val reader = new StdMappingReader(mappingExtractor) reader } -// def apply(mappingExtractor: MappingExtractor[Graph] = MappingExtractor()) -// : MappingReader[Graph] = { -// lazy val reader = new StdMappingReader(mappingExtractor) -// reader -// } } diff --git a/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala index 8ebbe5b9..707d8cff 100644 --- a/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala @@ -30,7 +30,5 @@ import io.rml.framework.core.model.ObjectMap trait ObjectMapExtractor extends TermMapExtractor[List[ObjectMap]] object ObjectMapExtractor { -// def apply(): ObjectMapExtractor = new StdObjectMapExtractor -def apply(functionMapExtractor: FunctionMapExtractor = FunctionMapExtractor()): ObjectMapExtractor = - new StdObjectMapExtractor(functionMapExtractor) + def apply(): ObjectMapExtractor = new StdObjectMapExtractor(FunctionMapExtractor()) } diff --git a/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala index fab6fd3a..0b1cb348 100644 --- a/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala @@ -31,8 +31,7 @@ import io.rml.framework.core.model.PredicateMap trait PredicateMapExtractor extends TermMapExtractor[List[PredicateMap]] object PredicateMapExtractor { - def apply(functionMapExtractor: FunctionMapExtractor = FunctionMapExtractor()): PredicateMapExtractor = new StdPredicateMapExtractor(functionMapExtractor) - //def apply(): PredicateMapExtractor = new StdPredicateMapExtractor() + def apply(): PredicateMapExtractor = new StdPredicateMapExtractor(FunctionMapExtractor()) } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala index 31f0a2fd..e8991cab 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala @@ -21,7 +21,7 @@ class StdFunctionMapExtractor(subjectMapExtractor: SubjectMapExtractor, * @return */ override def extract(node: RDFResource): List[FunctionMap] = { - this.logDebug("%s extract(node)".format(this.getClass.getName)) + this.logDebug("extract(node)") extractFunctionMap("", node) } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala index be3c2fb5..4e530017 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala @@ -69,7 +69,7 @@ class StdObjectMapExtractor(stdFunctionMapExtractor: FunctionMapExtractor) exten * @return */ private def extractObjectMaps(resource: RDFResource): List[ObjectMap] = { - this.logDebug("%s extractObjectMaps(resource)".format(this.getClass.getName)) + this.logDebug("extractObjectMaps(resource)") val property = RMLVoc.Property.OBJECTMAP val properties = resource.listProperties(property) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala index 1d1f2f7f..43fd83c7 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala @@ -73,19 +73,19 @@ class StdPredicateObjectMapExtractor(predicateMapExtractor: PredicateMapExtracto * @return */ private def extractPredicateObjectMap(resource: RDFResource): PredicateObjectMap = { - this.logDebug("%s extractPredicateObjectMap : extracting object maps".format(this.getClass.getName)) + this.logDebug("extractPredicateObjectMap : extracting object maps") val objectMaps = objectMapExtractor.extract(resource) - this.logDebug("%s extractPredicateObjectMap : extracting function maps".format(this.getClass.getName)) + this.logDebug("extractPredicateObjectMap : extracting function maps") val functionMaps = functionMapExtractor.extract(resource) // TODO: not used. can be removed? - this.logDebug("%s extractPredicateObjectMap : extracting predicate maps".format(this.getClass.getName)) + this.logDebug("extractPredicateObjectMap : extracting predicate maps") val predicateMaps = predicateMapExtractor.extract(resource) - this.logDebug("%s extractPredicateObjectMap : extracting graph map".format(this.getClass.getName)) + this.logDebug("extractPredicateObjectMap : extracting graph map") val graphMap = graphMapExtractor.extract(resource) - this.logDebug("%s extractPredicateObjectMap : returning resulting PredicateObjectMap".format(this.getClass.getName)) + this.logDebug("extractPredicateObjectMap : returning resulting PredicateObjectMap") PredicateObjectMap(resource.uri.toString, objectMaps, predicateMaps, graphMap) } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala index db1ff2b2..a84fc732 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala @@ -46,25 +46,29 @@ class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, * Helper method for inferring whether the given resource is a TriplesMap. * A resource can be considered a TriplesMap when any of the following conditions are met * 1. (trival case) the resource has the TriplesMap type - * 2. the resource has the properties: logicalSource, subjectMap, predicateObjectMap + * 2. the resource references the following resources: + * - exactly ONE logicalSource, specified by rml:logicalSource. + * - exactly ONE subjectMap. It may be specified in two ways + * - a) using rr:subjectMap + * - b) using constant shortcut property rr:subject * @param resource * @return [Boolean] indicating whether the resource is a TriplesMap */ private def isTriplesMap(resource : RDFResource) : Boolean = { val logicalSourceProperty = RMLVoc.Property.LOGICALSOURCE val subjectMapProperty = RMLVoc.Property.SUBJECTMAP - val predicateObjectMapProperty =RMLVoc.Property.PREDICATEOBJECTMAP + val subjectConstantProperty = RMLVoc.Property.SUBJECT // trivial case val isTriplesMap = resource.getType == Some(Uri(RMLVoc.Class.TRIPLESMAP)) - // required properties for being a triplesmap - val hasLogicalSource = !resource.listProperties(logicalSourceProperty).isEmpty - val hasSubjectMap = !resource.listProperties(subjectMapProperty).isEmpty - val hasPredicateObjectMap = !resource.listProperties(predicateObjectMapProperty).isEmpty + // property requirements for a triplesmap + val hasExactlyOneLogicalSource = resource.listProperties(logicalSourceProperty).length==1 + val hasExactlyOneSubjectMap = + (resource.listProperties(subjectMapProperty) ++ resource.listProperties(subjectConstantProperty)).length==1 // infer whether the resource is a triples map - val resourceIsTriplesMap = isTriplesMap|(hasLogicalSource&hasSubjectMap&hasPredicateObjectMap) + val resourceIsTriplesMap = isTriplesMap|(hasExactlyOneLogicalSource&hasExactlyOneSubjectMap) resourceIsTriplesMap } /** diff --git a/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala index aae8c1d9..54a78528 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala @@ -63,7 +63,6 @@ object FunctionUtils extends Logging { case Uri(RMLVoc.Type.XSD_POSITIVE_INTEGER) => classOf[Int] case Uri(RMLVoc.Type.XSD_INTEGER) => classOf[Int] case Uri(RMLVoc.Type.XSD_INT) => classOf[Int] - case Uri(RMLVoc.Type.XSD_NUMBER) => classOf[Int] // see todo @ RMLVoc.Type case Uri(RMLVoc.Type.XSD_STRING) => classOf[String] case Uri(RMLVoc.Type.XSD_DOUBLE) => classOf[Double] case Uri(RMLVoc.Type.XSD_BOOLEAN) => classOf[Boolean] diff --git a/src/main/scala/io/rml/framework/core/function/model/FunctionMetaData.scala b/src/main/scala/io/rml/framework/core/function/model/FunctionMetaData.scala index dbf0e779..2680dd24 100644 --- a/src/main/scala/io/rml/framework/core/function/model/FunctionMetaData.scala +++ b/src/main/scala/io/rml/framework/core/function/model/FunctionMetaData.scala @@ -5,9 +5,7 @@ import java.lang.reflect.Method import io.rml.framework.core.model.{Entity, Uri} /** - * A case class which is made to hold the string values of class and method names - * of a [[Function]] so that it can be initialized lazily later when needed in the rml mapping file - * [Dev note ~ SMO] Only contains string data like, function name, class name, source jar file name + * Contains metadata of a function that can be called by an RML Mapping. * * @param source string path of the source * @param className class name containing the [[Function]] @@ -22,8 +20,5 @@ case class FunctionMetaData(source: String, className: String, methodName: Strin * * @return */ - //override def identifier: String = s"($source, $className, $methodName, $inputParam, $outputParam)" - - def identifier: String = s"($source, $className, $methodName, $inputParam, $outputParam)" } diff --git a/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala b/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala index 1a47ecd8..3ee864c9 100644 --- a/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala +++ b/src/main/scala/io/rml/framework/core/model/rdf/jena/JenaResource.scala @@ -134,14 +134,7 @@ class JenaResource(val resource: Resource) extends RDFResource { None } } -// // check if there are type statements, or else return None -// if (types.size != 1) return None -// // if there is a type statement, make sure this is a Resource and that there is only one in total -// require(types.head.isInstanceOf[RDFResource], "Type must be a resource.") -// -// // TODO: what if there are multiple types? -// -// Some(types.head.asInstanceOf[RDFResource].uri) + } override def getList: List[RDFNode] = { diff --git a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala index b88d38f6..808251bb 100644 --- a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala +++ b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala @@ -34,9 +34,6 @@ object RMLVoc { val XSD_STRING = Namespaces("xsd", "string") val XSD_INT = Namespaces("xsd", "int") // signed 32-bit integer val XSD_INTEGER = Namespaces("xsd", "integer") // integer value - // TODO: xsd:number isn't defined in the XML Schema; however it's being used by grel.tll - // Therefore, this "Type" is added as a temporary solution - val XSD_NUMBER = Namespaces("xsd", "number") val XSD_DOUBLE = Namespaces("xsd", "decimal") val RDF_LIST = Namespaces("rdf", "List") val XSD_POSITIVE_INTEGER = Namespaces("xsd", "positiveInteger") @@ -59,6 +56,7 @@ object RMLVoc { val OBJECTMAP = Namespaces("rr", "objectMap") val TRIPLESMAP = Namespaces("rr", "triplesMap") val SUBJECTMAP = Namespaces("rr", "subjectMap") + val SUBJECT = Namespaces("rr", "subject") val CONSTANT = Namespaces("rr", "constant") val TEMPLATE = Namespaces("rr", "template") val TERMTYPE = Namespaces("rr", "termType") diff --git a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala index 85384028..f71131a3 100644 --- a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala @@ -35,7 +35,7 @@ class PredicateObjectGeneratorAssembler(predicateGeneratorAssembler: PredicateGe def assemble(predicateObjectMap: PredicateObjectMap) : List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]], Item => Option[Iterable[Uri]])] = { - this.logDebug("%s assemble (predicateObjectMap)".format(this.getClass.getName)) + this.logDebug("assemble (predicateObjectMap)") val graphStatement = graphGeneratorAssembler.assemble(predicateObjectMap.graphMap) predicateObjectMap.predicateMaps.flatMap(predicateMap => { diff --git a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala index 97b0e544..0bb86252 100644 --- a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala @@ -44,7 +44,7 @@ extends Logging{ * @return */ def assembleStatements(triplesMap: TriplesMap): List[(Item => Option[Iterable[TermNode]], Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]], Item => Option[Iterable[Uri]])] = { - this.logDebug("%s assembleStatements(triplesmaps)".format(this.getClass.getName)) + this.logDebug("assembleStatements(triplesmaps)") val subjectGraphGenerator = graphAssembler.assemble(triplesMap.subjectMap.graphMap) diff --git a/src/main/scala/io/rml/framework/flink/sink/FlinkResource.scala b/src/main/scala/io/rml/framework/flink/sink/FlinkResource.scala deleted file mode 100644 index a6e7aa4a..00000000 --- a/src/main/scala/io/rml/framework/flink/sink/FlinkResource.scala +++ /dev/null @@ -1,70 +0,0 @@ -/** - * MIT License - * - * Copyright (C) 2017 - 2020 RDF Mapping Language (RML) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **/ -package io.rml.framework.flink.sink - -import io.rml.framework.core.model.rdf.{RDFLiteral, RDFNode, RDFResource} - -class FlinkResource extends RDFResource { - /** - * - * @param property - * @return - */ - override def listProperties(property: String) = ??? - - /** - * - * @param property - * @param resource - */ - override def addProperty(property: String, resource: String) = ??? - - /** - * - * @param property - * @param resource - */ - override def addProperty(property: String, resource: RDFResource) = ??? - - /** - * - * @param property - * @param literal - */ - override def addLiteral(property: String, literal: String) = ??? - - /** - * - * @param property - * @param literal - */ - override def addLiteral(property: String, literal: RDFLiteral) = ??? - - override def uri = ??? - - override def getType = ??? - - override def getList: List[RDFNode] = ??? -} From d4bc26f9c87120b60b5f24b0eb59fdef2de1ee2c Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 23 Jun 2020 13:35:02 +0200 Subject: [PATCH 087/169] removed bak files --- src/main/resources/GrelFunctions.jar.bak | Bin 287602 -> 0 bytes .../RMLFNOTC0007-CSV/output.ttl.bak | 0 .../RMLFNOTC0012-CSV/output.ttl.bak | 0 .../RMLFNOTC0014-CSV/output.ttl.bak | 1 - .../RMLFNOTC0015-CSV/output.ttl.bak | 1 - .../RMLTC0010c-CSV/mapping.ttl.bak | 23 ---- .../RMLTC0010c-JSON/mapping.ttl.bak | 24 ---- .../RMLTC0010c-XML/mapping.ttl.bak | 24 ---- .../RMLFNOTC0008-CSV/output.ttl.bak | 1 - .../condition-function-on-po/mapping.ttl.bak | 126 ------------------ 10 files changed, 200 deletions(-) delete mode 100644 src/main/resources/GrelFunctions.jar.bak delete mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/output.ttl.bak delete mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/output.ttl.bak delete mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/output.ttl.bak delete mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/output.ttl.bak delete mode 100644 src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak delete mode 100644 src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak delete mode 100644 src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl.bak diff --git a/src/main/resources/GrelFunctions.jar.bak b/src/main/resources/GrelFunctions.jar.bak deleted file mode 100644 index 9094cba8d5c1814ba09f143a5542fe5d30b9a497..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 287602 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 %UxyrTG z@}_xPvshMt#d~L^J5mc$RxF4*G`R?^Zj}Q@%xj*gxf3`$YJMY> z`$nnis|lb6nP_n*BC8ii3u5*5aQ_H;G8#inLr9!X<=^V6OZQob2T5piDzK);}ppy}?oJE?(%Cl6>Nu922_FNH{@DDJxOa+M4Dkq(Srfp!3 zBs%t#L609Ii_7?~x76#o)Z?l3*49X+ZZA@P8gTO=xQEH5p!t_O0y@iT=lRq%N+ma| zie$nWnK&fM8Tq%=T0Z?K|783-uV*#f=#0hij7loydjfr2&uX7k%7;7@Pd_A9EE6uQ z9FJy%@?D6WC)ACjh9JW5>-V5V00GA$p+3o8F$lhg+seRkY5*lzFY z@$?VB5&Bl{6QcG=F!_v8cC9_E_BWx7ou5`cRkvgmSe|g0{2v{LmeRDeR;T#qWQCXMf9L}uuB94Y@; z*@?RxNG+?C!R3^dPEp99cL@c^{zIs@D5{NQQWxQnDeQ)RyPcY|yCXSqee54;Ru7k5 zozJX%991SIx=IzO!{ywONT0*5eh{VBvge~}rqZm|g0!fQYEvEBplfvICY5rMK)+^m zhANdpDwT33m6AiD3REo~T?eSO%+srDgv+J0eM~9&A2Oo=*mJESnOOQGKq9>!ySj5I zKwV5J|Dh5{95kyqOQfFo=rpV5l0Zk@68d?u;-KkN?!cPj#=a(b9Gp|Mx}kA$P^0xt zVI9|g<5WnT`5t-C$wR5=nL5h-Jq&9jhqLz;DOOUrZ-W{d3m;@ZnH-UU#iq(kc4)%| zmC)fCcB$GK^wk~YyWvW+n)&xUnQjw?rBD8r`X>#V`}wLYTl-jbd2180MaaKqN2dg(LI)E!(^x@8k`>$q*8XGg;CJxjjZoC!U3A7#|Nr z=EBp~HZ{8lI4t@svt&Kva??|jIR6|}W1C*3-g`WgVzkIpDVHcLdJqkB#VS1e_#m+)}G)-MWnVk_IomD_tn1$S2|Lle|3wpvaXY z`a`Hln9E2M_hzctD3_5O@El8*=ow|2i{)6cub6TFZ8SN|9BnkW!^j!FxEHR3m zLP$;@0K3Sj3hq!D_~~??qn<@ro=cYla4lw%}(BmjOxxXNy!a z#DSFIDs1fIBt+sSW@staHo^9w!Q7(T{HW9tNje?9TFZP=9J9GUw02;+)(n08XTH zM84N1__kOdnT!sfr&947#MpM_qa%seJrfWKgx}Q=Xg^y`L-^p~HTCQq8eLTzIq}!t zq14_fWJRE zkKHc9sZWQ?jAp0MsnWtMAd5C3Di-%7q4v<-*vT?a@my~4UjO8Z0w3d?HOzgg4i59m zNsf9WsHXX3;+6KpDv?f}wMO4z@CR8ko6pEX>GEIFO4D)e47N~8lNWcPPp8?-Lz6cK zZl1n-*XG^Zas&coa2Coz9#E)P=6&1JoQwP!vollI3aC=)o9av75P6k}gxEeAacfnz za)-$fICLhmTA1~w-|<++ifvaJYfRvfE2NPd3HgrxdDoHoAz919`~20{0rCBOhz4@& zb-U+|nYzt`khcS0ImCn4)<6`x9bdKf9*Zc}F3bbS=m#wUn&3&EKrcY+Hnu2y0EqP$W*d2UYr#-FMo9X_06d6>*dy@mLo5f&#;vFW8`4`BvP zODy^*sKgyun-S)%OH2G}waKuzyY+{5L|%tuokK}Zd|aM4h)}R9bn6TSz?PjmV3p(^ zN+P6ChXKyd3!khm9l2NvBpgvxo^v+1-ou{%(c}9p8t>2)`~;_T0dX4(*o`;`t(&Qt`IK=puCyH3HzF{Nn^JCU6}-`3${bFdEzK1wv3g|!uc|hEetv_18y!pbsO(DD(h{L_X z5A^v{e!QC0WU0)&+n|O@4+)~vFxkW4FqQ_ z58wIyjjey(xwEY{g`qx?kbx(BgE|RC$^C;GLlC?|(oQik_hMLSDJc^Rs0!#PD8p1J zjYq=ILLwgGMIF*a{Y4+{T0x?DgFYw9!F~%WCxGuU5X({lu~5sF0kJ?xOsiy)1ckzy ziHKnYLU5YdG(XJptx@m?MN~doreHEQ)Z{tQ4CqlpKsM~?3Lsm&kLo~$`)Q8SIR)TQ zhwwC3+dq{odVwLjMaF&P;yGP?jt#EB1S2afBsMcD^0}SfV)EB?>0`8U>=2aiYmnX=NC8(3fbei96 z+5oq6gOK}(Bi%vIdb-+xgz^X-`V=3+8^$mW>XfbdhIQQ&MpQTk&=iL9WW#=>2X%S? zx@kqkbJizkIB<*CnLNRq3IJ=zHwJ=vRa4?G_Q^PhW@7+j|; z+#A=QE!{pizb`k{s;Doh(PA)f*a5yspecwu-tNv2{`bJ{ckIA-c&K;v;qESG=q;vh zKMeQ!EW^}7-y(vKMMrWLmU9{woE?@#iGnXdOh#n*lWrvf@Fz@k zmE`Qvx!&VLDg=p69g1$v&>Zn&fDvhq1~Ei=!UFgZ=SKhvkhiQdtSWQ^1PVg7Gz3)Q za2>jEuWoe7!P#Yh`?E5$v>%x4U-_a2@UZfZ0Xl|QO~pgS#7N5At+D8>_--` z%Xa^<+L*3*LTRrCp_K3fYYCF^gKBY-%>azwr|~I|%n+W8sgIg;VO~)Q!D58qI?5vt z7=dGpL&Y<3gYMwYxr?RG2TRgzBQDAILf<9}U84yf?}JHv=%zKHd~v5M0`-H3t3~&0 z=#bZtW85GU$mvN1)Yt22x&van&Cxnl+hjl0uElk38P8V&Qrz#)KFtx~X5u-~FgcfaYcJ?>VqY$4IvCoeva zRmG5tmDaSJJnHN_ldd^GpLB0zj=IpSk7o;*dtsuQy?_Z;OJtN*Bse{Bams37LV_+G z$8~E!Q*-TJT4-&5T4fYHWk0lB$~zsZzs`6nfFgFb85$+E6gx&`qXNA##BZ zp@(<3j>Wm9bw?ecYb0l#DwAD* z^HjE{qGhH}4ErWAGhAvp8WW`qTK%k%)o+ch)rAn~);zCwv^&BT^ z>0wnwn+TS_su&7VZ|05lW%u~e{04zBVkbp}`%Y=dfO;0ReCL}<_1>NgXFJhXdcaO6 z8ml<%w=s4O#kD0YjE39mpmEA;X>K2T^$`QChzFfDPj>XwUW?PiX)$L$T05RDe&| z#>!19YV+u{6vyF^Ld2i9Mu>|92QLf@n#=2YExt3Uo$Zz{quYk6-Kv)I!Ke$Xs=3Li zy8z1-^2-;*7W{rky?#wsYWOU*P^Yv2r#?kj?p0L2qM{zBsGJXdS|a9YM~u2uLd03ls+{TlIzD2QP|vEjZdF_OLh^IAw;aBO{*KDEw;U*{!4&Wjk<)9axk;&W0O`3O zf37HsBdhZO?Aa;?3q*=)t4XJ@PFhX*b)ixpZ8I88)yl{F2;EQb%gK825@yDR$$T+A z3)1EQNAyH^9YJB=4Jfw??xzjU==@}b5M%)YGPO|*o{pL12y#sL*^7B08)V_vdom+> zOY`^RZy`^HBHwn*9wXDDc04KAZ%(x-{36q(;T{v0*Vaa8N;B}ogO6F@GwE~Dm62cQ z$IA`NE$dWjQp%ctrL_hhJ0ND#Zz3zNK&g-8(&yHxIB}^up-$}wAEVPdy@32q?i`wu0^7IM?*vyI1TYCN)46{m51F3HvWn`hP7 zc>1-_>y2BLu51_>+!@K;g6#LyZvamfk;PFd6j7#tD4+a-jnOE(F{h=5oGD271p_Zm zbz4;BYiRYoYxe6>cgc0N$=-(3;%kUh;kiWjx#5zdl54a}4Ewvp<%|5casQ?Jn-UIf zE+gS~>pqp;Ki{5>G`x$Kldw+F6Bw+>f!at9uzZNkz9jo;iH3(}^h1B@sQGNAUxvC8 z)4w4Y8_>)5{`OT5610lFZZmv=<2VR6jeEpwG4YeLVrx>>7$@bVK2XT~2y7=JTf(D^ z-Ic}1?N>?a!W#!pfmtSZGjYaubDinX*W#(#j(wsy$Ol`{wII^?Nxn}qh$k69Q?#mC z{cVRlTS>_Eh{DsfUj2E#Z}kUJQ?!Jq95QjGp%W-GbCBdp?52<$AsTUai9aBI_wq8v zLqFovSx}$cKVRG`w~?Kt5Dzg%cm`*)IjDS-Lm%jGCyj@L2L1{(?l>qS_$_~U$`Wqa zR2o@R1j<7-7RKtI6sn?L@gHCDF9Qt~$8)&TO7x=@rZ4|Nde#=^H@LesdzVLWkCq|e zS2VgnF&4HS=+vp*np`1QU15QJmH|~mJzIx%sMb!Q8egFF*t043+iNa+2QBMXEo;i$ zt$lqqN_mA?zJPy*HuRS=x=1*!3tl!r?6Fr)G|p39ZVOtDlXkxev-tEL@sWD%`PBwW zPICQb=1+Wj5%8)9de=6(NIY$UJmsEzv;LqFMQWkB+!nk{j(*Mm{Ivr7ys>`q9rv#J z&t43%D5et?-52}%-c6>Jo8T8e0hqRdY(h-{s0qG?ylFIJKk-#zas}O?~OG{EBIiQB(@OW>tOlMQ0@@h*1w8Dq@?33GAJt`-opwssYuPlyehs(MD z1P9ll@bo9mM6Ab5&`+L}A@8HapHzlST`CIQ451YyY6CR7r1s>4G`hqsEBEix$p!FXU&=+p1|tJpZTzDo1$Spi3uvn_#1%K|ep_{$0s^|Lsqw${LvM%7J?%&44+D$XJI(K(qp zkc%6`L_>~qlM0%9W24INv*d~tb3+SVhW!-*Cr#;|`6xySuyl!rk4Wad&rjcXxMdVBw9syWie>=boJJ&&f_IBUMR_s-!Y!GT&Ka zJg>Pq4LVSsOWTs$EmPZ);QjGujE+($E^?uzX6N)U-L9^5zK`^vvKd5*A`abfU}++K zew4$5(WICc`T`Dh*<*9^+3lowWdTOz(4r}co`}Z$W3jc3({hV|Bg@*gDAGc2zO($? zH~4?n@^9-X6}N$dfNa5lfRO(`YWamNUBoR-ZA|{Bl0PI_#u-=a=h!#NrFLBkx(p|5 zs;muoEa?R$!!HINQTc3`>7t*9L0s)CckAo*D^Qo*f{3-Mkqm-PPVybEiG`8WD3wm* zOwhGHAp9U>x=w)))3M}6WGRSerx~ZOkA3Fa@5g;}x!~o0?@7fQ(gktSI$lYoj^H@d z>{8o1CTG~}Qad_kXAtbHn0#=C%zwPS#h&_(^;`WI?Obhc`*;lP+PK3Or(dJn&^MWn zY+0m6khv-yiPvh-S;6e$!Bv09bsj26xrp3g%u#Eyz3b(%DF?pE3B!TAv_o@kpG)Sw)J$DO31iM8Fi`Wh}VGftSa22iHiNW zF~EEIDNq2Yj*9jgYLG=qMk@+8kPMf4q|m3VO06u8_EV}$5*-~GM<`6(bk^fuLFria zu(O?FYCENjn07&QgW5nPl=PhzfEN)Z#>!0%VDm_V@+a>I)X~M}Wvd%U1#C z?l?yHB3PU#dr!l-rn<}{D#@*uN!Flhas zQ(rKbuM+SNXp@cy0z&=&n)>$kHl~Jl|92yghPQ+2GWK_lGsjw(j3&w;$=WyyF|CZ` z&-pu;1X9w*dU6<0vT_GhyTp(gJ77=LaA5bIj*e{&U2_VZ?Y{;m(GfKBa$9qg(w2RT z9C_P!eV!%x?+Ra_Tj|o6`)rSQQ&$H~oTZu5l{=vC{92E1nmy84{=?LXQLt>nyhi{H|5ZAyN(OIL^zp# z$``)UtojbSQS`iY!{)j#iSYVvyIPpN#8A1;yH)f)GeM}Fr^BmyFQHhUrKoc}j*$h; zR5)>GGe4vqcG;mMbd1_Y8QD-`taDBa0Ca0LPooyayoo0&#v6Z3R3B!9!uYY|n5N@M z6TxH7>eo5S*`CNkLs4#3jb&qySX;?anB-#Ymx~(ySaH+VB9wF6{(vI!{_|~%m&-hI*F^`ThWRoO2lU7RCo<;E-ZIRoG(FY z$MrDF{?eYZEFh~}dRumpMS6BGH7>rA*BrQDUBh>D6#;W^<;)L%y5dA;k5j7q zPOoAI)l2FS)a)=f)C4qhsU8$k$hwL_&$L(}IU>S8v3n1W>Z;TquTRKk7px0?>;GVP z91YxLX+4>+@W~IiOz9mUJE*c%?$m0PG3}CVovM&Kl}cbC2W8&0cAkEW0n!{J_u5wH z8zjxoAIQ$xlDv<0LuJ~u37mEA4GeZnx+D2JQGbbsMfahZfn23vcKG78qtGj zHW(NSV+3@|(CO5u@An6B^fQh}S3@iCB;ys5A>7AV#|ufTCW^TS``t~Pm34^m%j$Kp zHXWBA1FWI3z_?V18|xHN=Ro@j}cK z?a8*Os@DRNlPSGy0cr3M4GB&Uxd$&%>9{~8gj3W_Lcbz+iOd0j?q^y`({y@xDcJga zJ^$XYCj(#%_XmexD^0rWvJbFVR9BQe8&N$$YTkuuu+@|#~$cqc#8W+6rb z5j|?%$b2$uI=7U9T~73X_Fc5T2-^7+*&B6uN6vtlu>wKa9@`h&S4P-Aphp~ROxTL= z0TN><04iAW4kxM}=JCOGNj3=fCp)NFD1A|I4!j~Lhr&^H15WHk&VJ#vhbwJ$mSj5&d?31mITUGsf@I@iRoUpn-`GGgYD@&k{zVIw# zYeu}VRU&OjueI#WVQFt}Wl|FTfWgNG-XpKYsBP)iihSdSlujL+BL7U&286WC!Y_yQ zA*sS?1nB$xWY7D+{0y+6_E>h*);x9iq3O!X+5BP0*2z5N)jM|Gjj1jBfqQUxcc>9^ z&EJT5@Dx=cX)_|&Sq!(}P@xsA@hb_##ed{c(#+k`&G~I}*928d={sp-Yx<(s4t_+@ z{|!YgB&_5h)sYi6F{@`AuE(Z#!{xQ1vs?rtv>u{uMO3TCZ>a`%rOhtV3z`5(o=X}j zTTw*Fi0s%|xo4~MobV`U4pYg}*zBRz0@RX_ThpjL?^QdI<&{qXnLS8$tx12@LYzvC z$j?V?N~PF@p{h-bJyR2oGQ?39y%NzX6oINI5~afUCberO^c5^1s2F2-TkQB_ zmMmB;Fb2{D&bYB+WU(^@r?GlK;`wk(zeX3bYSZD=V8p1ic(h_cQ#)IhCMSRXQssYy zWD#s!z2qS&0B#fpczFNLWfWu(#Rhj?_|_vj1S@4zdl#24Xk2gmL@QN)e^7DIc<-Ef zP`r$q>X7GJWjN+$wn_UT*uisE`wGt_ zO!kLe#@6ET>BrHFZ>H{+d^uY$+5}rK9Y&?=UYK7+Mjq=>7n^b|@}1Z_s&L7l?X&TM zx9FX;WRNTtkMhy9R1h5&tO^$x1l|WC^e1U>%piEKkusA(NzKdW3X~SIpivxs*+OyV zbO{G4@RV^?^;9hLdYB>gzj zo$yZ|RKz`zp_S*r{|sE(Id|*F^hFy7;=B(q=r{!`sSp_=%V$m4)$VGNO3x^Q0Bi?&0u=1 z82lFP79iU8C;$F{e?8WZcrP1%zaD-k9DdI$-~XQUt~Bvv*W|^O&9#$O@Kq;s#mY!c z)OnR&` z4@N%WLRHP|WRqB>^NJ|JRNj+8UBp}I=_T$dd8wp*uabxJ$)Z#fkAzDKxoM1m%PH#z z(RU;2jT(>q5Z@#)Jv=~ZcJ%AL%Sys*amkKqA>fWUCPyga4u#sHHq?)QRtYc!c8EZ$ zPI*z`RINDL5IMR+okk1i%mmGJ-_V%gCpdP>1N|sDUKX9tXrt`0Ry_Zdfu#=bvMu3^s=^E3g_y`mMH|QB`}_a!DPjJbPZ^f-qb&&m1muGh1cd$nu}c5{ zX^$fIwho3)rmFVB|AT-0AHm*}4(p>LMlj}o4@g`M1%cFNU35wYv&~dKD2EAL6mEe* zr!+4zl2i%LA}5nVzSR^&yXjrg(^|Dw<5e6WS%Ej(Q_zp0q1)^dliPfw07!tX|?Q^ z9b&87EIAcckSy8-S2ozHlOOX~d4UK;H;Np*(GuCf014CE^khEzC<>F?V%prqk)=it zag4diJuZYfcuw$zRCRw^v^a4H(VXA=@rtC$>6H1YsWa&H%c5CjE!~<`wsbT{_ zo9{wKZ!d)?sE^%_Z0fujc^xAuN_s{oZPwQI#ho)GT3Gc(K^az*x*zW(Q8bt>A%k)Q znx-*!Y@9sWwl2|_C+P6(VL<_+lsHT!U_;Vn_}BVJ97hB#CmxYw*J~=Hrd7LSjveKE z!Du7J<;^mcI3=|JP-j;re^LTCag=O&97u8(sgQ-GRG1Jc?0-lkHa8@Cq~MLrz?K4o z_6Y9xQbKCRTA5HEDm{b%RC7H4g9iAO-EMO*;b zQX^|Z07)3nBq)u#189K!?qUNuw~ey3HRB?w!x;lG7wx`}R~>h$CjC0nU>Kt;{H(ns z>T_2rK#-9juaWns4coH@D}1{OR3>eTmw}|GWIq8TutlsZzN>A-9bQVJ30ngC#ZOp+ zqwgv=v{k*rSk_Wci=Dwdu07ix)?(A%%hzueuwWA{?)Umm?)rkdpy>uRGo(m;^5Lc( z30Wy!CO;$HlTJ;sYT5>_R)T=ArezzSWNp=$rAtDgp<&L^p)H@w%hffJba=47enGxE zIS~`1C1*$b`1xSi#lf^i5knlXLZA6TIQj-u-ci+ebF6+TJ-a{mSqo|0t6DndcxjBX z7+KAqtGhMD{1aIxo~M5~MPG}q-@@fgq?aCSg;`ptGz3rI9iDbDgctCIPo%Sh zfjAc)N*rM@-TAKTfn8_eu^h5`(@SX)j?mHK`*wTG>QVu8o{3 z80J%Zx?0%`QEFhXR97tW;N-jXJ|T5%KKp|Lj>Vz&rk^>qy=hIUlf?83 z<9jAr*^>vA_X9&8x5rOLsVQ+Yu{c}_DOHbBqUS}-c+p={4e8&a0e6c(GMv^w*vuUn z4UcktrKc86^7wdMnbJjWJ0*E{;~-2J%O=PsUvON?0DK&9=@E2!6wt3f;n^=Im*8cl z{HTYhw^dARoWnO7ru?_|2Sg?61hp)=Q*w@Py-lv{kXy5C$-{JQd-_7&?%bUt4_o(S zH%jdX@j7#TxB@Ilcag*%>WZV=F0)Rn1ncTmkzwiR7|GLAw)El1nr)p5E|*`KwmoAE*WU{R{aZmhr`r0~ zG((blh{lgU=r^!_+5taUv<+(tpNICR@d7l(6pOw27bY^^EJYdtY;kFxa-SE2lu>!3|UZ!ek@k|ulEKB?NqC-{9V~O^$DNoM| z{3uiUI78Z8xnky^PI8Fh?L?YyG(YceTFtAb;J&hNQ30U*PodJv9#tQrn`_cBvc)0K z{3U=BV-wOgiy|W1(XFkAH)0c^abx1jZsRH>%Jtb1QK4hw$_=gabcn#t8-0Hm#F zPrLoG%<<_DD6YTH*rgsZzdf zL7^Um*qfAovD<;&RujV&oWMtc&z6mJGN%m?~T_|LYQh2c>` z2H+t2>&v9r!ra4(gUdb~xI;L3yXenPF_zHqk(&s{K_jZdLP!}g8u>z-6v-2S75R+v z7u~Sq<_pn70AW;oP;NL;zlh+QL(AdNaw?KWQ3OEwK|LOz{HV_IX|<%YnC13%WkNfO z!iOfpxgEWRolRkWrrR3{y_d5)5Ue8T##%(mM^pWlq~RD=)*IHI%3ZgHza6qpwxlUA5bJ+ z7>xS`8zLgR`}3Z?!y;vgAe`Zc5e=`@e1+6xj_yOU)8~y~j~Q z0l;lgRx^g6|MvrT(Pqo)7tz%3j@c?n#T7XLPXy!t(mBmZyJV={e(6VwdtQ%PK)N7` ztf?sdtB9v|+qqxfL=EriIDU4RyWY>;iQ{cRc-;eSA8~s?MKb#B0YkQD*!#}ID9k(H z{w*bosbJXZfio6mj*;{nPMf!Uzf9V{_2<)PCZn6sz$A=6EccH0Tm z@1~<3c{fUa`Azu3GxFosaZHKI>@xC4>-4z6RQQjz$ift4QsaLRS$E{ot{hh>2~{L4 zms`{M@y(!`se(23!P3&GhdQZGgo-|~h8KD=ewpeQ+FfcRFP~HgbfzV@&1QUdhU&d! zj>;RWEthA%kX4h`Y9QBmfG!y{c*-W))JW=~k#_A09p;i#%c~jb)4CHV^kd24r{!AC zf>V}h$4qm#O&uN5Zhk?tuJn{CHeH^97XLtVw@)2i+-^R#Hi66(w0W~nq3NsW(jDB= zU4vQlp}Qu5`buo2OKa)kNKLi-W%U z?P+Z@4ZkgOt4Qb7;0dp`DUD=X5N1~tc9kD?6|5swn70@UI=MxubTy!O$gfKIY#i8# z9!8C15ZZ`8)@Y|p@FzkdDL<1xO)8*!FN^NUEUIVCB&{YE+^OX>L}6NWxvve7u1V@U zKX(IqomMDqkIYcmaKBRS(m%_Gcf)MnCk)*!4&5ye-7N*(Ee72!2i+|L-7Nv#tpM#K z34Kuv&R+=5FWz$pi%}0K_p#c7PkNCe#s9^zW6#yE0G(aR^Iy@-?h6NgqcyHR%sVQS z!qI{Jf{^oF;-C_YPZiR$65+KH-)=d;&k7N$yn|9H2dlDEvA}H%q6HdJ?Ow6&X%K7$ zewkmdpMPtRe`}cEIL|ol79&Q=NEgb+m6FvJt6?hqlBhKeh(1gpe}O#A9}gsn;L8LW zhwF)5Gz{~n1C1m2df|cAbQdk;Po2K8eCs-_+!41K_2&`3Xbt8l-WUz$sNRST$0*+X z4VXW>5`Yq@?^s5JG8g;dmlRKq!-y`R-aR2b+r#|M|K5Fv5hJ}9FAJOs_XTTEAbo-} z%9FiN3HPOL&_MABs3U)38$Oa~@xpJYqj*9X?o9w@h5NEJ*b_aO8U1(I*@nDuroC{My>Nbh zwTrvKh>ZJhr@kj|ub@&n%Um4yeH>UKPnHPu8T0 zSjxy)7Z|`x?w49-rdnhslZw$J!Hpk6MoMpmb_y*QfI}B7A=uw!L!TkGaplOC$>(%^ zC;0j)L~i|U;X;}o}ZsT@f85CPZL8RkvB*zrH0HqOk~}EWcb9E0}PxKs+JD{XH-tm+S*`WiV1Uv_ViX3_is3S1BK-yi59k*g7WiA z2lwqm+rRs~8IA9&>RjpE#SX1-YE7@3S#;nyO^WO-B@s`e<=r4nSEC6kB3qk7dU^{N ze=Fd|Sp8aR8oac&en|G_>lHtniutY-bd3AKWt?d>BvjX@)v`z--zDf5r@A5osb#1@ zsf+3IDguZTn05p#vaF?-D(BIlDN8Kzk-+PmgIQGx*0BK4%HuV*(`5) z<~=cdvFVpNT5M~S$A&-N0`CDc*hEyDJ@In%Gi&hPt%Y+No5dfMmG@~VYRZj`%-G&7 zEmFX$l*Ez}DalmniNr)wQkh~CEiIHpQ{~2PUf2mIDy=+GAnmMsu5XhpxA5EW0x=`m zj@F?pvD1%PYPI&o4AC2`?37A}8kPtwW=?ChU1f6=LlcM8%0aSOQsRlfv`QgU*-{Wm z16rkUX*@~c6hTe8=(X!tsF=G9VVDu^2X(~*i8DHY0?QM2hJ;vA!-Jp9B zMtrH`B&VxOn22HS&?3KN)?!G~F=><{{}-eO(lGvMHq()^zxEhDL48w^`sAP)v`JEu z`g7M|rtNW$B(XqRSOK^MC9TO;|6SE{4jW zd-z$mKXIH*G~6kG?W3;GvX-ck6P37|ZMe6GQitnZvTif6FrayLZ#*1CuInh#DB5ezu1iPBYh_$!NUznm% zVJx;IvcdBpmw)Eze((@^Go`641$?$wB6JM`IMi6DYRqK2*P`7ybC@rg+{H(57YFAL z7TlV!avKG+xTUyatP1EA@eMe=ht6^})D>N&n^WGw=n<)^q>fxcYwxc(rr@cWvh~B4 zURtK*RIhw!5ezeMiI%1`vu51}Hf?wy3}v`rhWu83q>r$|i z2uY?d&aFMCS6i(=(dndbDwRp4mtZ3+Ug^kOfkT`J@(D_0gYx4PJxqg6E*_?rQPps% zoc?Y9Gnb=s>eESI=@L-t0-924Aq~Gz^(m-k71is4QPSuFX=SNfSr=7_`K%I^;oD{N z#3w1YX3YaO;)hl-+S3XnJ5u46ky*{G;a1qk)}q;v2`q8R@3*2>=Vl_-PRps5*tz&E z*1Jaa$Q#m378Vc4Hfz#Bw_Z1(Ii9ysBOd1rEKo0T;Hb8$(TwmdxF3ejQH)%Q@vgB% zHn}=VtU5 zNziK{AqG56YPgWaPtThuB2AJ|qa3Wz%R&&IVVF&ty9O1Y>R4@|7_L)&e67mK_SIq! z-WV}$Da$GE)@7GV+x6mBuZ(jS?L@wmkiX4fij9mI!Foe58S0XgoHO|0Sx50ACsVhq z1u9#LlT+b3KC+3Uxa@;+t7GM2+`Z!qQ8OCBZ$paA>QcYS;XPLCN*5h@OfT1bZMviA z$o#fl(CLe`#Q@s1KV|T~JdE-*Pv`yP!qzxt%&VEBT+=c6-+S^Vm}LTx=ZV|kNQU!E z=jaQbMjL*y%$mcrKak0==%jbiod2RaBmYd%B(H49^tB%G zS+0{S)*9U*_6g(1oB8N!&zxR^*~4i+fo?qWvt9jMm;e4#>1TWFrds;ef*X2lmoF>VVYGrN7e^_i18#8+*SZSMQ`_r9kgWp%`F;#n5Et)b`S~rH)QEpm3 zrO4K`@t{P^4`#p`dpy!v1p3=tN%A_Q{+vIgTV#j4_(!o`@&RI%nvWvrr3y1o#TZBVm<8 z^50iQz_p3l1?^)C{#Xl)0W3E=!(+`FXIerD)~H{3Idm7a^W5++|CPq>Hfvs{cmCf` z{A+Mb>V{#J6XJunKpW_IF`ZH)_TQ(sQO4w^=yOys0u*HZQd*-@u*4F`<_q(EK<}ACvEFru?F<(D4pAc zc7$)_w*BCCkq1=w$N{6QbjmA?rV&1hXLY3ozE@f`(Vzq}>{KXi!U}qeBAlQ6belNX z;T6-+xj)(phOV!ECoV>y8F%+@$c^%u_@vv!4dY>eKlbBFZqS_xWBrSnVtr-{HTbD3 z=^%t3{aQZ=@&|%gJ;LA3G@^y7?B=C|=$G?Tp!Ckr12~>c5cm~>80P;X_Cj zf*Nx(6bAK2mgTjS>q&_4Us&(6yzFC2b#j&IXl~YRNtThBYO&}5w4sSbHLy0qCyC!; z4je4eVoxjnz?S4NA#ZLLZfh1c*3KwKMF6*$mNpKW-(ln|Ks7&+&o02$Ey4Cl(LV50 zbgu1rso%e$?=j2HFhADf9xu%;@wI*Gj)?7!xcjARe=ylSPd$SJYSDQ-_(UjlKDa={(=3UfrE`P-ld0v?4{w4QMw74^a^kd6X4 zN$`8CIB2UlV9O_9pp^5jRFshn87LlTOAN#av?T-DLUiRAxc{`l9cV?ppbxzK1>}R+ z5UPLo0%=u;)~O0;(Ko1{i0z(0mX(8O4Kv7r@D4VJL$P5PARqzmLu^RYe?oW%8bHIi z#s60*hc-BOsdvQzzQO-spGX*sc_N#MaFa~0g zFYp8LNr2vbARGBXw)6dV9sOBj5E2A)g;A&hzOwcE5bwbTc_O?=(ePc?kAE0}@#FOao(>RE2u5 zz%`hoUz$V%qsTVA1LQydD?EbOR3WyiL1xA3u+=_>N`#nQKe(SI#i4Y5=PkAio**Utg~TQVi2_!@WPp+{RmnWPNm`VY!O3C>I?`%XC1z_~bs4xU zrh#jFnfgn<&=MAsM!jomtJSTo%lFc*?fs&&Rqx!*{XEzCIxR!WNh0YZb?2t%>h?0`V2V&@^^yt?2XGb|Ip@+0ukuOYs%#4cqF9n4$*f!U$xn{&wf$3 z>aN*sqpu#|vAOqei0Rwk>+5(S4D}2v`A&=4;km6<>8A=-p=8x4*EMlWxI{rLaGaVD ziJ4St)XLxGs=a58cF3vQg{_5WQNlJ z*JU6s8aA@)U~34j@smI$Gg04o!k@Xsx6J{I(zbiVzgrIV+1*}`?JeJhZx;RNRqPRz zuO~u@9r4|5|80Tc0Kr4-s4rfIZpS?No#gYARA-j*5E?qD;5Rbe z&S}&mn<&^Qdlf@`UTI|jk*3spfS_N8F5q;>KyQD$OEP>w?*FqzIBkws)CEfm_4k%c0#^?``rby;jm0h+3Sj8$jM%ctRZ*W-)^uer2ApIEz-gf_dBK{$ z_FA{Szh0@bK8E$e6zB&L(DhQBC3|Afx12N6E~CVKn}sO1^s2o#bQy=)Rlc*2sJAvW z?T4}-*wej^Sv5}W40>Xm7dI@muR6yCEpm+U&t|7F=_^3JW>uR}w7*iXhd z=5TxJ-bz-AyrbK@`%Zv{xrU)=su?!1t?MQy51o?}ULS?6NOn^(V<8q3UQh0}Br&i| zpe}Z-5hmi6SMf1pJuXE|a^x3ML0Eg#l1sZbpdCZyh+yk1M{eoVjAD|jUK&X;>Y-E)D zz;}(IKNIEK_{fh1ztQ^3hT#zdQD=CA0}Eh5_&CoNeXTHP`i*@Pc7v^Fb2P3e!-Tf# z=-2}++{f6g-Y4Ib)flI;$Srq#H(<0H9!J=f1paHHH7D>)x*w1F$eeZ_%$5AbsODEW z(#oyuE)078P9+KJY~&jorJ~DQ8&SiJ|A?^p3Wup+Rj7oyA%^PSJ3f-;(h%f(1JgS> zlGY*V;FuZ3;BbqEIp=WeNk4n`f-~Cg8hfSGI>*(iFTcfkD#T){x3rvdSFyZ0*M-?L zVwb=9_;~lFsASoegSKI-=YphSdG$xC0y;$iCH6hga4}WEDF(_m_`xizeLYQGwRhFn zc;rE01qXgn#V%08ZaTb7{1wLzn#+}7E8tm9dppS`$$ngWii3ukuCB%hX;X%ZU|*+x zM$7b@dM4{kOc~<`bo5Y{_ereGGXgiaORNOx&teL#WPOvRnd}$oV`auvpAb!u;$iIQ zmNDNW9`BaR20Kg|Wonk9`oSy3Nixv;mwO%M)$X0qrBt6nS5ey9i9STMQIeVj_4U5$ z+nSXeuRS^DOGu-42vy^3&q@ZtTPM+&uW_OvU+j%-fu90Kxr0etTUgkvETjwu?A*k3 z$c>ca_HDGCt5=!L;+ew8gavcgyPYJ$UEjebs1o6S(%Fr<)brs5F;Z^~C2GL7r^?km zjEmMMc&H!{1HWrZ`SE@KaFn+NT74aJ!%KjzLvqe3D&&VrhrM3 zjaycDK}J=L{ylq$HQ0`tN6!vUWecW#sA!qbjMZ_>vUGtJKA~{H zB!o;wK@OAl{cCtl>7+nxoqqPJ21{E$ACAU3R$ttd zZvs)W|I9f&-xZg5Rw6Qg?$o|Ji%m$rVMnB6AC`sZj7Kp(i|Wx|O*h&_3DS>kfkhtS zJbw!o6Au<`KqkIB5*6%_o6RlH$$+{DIqU#CcJl7n9qD~bC+v-$H)35n<~5Gl6U;71 z;G9?-WhPp2D8}=+_fQf%$Rb(b7N5J}2;=|T=7|9DAB1WJnFX}n70o>z*#pZxQGD5E zD+Eb})am5UXZeqN`N2K=S~9Zb%AZA=sgdO=7=6sP_nOM>8?vl+_+_b#I@NkiO4kYH zwyYd7h4d{V=u@()b!3kO<(qHmmIC|!x_djKl+!*0`&~^JXf}-KHub}aa7Se5(=ycQ z6zC4;0H?ge{P*I@Jk-FXv)Hq#aeNUi^8j;*sj;#8LT6ahxk+vbSFl4@oRX}KhCexc zk!slJ#Hm}Ys2oe|P_>+}MCg#T zz$yF&9OX<%XGm3vZHrNC!T_r)4w1nRRkB%Pyy4;i-+Z?x8WJ*Cee0FCTf|{r(tJv6 zotJ?mu62{C`V>z{4y;8jE%a}9!I|UA{ zX0ubZTHM@BGwm~Z&za0FJz@DT<#Wchjg!}oJ(CV zk1Mqr1T>MBmrA3GeC=ea|x{@kP%TAQ>MP+zQyaj>vRaYBZ@qdLz~f2ti$VfJN)HF<#(YD zW{G=EV9C*Tm0IN+*KxJR@_-hvYe#DNRJL)>CjsCNi}59MQLS=OHODvT%NZ!X*X~IA z!Ig>u&qLBTYX1% z$%5<_)@kUIQkg)s;!Y}AsL^a1BA3vX--ZwL!sSr(tE7Cmy!ejMQ13Nkvql(v=$2{h7c z4Nhn}7lCC~l!`f)v{8xUV#7|7!~!fbsn)2#%zzSYSxoo6LVEFvGjXnEK#L0$ZC*;N zk7ep>g}PC|*-UyKhYXNmE|EB=bc0!`JCYJ0hjt!r#HUnE61h6_d(U|>wN6sUZRs%F zRx7!&sG4@pdF=MxCgMuGp_3x!q>%K5nD~tX<)f;JR9ohp7!FM zl@YwqyqIq2j>=7R^o|Z!$4^*+*~^42dw8VMKL3^!u3HUrUa}9Ob;#;f&7iE zK1e*TU?IoJh2j&%qI6+y{)C>ZGs+Lv=ePKE@d5_dx^N%FzinRv9NUzlng0 z1wJPiq)(Lg1o3l=X1Unb1%?1O9J*sW=uZ@&%+?+nQ(?2cG)&jHo}xWPnD|6NkY*{t zDD@)@d%1*C-FAT9Sx&nWUnuyQ-iew(w8)u+gX||If#UV3`SQMpau4)eCE-x{n`3m< z^B&I`?1!fBPy5O|d6|f|L_?3MZXInyPM)dc_QahAY~?*BqZ>{pPC2Suh>~GT>4-A3 zc$7IAo!J>TPo$+g{wzn&zF&r@O~vg@0iPL^v8W^PqPN6K-J)m=C?gtXf{w$@rY=uB zz~_iPTx`l-O85FSMsh>z8UFa0a+O@nv$@5qqP2q zYFKm+38LBNXraqu**P4cr*^S@BjQlc`Z zp8r#N8lya6_eb!j?(U>Kx_KFeF5{Xn!~;Y2Z;m---U zoD0f3uB^qt;?ez;07)hHGB_@@i@36u35(gxfDh`pbK1l;XxHO?uJaKzs3l`;n0Y5H z!$UJJw9sQPtm0^fBp1cLTiW5bAVY`KC zjIzg@HJ&Zyk-^$D{nV*U4*0`M_g!#7MVGD-K{-B^-j3CM*-cOEC_zn>OHf~cJDeG(<-xBz%~<`JCK(#CGiDtTq>tD-W=bXwF`;RaQa$=ydj6s2kEC(Zh}S6& zPDd72n7Syw4M8%&zc!T2R|+SR14Y;$I4gk#%@{NbTJ7HHE$^;vvS9*#w$YF5g?AsE zZNc3j2;=gnP|D?=GtwCKOY!(Oes@@hK#2>hhuYGM+(2+BJMmuWE16o>L03*)z5W3E zGmpN3fTF728-OMlB?{#nLHC@lI?s&ul+Yn*rBAGChuj7=3OLAob=FaZ@T}^GNzwAb zRs9#u5NaeU)AkhlKX+X2Rh#a}e}I6*6M}#U{4d6c^8Yxd|MPlRwO4U*va~b*kG+>3 zEm#lLW%RG>EV_*Dc%rFbL9m41In$&+_Jkoo!9}A(e@nqYslG9LN`=asEo!lrZ|Uir z9t8^N)W}%UsONJ>D1&wxRJplVtX$PtFR#>Ur{vymPfeK|LDnz&<#k-o_B?-n`_J+n zZ@%9oxDx=Oe^Hus5bdgC_72Z&w0GoW@#wZE<>?=pN$~du)?xg$ZjbW6a@n=xF!9-n z@%Ctm*4w;rD+nojcDP62P&ZWIf4n+8;-}d7` z{7aPkg7Mrt({t@`ug8J7XUNeTc6~o5(e9b-&wn(EbR+WhN@C|XJ)@xeQUNdEyz9tu zv>(CCJ26+bnI4ws92X3I%X;n=D&;?L%{w*2u=RrOH>28Tc(K!Y)5ZI-9aG|wY5vu( z{+)oyKejaId=1Hd=7tGCqf~{0Ubay1R+b7Cfdy?4>M#07+ext?t`<*X&_iVe#x`Fw%9DHr6NA<^EG%8D5)t;=#&i;GsmPlJ z&QL!a*i43T4Nn~;U9OK1Y6K46U?H4$EgwR{XT=LNw6IgKizr{g!H3O7h3S=H448ec zwFoL9RiI75lO(Mg@nWvpaOAp zIX+RLN>%=CD3IGlYohn-4{8aoz3W0?3N+kw_fZodT}^O_Ug zGODeT5Z>F&M4-_M1L2copra1%KCVmj_ujTy(qrlw0-I*=VO2JxGDl^*a%B)X1iTUxbz> zPDqHD?zqQ29gmP!;qfU^Jk;II+Bd*5sRkwd>zef7U=Iod{oNnMDq5ZlO&OYMo0_E} z<_+}^v#TQ=enBkY3QkqFQ`#WXZ`w)#btajxq<1q>B-;+5N+qJ0l8V$-(!g!B(`>Si zpKMXG69tx;8%eE%0m_oxnY?Z~ld_e{^6<8{(YGW_*8C+S}lVGI-mxUBlAcEr`G zL85H>-9)k6@w8haAI;ISTWqa%u>irxghs7=USlcNiqRtJVk&|-CB7$ZOvc7g(R?#K zReT)Mwkp2m6<}1QmRJF8sl^wj81t-n6fLh&C2gcw1g*4KhKz@)5`F1Jp|EV)$d7J$ zF-i^BZU#2Ng#VASuYj#2Mz+m_nUl$cnVFe6H_Xh;%*@Qp%*lkA@rEYM%rL}idwbZ_DciXPICA+G8DzES@#Elq9dFiYY(Q#Nc9BpY%qfx6;t^{(aoged} zR_?KS>9s`{GnG_S#jrXieoikUbF&Ll`^@Tto+X7*;rfK_&ZtH5?OdF`wtc?Ni{ayzWC>?4iJyV@(KkiKEC8lGIreQqwx~T{1Tre z-l|5gkuM;3zVq2EJza$+y;AitFAs)&uceZKvkpmPYjD^>m?n=iMp71roLTFwjK~8i zi3%ro&Z^q8gH5I!Ua$8HzJwxg3q3fOJ498I3AzdAk*Eg^%b8 z{#8nLE>CH>ct$Vr*ePsBTy`;N3qQ^H?&s1L*YaDRB(;01>PsjC7%l^K2*sll#$lu`gkQwLqi>+TAP*X9}A(Afyy}E}o zFb>_}|5TEt-izpO)cJm>2THNS{)s3#ynjenZwmVdfgbSGC8`t|CJFd`i3@9cMxImX@Dy$)QU^XW>Yg96g{6I`}z zjPURIv{uE7Me^2yTrExg5X72=JnLCY5LzM-DKKaaFnDVaJ>SG{{XGwy>Bm2+CIhs@ z6xi{q=25NsAXRG_CIa`jA(=Jj1v#(_PLM0MKx!L7eZ{~YE}{{^CVKus^NL;w8@?JN%R3gC9E*_Jos0bIM+0&C1?3YwwRdL$6)ni(Y3_6#D~5 z#{w0DSab#jJI87?iWQTlc)Tg#JfBo;Mx0^#3_w#KJ6H9D> z^BDcHP;!8tUNjGD0{YM>1O^3r-wezVr`AlLZWFF!vdI zy3hSL<~i}AD&&Cxvqxc3l;U!n2drTz1f)^fCfnCE%WQ$5eL-w8%D-8rG6W}i^ZcC-=7M7+F&k@+A*MZk-t{(?nRQD!AiFZkg`9N+7*ha z7NA|TqNjKpEKx2Wpw7h^FQIwkhopERh7XAHm~TbJ_q}ED>j#GT;;f{Mahb7<4~@2e zIT_Uu2#ugn>X$}8*Cs?dQ7d|lSpPUvwo^*WPC0@kdurV^N*X;($CB!d-FBXD8qM0& zHH*Ws&Eh=xtK@$!w0DdJtr;3@VhBNYTaD7KPSWGy?_Qg*7P z>{3gV<*kF7%POre5_Yo@Gj3aoTX8ofWnAV0hufNa@4QS|6;AZFz-jmPJZs}yA&yft zlM_t22h}GK)xmN5)3@Am>o&zR;kZyCE1uZ$TUBZDc$Kn4(PBVysTik>RuHD8rZ{YK z7G~={$us3y^B?udI`wCG35v+;XTz$>;g4Qcp9}W|!OL^*H_G?cQdL(K$MuUUOxnh# zlWI(^W;|&4VxfygI;U3}T#ROvhYNRu8R8Q?@UBNAzZGaXO1*^9NM2V|z6DNC@bce% zQ{tuPS6d~8fxN3ho?)(&mDqw>aOp0Hyh=D_(s<487mOn3qOr|+k5@Y2rSz+Cxb76_njAx!qhzz@9-zD5xuT!Sugw zoL!7(9QWoz>0Qo*SK8Iv>=wPdXojYyZErJ11pK!;pO)2ibF*Id>g#(kg-eFZ9UG*1 z!|pgIh*E|qdce#=0;F<*=j@u{m|$j7-T%%ameCb#&s=pfR0%7qyyd`(1NZ zHviK_t#gft;<7`{kN6V9#yOeDik7WrN=}=ajnLUlkO_8@W`QPNy*ZXxZ;&AxJ7EK> z`3sJ`PMulVoC-V2J#(QhGchldZFtZDB1`$2g-Nos0b2}I_M4df@|1U)`e~vSvroeG z9=9_EwlBRFPV-qSfG65l)gccbhV0{xi8qkmS?9HN<#NL<{Y+{S(S1DRq6tt{+S*=6 z+t0KAZO*10hTGv55(u7*#{DC1{h`2oW8#ylLp|(T$m85$S4uT+d6At14vCvyCJDP; zZm9{*ZhFX5t$KbARI~X(jNVzRbKZILM%1!KJV}ra{hZGV-iKzABoeU3=vhdr!BaUg zb_)O&U?fGCW4)`V(Qa3Lnl_s9T9x^=QmoO&F2y7ZMwd=Fw@zJI&gI0O&slK#}s}D$X7f2Rp zrN&_z_vTMZwJ~zCo0@ee=|!vF>oi4WSQH{e%e2h8jbw&KA&f1=U7PJn_tSKw_E@d# z3MdHcFxW{(WDifnG$`6gMO;E1}nwNnty8&MLq7HN5#bj@Chw?XBKrVFKuam3ky=7xTh{mhT051$!Wv&?awqjKTz>^Xfbq$%JDxGKP6 z9)A7%P-+~p^u3y9^82J1k5AvAd#MG+O4QO#2c$UD^S1_AUS7r77GzDhd`KU))?d&E z(S)XW7P$PkE8?N;ay3xt(8T*1;DDpR5!3XeC)7GzWqt@k>I3Y9JC^Q3#E(Nr!@HiwN;(CDWiZ0Ya}JCfeW;l|rMM z32Ly+Q$c_mLK(^k@Pr2F1StfghNp2Qr+6$+Op~ZSi8RFo(173ZAfAFdBN=t~%5zozUOfsLLCgh2+8ck4E&!XVa)RzNc}N$j9T7%a76DP|bB?5%br z>7TW>ElaJ`tFM9(R@Jrh6oervD!*l@)i$h_TG!oMFy7{^8a|3IxmY;5l6zR1nhx$> z4uAii;@feavA>$>aOQg02`2yx5Pz1Z%6ijr@Q3kPLm>7UK|tycHbG2ysls9KpGJt@ zyKuQj`0lfSpuDSn=$bG^#2mhLgN#e$oHB)#X>2kI^vRwYGKov}44Eo6!6$JJnmRD) z6*=xQ>6JKsGw~BVhT+HwAy9g!*m8i)D{>Yf{==H<9X1tzb|FvMl0QG!zMjoR)u)GFI|K`*8Gg^~QlV%OXZ{u5h$hg_D_Z45!O@ zz=RhUPYIVEv!I=UjgxW=B4e&Yb)CL4c!|jG2sSqI!8Y|R8C1n`v_^GiZ>cB*yUR#Y z4wBq-;jng^hrnFMCcq$fuVOP5`zrZhODR7{-sB+N<4?&-T{)`JhmuJTIucr1L-qch z0eCgcSP>dNDDBPN(y|k=;RGKy*q>=YeAnleGsk%ljdA6nB=s6zdQs$0Tv>8(WOi6a zl>iTHVHr_r(tDa}6R)Qjm$4K>P{0wd<902y#1K#hoKxmnZFky*ye(v|4d|5S_rTK# z2GMSrF@SN6Z+zcH;?uy&Oe_Hfu5r9&@zIu2*=W&)F0}{V*N@Y9!Z30$UjbrdL2|U) zHiY~x?W5gmG%oL`Z8Ku4xW9gfAwq}FVL)Ri7->DJ4i7qgW@ z-EhkhP1rh>U3hIf-ajj#bG2OwZeE6PSMeb%{)E8>S1<1+ND65aLtrG@yhIferj7{o z+ww_ELk&5Z6v$wwQPh*n%NnN2k$TJ5E_IS>Q$86`qr!|!QQ^+53@#hXwy9{7ZYh1V zN-tHwFAS zHLtEbQ!|e)(bf&GJ!d~HfL)+qXcKKsZN~2u-0E4u?lfQls-3LlN`1YFh03D3^X$A! z!C5$!@=p=JSPwEFc9vhfT27Q_Zvu6AQj|))*hDUcbRoP{#L07MDXO!?#2y7OY0wUS zVaxcD<048WT>L56X~n>0ypKER%OC@{E$u^WQ}c2&&Q!@|QDa~he+PNgBoR_g*mvC< zXQbbOsU}&#_aM1?BIkOjZK%oHurqZD5x=v*(w|dc-v?2VbU?0M2W0R)e)t^)(m%6h z?j*d>W$q-t@MQ`lypUw7k9SKS%bR=xj@g*Yf!%V)3?`q_$Mz=oNLc5RV1rH<*_H^ANuI-ouw-hf9jP}_w>-lrFRQthL>=7}JwYb-?848}%& z`D)m(yS}`+ zu-3!1y0x(edm=zV$Zhhe)9q+hRBHf zC|T8_Qx@9{MZ}ua3|KRcBCkI5RL3p53o4ppYcKWkn=Dx#;5@xyX4IrB3!=* zue#W^&OGuL zc*v_uFxqn$k%EUFnCGZUx+8C>b8HaB1k>QS0)&<-g6Aug!itJ9p$njdw13<)hj3FA zAaKu?qgTk|nShoSvri@7>&HF`jns<@bgJ!FqlFkNBz3^p9lg`+2C1{brtD5V7oZl3 zMv_rB%ZXnIW{H$8UCeC@u4iMTcwplx9v2Pj4z<5Iur93}@<5h8PzrNS1Ca zLVsZE(#!`^?<#fc2Z8p)2&o^C7AU4#TI4c9s^Yrxr@+CnE>5tvpe_p~D0WRN)gBkf z+zv7isd!_#^jKCca9XjHopS(O!HV_l(#|z;UFh`M7a5oIAh#^C&RyasSUArq%Q_brm!@O9QVXk`#|+4!dcHAiT4YoW z7x{D!`6(nXXyS#{AkPO|%low0z*c`GC?>1E$;73LchE*`)vSr?_&Uf$?*|iH`!_<^$ z)ofb|*;cTvG}GdjkVQd%k%#Jy(P(p7*|l@+2xkULtXX|*=h1vx7%JZJV)`=axT;v* zoyQF8^di1c)^*Cx(wEMV|3S3ic(F!IR(+e6Wf&_V!>JXjO%SzS8gwfeRwFGW4QMS| z#zNHyF@N`Tv~G#&glkFRv}|{qUn4TrbiSj9D^^#0J*`Pcz_t{15xy_Cc#aLH6^iwD z{U1-;3Dvr3&QcFsJ~Y(0I*ZfP%i&;N3)Mbq&03*VA03owIU;EKAh&QE2vtwV{Ehra z6MUgs{FZ_xGr8&u_>(2xT-ShSQY+VqAT`wLBQNFJc8tJhP^*U`h}zd5f0H|!_eFBV zztHXqR0YbH%BTE-H-$xq*-3kig=jLDoPsOWHj{?;LYyQLA!@_0{*M0R17`gyV*ofU z1V=63^&1Y2;wDt5sc_~o(63%=(&aNPMQNjPr4^{j&{?#^-U?*P(C~}mShak0V1u*P zj+rh@JBlkv1K>VmWT9Aw>Fiu*^o;DQ0q~zOT0~Bc?igvtvV%B{Fk~XZyaL2vG|{Lt z`9xg&%($T2%*0ZkvTM@kZM$*#J*w$b9jfWWR(+)QH72qOV*;y|ogg)s(Z4$Mwa>`m z3e`iH&C({84=?v{p#+PytZnx2$4jw8KJ=q7l#Ukq-kWDwSNCD_whlZ8u0;9bs!M!@ zbN=v{7VSr*;Rl)y+jzm%xL3jB0d8tb6lSgXD0X6V7FcBTL2_I2>98|sneM5vXg3(G$LiIkr1 zmVRIV604wg;|8SnTY}uVrjGp5!X6f@$v&la+l=R~(@c2gOz5ubvXv3N8I#N|oC8BN z7t~^p@rt3wuv=iu##nRhjTpq=(tpQ)F73y?@%VD=w}OIzNd5;FlmA{d|I<=JDr#zG z=xXEgFF*d5`J_~FhXG6o`7^9q4KM0dwcAs0P>L57h7P79!GaA1bxlv*)_E(nhbQtc zECVXiCy0Mah8_;lEiwCAX71Yco0;3m$H4 z=T5j#TaQH1P+995%KwF9&UP>&waAm41Z~?nc7LL32lJ_j!e!lJlF&?{*9sM9TqL#i zQ^cqk&OLD~A{v4g_3`fxrs0P?F>n0Dz}|L;eplTx{X1CDQ`@h#QF2Jn-@L*p2?NM) zv=U(Bx8hH(IgT&QBYCUl%X)(HR3@wtjI{1B6z-u+aa;J%2N?h+Wy(hg_E*pu7D)WQ z=dGY|wm!#PhAS5Ew!sa

HL3n$rs6x%=&$Cwg?;qMEZZtUD+?zS^_NXzQDx( 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

|Kp?c>*zK^u$ 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ಱi+3}G~Fe4k7F5Yzrq#vdH}ij;2* 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 z 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≺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�(gwP)>9FxEnU*j15wa-k%p`ry{EAA^ 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
CLy1XjM0ai2t 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 diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/output.ttl.bak deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/output.ttl.bak deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/output.ttl.bak deleted file mode 100644 index 037f691d..00000000 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - "Venus" . diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/output.ttl.bak deleted file mode 100644 index 4aa4759e..00000000 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - . diff --git a/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak deleted file mode 100644 index 250a85dd..00000000 --- a/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak +++ /dev/null @@ -1,23 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-CSV/country info.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "http://example.com/{Country Code}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:code ; - rr:objectMap [ rr:template "\{\{\{ {ISO 3166} \}\}\}"; rr:termType rr:Literal] - ] . diff --git a/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak deleted file mode 100644 index 04fa74dd..00000000 --- a/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-JSON/country info.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.countries[*]" - ]; - - rr:subjectMap [ rr:template "http://example.com/{Country Code}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:code ; - rr:objectMap [ rr:template "\{\{\{ {ISO 3166} \}\}\}"; rr:termType rr:Literal] - ] . diff --git a/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak deleted file mode 100644 index 157c218f..00000000 --- a/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-XML/country info.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/countries/country" - ]; - - rr:subjectMap [ rr:template "http://example.com/{CountryCode}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:code ; - rr:objectMap [ rr:template "\{\{\{ {ISO 3166} \}\}\}"; rr:termType rr:Literal] - ] . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak deleted file mode 100644 index 9020be0f..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak +++ /dev/null @@ -1 +0,0 @@ - "NAME: VENUS" . diff --git a/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl.bak b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl.bak deleted file mode 100644 index 382c995c..00000000 --- a/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl.bak +++ /dev/null @@ -1,126 +0,0 @@ -# NOTE: this mapping file was initially generated by the yarrrml-parser. -# However, rml:parentTermMap :ptm_0 was replaced with a constant. -# -# More specifically, the following -# :om_7 a rr:ObjectMap; -# rml:parentTermMap :ptm_0. -# :ptm_0 rml:reference "firstname". -# -# has been replaced with -# :om_7 a rr:ObjectMap; -# rml:reference "firstname". - -@prefix rr: . -@prefix rdf: . -@prefix rdfs: . -@prefix fnml: . -@prefix fno: . -@prefix d2rq: . -@prefix rml: . -@prefix ql: . -@prefix : . -@prefix ex: . -@prefix idlab-fn: . -@prefix grel: . - -:map_person_0 rml:logicalSource :source_0. -:source_0 a rml:LogicalSource; - rml:source "sandbox/function_related/condition-function-on-po/data.json"; - rml:iterator "$.persons[*]"; - rml:referenceFormulation ql:JSONPath. -:map_person_0 a rr:TriplesMap; - rdfs:label "person". -:s_0 a rr:SubjectMap. -:map_person_0 rr:subjectMap :s_0. -:s_0 rr:template "http://example.com/{firstname}". -:pom_0 a rr:PredicateObjectMap. -:map_person_0 rr:predicateObjectMap :pom_0. -:pm_0 a rr:PredicateMap. -:pom_0 rr:predicateMap :pm_0. -:pm_0 rr:constant rdf:type. -:pom_0 rr:objectMap :om_0. -:om_0 a rr:ObjectMap; - rr:constant "http://xmlns.com/foaf/0.1/Person"; - rr:termType rr:IRI. -:pom_1 a rr:PredicateObjectMap. -:map_person_0 rr:predicateObjectMap :pom_1. -:pm_1 a rr:PredicateMap. -:pom_1 rr:predicateMap :pm_1. -:pm_1 rr:constant . -:pom_1 rr:objectMap :om_1. -:om_1 a fnml:FunctionTermMap; - rr:termType rr:Literal; - fnml:functionValue :fn_0. -:fn_0 rml:logicalSource :source_0; - rr:predicateObjectMap :pomexec_0. -:pomexec_0 rr:predicateMap :pmexec_0. -:pmexec_0 rr:constant fno:executes. -:pomexec_0 rr:objectMap :omexec_0. -:omexec_0 rr:constant "http://example.com/idlab/function/trueCondition"; - rr:termType rr:IRI. -:fn_0 rr:predicateObjectMap :pom_2. -:pom_2 a rr:PredicateObjectMap; - rr:predicateMap :pm_2. -:pm_2 a rr:PredicateMap; - rr:constant idlab-fn:strBoolean. -:pom_2 rr:objectMap :om_2. -:om_2 a rr:ObjectMap, fnml:FunctionTermMap; - fnml:functionValue :fn_1. -:fn_1 rml:logicalSource :source_0; - rr:predicateObjectMap :pomexec_1. -:pomexec_1 rr:predicateMap :pmexec_1. -:pmexec_1 rr:constant fno:executes. -:pomexec_1 rr:objectMap :omexec_1. -:omexec_1 rr:constant "http://example.com/idlab/function/stringContainsOtherString"; - rr:termType rr:IRI. -:fn_1 rr:predicateObjectMap :pom_3. -:pom_3 a rr:PredicateObjectMap; - rr:predicateMap :pm_3. -:pm_3 a rr:PredicateMap; - rr:constant idlab-fn:str. -:pom_3 rr:objectMap :om_3. -:om_3 a rr:ObjectMap; - rml:reference "firstname"; - rr:termType rr:Literal. -:fn_1 rr:predicateObjectMap :pom_4. -:pom_4 a rr:PredicateObjectMap; - rr:predicateMap :pm_4. -:pm_4 a rr:PredicateMap; - rr:constant idlab-fn:otherStr. -:pom_4 rr:objectMap :om_4. -:om_4 a rr:ObjectMap; - rr:constant "J"; - rr:termType rr:Literal. -:fn_1 rr:predicateObjectMap :pom_5. -:pom_5 a rr:PredicateObjectMap; - rr:predicateMap :pm_5. -:pm_5 a rr:PredicateMap; - rr:constant idlab-fn:delimiter. -:pom_5 rr:objectMap :om_5. -:om_5 a rr:ObjectMap; - rr:constant ""; - rr:termType rr:Literal. -:fn_0 rr:predicateObjectMap :pom_6. -:pom_6 a rr:PredicateObjectMap; - rr:predicateMap :pm_6. -:pm_6 a rr:PredicateMap; - rr:constant idlab-fn:str. -:pom_6 rr:objectMap :om_6. -:om_6 a rr:ObjectMap, fnml:FunctionTermMap; - fnml:functionValue :fn_2. -:fn_2 rml:logicalSource :source_0; - rr:predicateObjectMap :pomexec_2. -:pomexec_2 rr:predicateMap :pmexec_2. -:pmexec_2 rr:constant fno:executes. -:pomexec_2 rr:objectMap :omexec_2. -:omexec_2 rr:constant "http://users.ugent.be/~bjdmeest/function/grel.ttl#toUpperCase"; - rr:termType rr:IRI. -:fn_2 rr:predicateObjectMap :pom_7. -:pom_7 a rr:PredicateObjectMap; - rr:predicateMap :pm_7. -:pm_7 a rr:PredicateMap; - rr:constant grel:valueParameter. -:pom_7 rr:objectMap :om_7. -:om_7 a rr:ObjectMap; - rml:reference "firstname". - From bce1fc706df2e4b688853c5ff86fbe8d4bada556 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 23 Jun 2020 13:39:22 +0200 Subject: [PATCH 088/169] removed unused variable functionmaps --- .../core/extractors/std/StdPredicateObjectMapExtractor.scala | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala index 43fd83c7..ccc55f91 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala @@ -75,10 +75,7 @@ class StdPredicateObjectMapExtractor(predicateMapExtractor: PredicateMapExtracto private def extractPredicateObjectMap(resource: RDFResource): PredicateObjectMap = { this.logDebug("extractPredicateObjectMap : extracting object maps") val objectMaps = objectMapExtractor.extract(resource) - - this.logDebug("extractPredicateObjectMap : extracting function maps") - val functionMaps = functionMapExtractor.extract(resource) // TODO: not used. can be removed? - + this.logDebug("extractPredicateObjectMap : extracting predicate maps") val predicateMaps = predicateMapExtractor.extract(resource) From 145bb14e65d0229b3f6acdc4368d3ac640960da9 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 24 Jun 2020 09:38:09 +0200 Subject: [PATCH 089/169] wip: feature function #25 - RMLFNOTC0007-CSV working - moved testcase from failing to working - updated implementation report static-fno --- .../{failing => }/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl | 2 +- .../{failing => }/fno-testcases/RMLFNOTC0007-CSV/output.ttl | 0 src/test/resources/report/static-fno/result.csv | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl (95%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0007-CSV/output.ttl (100%) diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl similarity index 95% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl index 2019aab7..3e51b5f2 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl @@ -7,7 +7,7 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . +@prefix fno: . @prefix grel: . @base . diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0007-CSV/output.ttl diff --git a/src/test/resources/report/static-fno/result.csv b/src/test/resources/report/static-fno/result.csv index 3311ea7a..e941b368 100644 --- a/src/test/resources/report/static-fno/result.csv +++ b/src/test/resources/report/static-fno/result.csv @@ -6,7 +6,7 @@ RMLFNOTC0003-CSV,passed RMLFNOTC0004-CSV,passed RMLFNOTC0005-CSV,passed RMLFNOTC0006-CSV,passed -RMLFNOTC0007-CSV,failed +RMLFNOTC0007-CSV,passed RMLFNOTC0008-CSV,passed RMLFNOTC0009-CSV,failed RMLFNOTC0010-CSV,failed From 3366e61a7301cdd38323365e5fca3574fe170928 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 24 Jun 2020 11:00:33 +0200 Subject: [PATCH 090/169] Added link to function documentation --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index aa6842f4..5a79c034 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ The RMLStreamer generates [RDF](https://www.w3.org/2001/sw/wiki/RDF) from files using [RML](http://rml.io/). The difference with other RML implementations is that it can handle *big* input files and *continuous data streams*, like sensor data. +Documentation regarding the use of (custom) functions can be found [here](documentation/README_Functions.md). + ### Quick start If you want to get the RMLStreamer up and running within 5 minutes using Docker, check out [docker/README.md](docker/README.md) From ad4bcaba88b4f444aa24bd3c4de1fac134343be0 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Wed, 24 Jun 2020 15:15:48 +0200 Subject: [PATCH 091/169] Remove mainClass node from ServicesResourceTransformer --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3060c298..2e992c8a 100644 --- a/pom.xml +++ b/pom.xml @@ -364,7 +364,6 @@ SOFTWARE. --> - io.rml.framework.Main Date: Thu, 25 Jun 2020 10:07:46 +0200 Subject: [PATCH 092/169] WIP: EXPERIMENTAL -- integrating new way of binding reflected method par MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some of the SANDBOX tests started failing → those with controls_if All other sandbox tests √ OutputGenerationTests √ --- src/main/resources/IDLabFunctions.jar | Bin 3237 -> 3361 bytes src/main/resources/functions_idlab.ttl | 10 ++ src/main/resources/idlab_java_mapping.ttl | 9 ++ .../core/function/ReflectionUtils.scala | 89 +++++++++++++ .../core/function/model/DynamicFunction.scala | 121 +++++++++++++----- .../core/function/model/Function.scala | 6 +- .../model/std/StdRandomFunction.scala | 4 + .../model/std/StdUpperCaseFunction.scala | 3 + .../FunctionMapGeneratorAssembler.scala | 21 ++- .../RMLFNOTC0023-CSV/mapping.ttl | 19 ++- src/test/resources/log4j.properties | 2 +- .../scala/io/rml/framework/SandboxTests.scala | 3 + 12 files changed, 243 insertions(+), 44 deletions(-) create mode 100644 src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala diff --git a/src/main/resources/IDLabFunctions.jar b/src/main/resources/IDLabFunctions.jar index 9461a502c2c4b72b4f145d69a4cf15ed90a6b11b..290ceb15363961a2d317d52ede8683c04b8d7fe2 100644 GIT binary patch delta 2228 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 { + println(s"Unable to find ${methodName} using cls.getDeclaredMethod; returning the FIRST occurrence by name") + filterByMethodName(cls, methodName).headOption + } + } + } + + def filterByMethodName(cls : Class[_], methodName : String) : List[Method] = { + cls.getDeclaredMethods.filter(m=>m.getName.endsWith(methodName)).toList + } + + def castMethodUsingGenericParameterTypes(method : java.lang.reflect.Method, inputParameterValues : List[AnyRef]) = { + println(s"${getClass.getCanonicalName}#castMethodUsingGenericParameterTypes") + + val genericParameterTypes = method.getGenericParameterTypes + genericParameterTypes + .zip(inputParameterValues) + .map( + pair => { + val gt = pair._1 + val ip = pair._2 + gt.getTypeName match { + case "java.util.List" => { + val resultArrayList = new java.util.ArrayList[String]() + ip.asInstanceOf[List[_]].foreach(e=>resultArrayList.add(e.toString)) + resultArrayList + } + case _ => ip + } + } + ) + } + + /** + * Given a method and inputParameterValues, castMethodUsingParameterTypes will use the given method's parameter types + * to cast the input parameter values. + * + * @param method + * @param inputParameterValues + * @return + */ + def castMethodUsingParameterTypes(method : java.lang.reflect.Method, inputParameterValues : List[AnyRef]) = { + println(s"${getClass.getCanonicalName}#castMethodUsingParameterTypes") + + val parameterTypes = method.getParameterTypes + parameterTypes + .zip(inputParameterValues) + .map( + pair => { + val gt = pair._1 + val ip = pair._2 + gt.getTypeName match { + case "java.util.List" => { + val resultArrayList = new java.util.ArrayList[Object]() + ip.asInstanceOf[List[_]].foreach(e=>resultArrayList.add(e.toString)) + resultArrayList + } + case _ => ip + } + } + ) + } + +} diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala index cf49c974..5f0f600c 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala @@ -3,8 +3,9 @@ package io.rml.framework.core.function.model import java.io.{File, IOException, ObjectInputStream, ObjectOutputStream} import java.lang.reflect.Method -import io.rml.framework.core.function.FunctionUtils +import io.rml.framework.core.function.{FunctionUtils, ReflectionUtils} import io.rml.framework.core.model.{Entity, Literal, Uri} +import io.rml.framework.flink.sink.FlinkRDFQuad /** @@ -22,6 +23,60 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten out.defaultWriteObject() } + + override def execute(paramTriples: List[FlinkRDFQuad]): Option[Iterable[Entity]] = { + // if a group (key: uri) results in a list with 1 element, extract that single element + // otherwise, when a group has a list with more than 1 element, keep it as a list + val argResourcesGroupedByUri = paramTriples.groupBy(_.predicate).map{ + pair => { + pair._2.length match { + case 0 => pair._1.uri -> None + case 1 => pair._1.uri -> pair._2.head + case _ => pair._1.uri -> pair._2.toList + } + } + } + + val argObjectsGroupedByUri = argResourcesGroupedByUri.map{ + pair => { + if(pair._2.isInstanceOf[Iterable[FlinkRDFQuad]]){ + pair._1 -> pair._2.asInstanceOf[Iterable[FlinkRDFQuad]].map(x=>x.`object`.value.toString) + }else{ + pair._1 -> pair._2.asInstanceOf[FlinkRDFQuad].`object`.value.toString + } + + } + } + + val orderedArgValues = metaData + .inputParam + .sortBy(_.position) // iterate over input parameters by position + .map( + ip=> + { + + argObjectsGroupedByUri.get(ip.paramUri) + + } + ).flatten + + if(orderedArgValues.size == metaData.inputParam.size){ + val method = optMethod.getOrElse(throw new Exception("No method was initialized.")) + val castParameterValues = ReflectionUtils.castMethodUsingParameterTypes(method, orderedArgValues) + val output = method.invoke(null, castParameterValues:_*) + + if(output!=null) { + val result = metaData.outputParam.flatMap(elem => elem.getValue(output)) map (elem => Literal(elem.toString)) + Some(result) + }else + None + } + else None + + + + } + private def findMethod(classObject : Class[_], inputParameters : List[Parameter]) : Option[Method] = { try { Some(classObject.getDeclaredMethod(metaData.methodName, metaData.inputParam.map(_.paramType): _*)) @@ -62,40 +117,45 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { val inputParams = metaData.inputParam // casted to List[AnyRef] since method.invoke(...) only accepts reference type but not primitive type of Scala - val paramsOrdered = inputParams - .flatMap(param => { - val value = arguments.get(param.paramUri) - value match { - case Some(string) => param.getValue(string) - case _ => None - } - }) - .map(_.asInstanceOf[AnyRef]) +// val paramsOrdered = inputParams +// .flatMap(param => { +// val value = arguments.get(param.paramUri) +// value match { +// case Some(string) => param.getValue(string) +// case _ => None +// } +// }) +// .map(_.asInstanceOf[AnyRef]) + + + //val paramsOrdered = arguments.map(_._2.asInstanceOf[AnyRef]).toList + val paramsOrdered = arguments.groupBy(_._1.uri).map(_._2.asInstanceOf[AnyRef]).toList val outputParams = metaData.outputParam if (paramsOrdered.size == inputParams.size) { - val definiteMethod = optMethod.get + val method = optMethod.get + val castedParameterValues = ReflectionUtils.castMethodUsingParameterTypes(method,paramsOrdered) // let's cast every input parameter value to the corresponding parameter type of the method parameters - val castedParameterValues = - definiteMethod - .getParameterTypes - .zip(paramsOrdered) - .map( - pair => { - val t = pair._1.getName - val v = pair._2 - t match { - case "java.lang.Boolean"|"Boolean" => v.toString.toBoolean - case _ => v - } - } - ) - .map(_.asInstanceOf[AnyRef]) - .toList - - val output = definiteMethod.invoke(null, castedParameterValues: _*) +// val castedParameterValues = +// method +// .getParameterTypes +// .zip(paramsOrdered) +// .map( +// pair => { +// val t = pair._1.getName +// val v = pair._2 +// t match { +// case "java.lang.Boolean"|"Boolean" => v.toString.toBoolean +// case _ => v +// } +// } +// ) +// .map(_.asInstanceOf[AnyRef]) +// .toList + + val output = method.invoke(null, castedParameterValues: _*) if(output!=null) { val result = outputParams.flatMap(elem => elem.getValue(output)) map (elem => Literal(elem.toString)) @@ -109,6 +169,9 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten } } + + + override def getMethod: Option[Method] = { optMethod } diff --git a/src/main/scala/io/rml/framework/core/function/model/Function.scala b/src/main/scala/io/rml/framework/core/function/model/Function.scala index b29dd37a..c75f2db3 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Function.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Function.scala @@ -4,6 +4,7 @@ import java.lang.reflect.Method import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.{Entity, Node, Uri} +import io.rml.framework.flink.sink.FlinkRDFQuad trait Function extends Node with Logging{ @@ -13,7 +14,10 @@ trait Function extends Node with Logging{ //TODO: Doesn't support output of objects yet ! // it currently only support string representable outputs! - def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] + def execute(paramTriples: List[FlinkRDFQuad]): Option[Iterable[Entity]] + + + def execute(argumentsMap: Map[Uri, String]): Option[Iterable[Entity]] def initialize(): Function = { logDebug("initializing Function") diff --git a/src/main/scala/io/rml/framework/core/function/model/std/StdRandomFunction.scala b/src/main/scala/io/rml/framework/core/function/model/std/StdRandomFunction.scala index 76c4dd24..0e3b5fe3 100644 --- a/src/main/scala/io/rml/framework/core/function/model/std/StdRandomFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/std/StdRandomFunction.scala @@ -5,6 +5,7 @@ import java.lang.reflect.Method import io.rml.framework.core.function.model.Function import io.rml.framework.core.model.{Entity, Literal, Uri} import io.rml.framework.core.vocabulary.RMLVoc +import io.rml.framework.flink.sink.FlinkRDFQuad import scala.util.Random @@ -15,6 +16,9 @@ case class StdRandomFunction(identifier:String = RMLVoc.Property.GREL_RANDOM) ex Some(List(Literal(random.nextString(10)))) } + + override def execute(paramTriples: List[FlinkRDFQuad]): Option[Iterable[Entity]] = ??? + override def getMethod: Option[Method] = { None } diff --git a/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseFunction.scala b/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseFunction.scala index e21ca4d1..dbf6bb9c 100644 --- a/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseFunction.scala @@ -5,6 +5,7 @@ import java.lang.reflect.Method import io.rml.framework.core.function.model.Function import io.rml.framework.core.model.{Entity, Literal, Uri} import io.rml.framework.core.vocabulary.{Namespaces, RMLVoc} +import io.rml.framework.flink.sink.FlinkRDFQuad case class StdUpperCaseFunction(identifier: String = RMLVoc.Property.GREL_UPPERCASE) extends Function { override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { @@ -13,6 +14,8 @@ case class StdUpperCaseFunction(identifier: String = RMLVoc.Property.GREL_UPPERC parameter.map(string => List(Literal(string))) } + override def execute(paramTriples: List[FlinkRDFQuad]): Option[Iterable[Entity]] = ??? + override def getMethod: Option[Method] = { None } diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index 7c17df54..1c5012db 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -25,13 +25,14 @@ package io.rml.framework.engine.statement import java.io.File + import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.FunctionLoader -import io.rml.framework.core.function.model.Function +import io.rml.framework.core.function.{FunctionLoader, ReflectionUtils} +import io.rml.framework.core.function.model.{DynamicFunction, Function} import io.rml.framework.core.model._ import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item -import io.rml.framework.flink.sink.FlinkRDFQuad +import io.rml.framework.flink.sink.{FlinkRDFNode, FlinkRDFQuad} import io.rml.framework.flink.source.EmptyItem import io.rml.framework.shared.RMLException @@ -90,15 +91,13 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { private def createAssemblerFunction(function: Function, assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Item => Option[Iterable[Entity]] = { (item: Item) => { val triples: List[FlinkRDFQuad] = generateFunctionTriples(item, assembledPom) - val args: Map[Uri, String] = triples.filter(triple => triple.predicate.uri != Uri(RMLVoc.Property.EXECUTES)) - .map(triple => { - val parameterName = triple.predicate.uri - val parameterValue = triple.`object`.value.toString - parameterName -> parameterValue - }) - .toMap + val paramTriples = triples.filter(triple => triple.predicate.uri != Uri(RMLVoc.Property.EXECUTES)) + + function.initialize() - function.execute(args) + // efkes hier proberen om de method te invoken ipv in de function instantie zelf -- dit omzeilt aanpassingen aan execute signature + logDebug(s"executing ${function.toString}") + function.execute(paramTriples) } } diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl index eb3b9f21..987a170e 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl @@ -19,7 +19,7 @@ map:map_person_0 map:source_0 a rml:LogicalSource ; - rml:source "fno-testcases/RMLFNOTC0023-CSV/student.csv" ; + rml:source "failing/fno-testcases/RMLFNOTC0023-CSV/student.csv" ; rml:referenceFormulation ql:CSV . map:s_0 @@ -29,7 +29,7 @@ map:s_0 map:fn_0 rml:logicalSource map:source_0 ; - rr:predicateObjectMap map:pomexec_0, map:pom_0, map:pom_1 . + rr:predicateObjectMap map:pomexec_0, map:pom_0, map:pom_1 , map:pom_3 . map:pomexec_0 rr:predicateMap map:pmexec_0 ; @@ -97,3 +97,18 @@ map:om_2 a rr:ObjectMap ; rr:constant "http://xmlns.com/foaf/0.1/Person" ; rr:termType rr:IRI . + +# separator +map:pom_3 + a rr:PredicateObjectMap ; + rr:predicateMap map:pm_3 ; + rr:objectMap map:om_3 . + +map:pm_3 + a rr:PredicateMap ; + rr:constant grel:p_string_sep . + +map:om_3 + a rr:ObjectMap ; + rr:constant "SEPARATOOOOR" ; + rr:termType rr:Literal . diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties index c716fb6e..13f68f16 100644 --- a/src/test/resources/log4j.properties +++ b/src/test/resources/log4j.properties @@ -1,4 +1,4 @@ -log4j.rootLogger=INFO, stdout +log4j.rootLogger=DEBUG, stdout log4j.logger.org.apache.flink=WARN log4j.logger.kafka=ERROR log4j.logger.org.I0Itec.zkclient=ERROR diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index c1e0e8c0..986d771f 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -142,6 +142,9 @@ class SandboxTests extends FunSuite with Matchers { } + test("failing/fno-testcases/RMLFNOTC0023-CSV") { + executeTest("failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl") + } From 73c84ce10c6f3cb33338f44c7158cf5eec6e0426 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 25 Jun 2020 10:36:05 +0200 Subject: [PATCH 093/169] wip: function feature: supporting array parameters --- .../scala/io/rml/framework/core/function/ReflectionUtils.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala b/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala index 912ed13f..9266542e 100644 --- a/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala +++ b/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala @@ -80,10 +80,12 @@ object ReflectionUtils { ip.asInstanceOf[List[_]].foreach(e=>resultArrayList.add(e.toString)) resultArrayList } + case "java.lang.Boolean"|"Boolean" => ip.toString.toBoolean case _ => ip } } ) + .map(_.asInstanceOf[AnyRef]) } } From adb921e119823bf5182e9d23fdfdf0427b9b5a5f Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 25 Jun 2020 11:02:06 +0200 Subject: [PATCH 094/169] wip: function feature: refactoring + clean up --- .../core/function/ReflectionUtils.scala | 10 +++--- .../core/function/model/DynamicFunction.scala | 35 ++----------------- .../core/function/model/Function.scala | 6 ++-- 3 files changed, 9 insertions(+), 42 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala b/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala index 9266542e..adab8c4e 100644 --- a/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala +++ b/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala @@ -34,8 +34,8 @@ object ReflectionUtils { cls.getDeclaredMethods.filter(m=>m.getName.endsWith(methodName)).toList } - def castMethodUsingGenericParameterTypes(method : java.lang.reflect.Method, inputParameterValues : List[AnyRef]) = { - println(s"${getClass.getCanonicalName}#castMethodUsingGenericParameterTypes") + def castUsingGenericMethodParameterTypes(method : java.lang.reflect.Method, inputParameterValues : List[AnyRef]) = { + println(s"${getClass.getCanonicalName}#castUsingGenericMethodParameterTypes") val genericParameterTypes = method.getGenericParameterTypes genericParameterTypes @@ -57,15 +57,15 @@ object ReflectionUtils { } /** - * Given a method and inputParameterValues, castMethodUsingParameterTypes will use the given method's parameter types + * Given a method and inputParameterValues, castUsingMethodParameterTypes will use the given method's parameter types * to cast the input parameter values. * * @param method * @param inputParameterValues * @return */ - def castMethodUsingParameterTypes(method : java.lang.reflect.Method, inputParameterValues : List[AnyRef]) = { - println(s"${getClass.getCanonicalName}#castMethodUsingParameterTypes") + def castUsingMethodParameterTypes(method : java.lang.reflect.Method, inputParameterValues : List[AnyRef]) = { + println(s"${getClass.getCanonicalName}#castUsingMethodParameterTypes") val parameterTypes = method.getParameterTypes parameterTypes diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala index 5f0f600c..ed3c4674 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala @@ -62,7 +62,7 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten if(orderedArgValues.size == metaData.inputParam.size){ val method = optMethod.getOrElse(throw new Exception("No method was initialized.")) - val castParameterValues = ReflectionUtils.castMethodUsingParameterTypes(method, orderedArgValues) + val castParameterValues = ReflectionUtils.castUsingMethodParameterTypes(method, orderedArgValues) val output = method.invoke(null, castParameterValues:_*) if(output!=null) { @@ -117,44 +117,13 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { val inputParams = metaData.inputParam // casted to List[AnyRef] since method.invoke(...) only accepts reference type but not primitive type of Scala -// val paramsOrdered = inputParams -// .flatMap(param => { -// val value = arguments.get(param.paramUri) -// value match { -// case Some(string) => param.getValue(string) -// case _ => None -// } -// }) -// .map(_.asInstanceOf[AnyRef]) - - - //val paramsOrdered = arguments.map(_._2.asInstanceOf[AnyRef]).toList val paramsOrdered = arguments.groupBy(_._1.uri).map(_._2.asInstanceOf[AnyRef]).toList val outputParams = metaData.outputParam if (paramsOrdered.size == inputParams.size) { val method = optMethod.get - val castedParameterValues = ReflectionUtils.castMethodUsingParameterTypes(method,paramsOrdered) - - // let's cast every input parameter value to the corresponding parameter type of the method parameters -// val castedParameterValues = -// method -// .getParameterTypes -// .zip(paramsOrdered) -// .map( -// pair => { -// val t = pair._1.getName -// val v = pair._2 -// t match { -// case "java.lang.Boolean"|"Boolean" => v.toString.toBoolean -// case _ => v -// } -// } -// ) -// .map(_.asInstanceOf[AnyRef]) -// .toList - + val castedParameterValues = ReflectionUtils.castUsingMethodParameterTypes(method,paramsOrdered) val output = method.invoke(null, castedParameterValues: _*) if(output!=null) { diff --git a/src/main/scala/io/rml/framework/core/function/model/Function.scala b/src/main/scala/io/rml/framework/core/function/model/Function.scala index c75f2db3..d4ffb953 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Function.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Function.scala @@ -5,17 +5,15 @@ import java.lang.reflect.Method import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.{Entity, Node, Uri} import io.rml.framework.flink.sink.FlinkRDFQuad -trait Function extends Node with Logging{ +abstract class Function extends Node with Logging{ def name: Uri = Uri(identifier) def getMethod: Option[Method] - //TODO: Doesn't support output of objects yet ! - // it currently only support string representable outputs! - def execute(paramTriples: List[FlinkRDFQuad]): Option[Iterable[Entity]] + def execute(paramTriples: List[FlinkRDFQuad]): Option[Iterable[Entity]] def execute(argumentsMap: Map[Uri, String]): Option[Iterable[Entity]] From b10490db1ec20bfa1f1a6982d1752d32f04b3dfa Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 25 Jun 2020 11:04:18 +0200 Subject: [PATCH 095/169] marked "old" execute method as deprecated --- .../scala/io/rml/framework/core/function/model/Function.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/io/rml/framework/core/function/model/Function.scala b/src/main/scala/io/rml/framework/core/function/model/Function.scala index d4ffb953..21f8900c 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Function.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Function.scala @@ -15,6 +15,7 @@ abstract class Function extends Node with Logging{ def execute(paramTriples: List[FlinkRDFQuad]): Option[Iterable[Entity]] + @deprecated("Please use execute(paramTriples: List[FlinkRDFQuad]) instead") def execute(argumentsMap: Map[Uri, String]): Option[Iterable[Entity]] def initialize(): Function = { From eb40341fbfe4b0ef670d5f644c23a65473750878 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 25 Jun 2020 11:43:53 +0200 Subject: [PATCH 096/169] =?UTF-8?q?refactor=20map=20=E2=86=92=20flatten=20?= =?UTF-8?q?to=20flatMap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/function/model/DynamicFunction.scala | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala index ed3c4674..904735db 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala @@ -50,15 +50,11 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten val orderedArgValues = metaData .inputParam - .sortBy(_.position) // iterate over input parameters by position - .map( - ip=> - { + .sortBy(_.position).flatMap(ip => { - argObjectsGroupedByUri.get(ip.paramUri) + argObjectsGroupedByUri.get(ip.paramUri) - } - ).flatten + }) if(orderedArgValues.size == metaData.inputParam.size){ val method = optMethod.getOrElse(throw new Exception("No method was initialized.")) From 44e5cf8cb4d68ce247610dde3aa801391430a300 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 26 Jun 2020 15:18:03 +0200 Subject: [PATCH 097/169] fix: #25 - deployable on flink --- src/main/scala/io/rml/framework/Main.scala | 28 +++++++ .../io/rml/framework/api/RMLEnvironment.scala | 33 +++++++- .../core/function/FunctionLoader.scala | 82 ++++++++++--------- .../rml/framework/FunctionMappingTest.scala | 53 ++++++++++++ .../rml/framework/OutputGenerationTest.scala | 22 +---- .../scala/io/rml/framework/SandboxTests.scala | 27 +----- 6 files changed, 160 insertions(+), 85 deletions(-) create mode 100644 src/test/scala/io/rml/framework/FunctionMappingTest.scala diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index ac8d931b..2c4f42d3 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -48,6 +48,7 @@ import org.apache.flink.streaming.api.scala.{DataStream, OutputTag, StreamExecut import org.apache.flink.util.Collector import scala.collection.{immutable, mutable} +import scala.reflect.io.Path /** * @@ -89,10 +90,37 @@ object Main extends Logging { // Triple maps are also organized in categories (does it contain streams, does it contain joins, ... ) val formattedMapping = Util.readMappingFile(config.mappingFilePath) + + // Adding the default function descripion and default function mapping files to the RMLEnvironment. + // RMLStreamer will look for these files in directory of the JAR-file. + // TODO: support adding function related files using CLI arguments + val defaultFunctionDescriptionFilePaths = List( + "./functions_grel.ttl", + "./functions_idlab.ttl" + ) + + val defaultFunctionMappingFilePaths = List( + "./grel_java_mapping.ttl", + "./idlab_java_mapping.ttl" + ) + // adding default function description file paths to the RMLEnvironment + defaultFunctionDescriptionFilePaths.foreach(strPath=> { + val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) + RMLEnvironment.addFunctionDescriptionFilePath(p) + }) + + // adding default function description file paths to the RMLEnvironment + defaultFunctionMappingFilePaths.foreach(strPath=> { + val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) + RMLEnvironment.addFunctionMappingFilePaths(p) + }) + + // set up execution environments, Flink needs these to know how to operate (local, cluster mode, ...) implicit val env = ExecutionEnvironment.getExecutionEnvironment implicit val senv = StreamExecutionEnvironment.getExecutionEnvironment + if (config.checkpointInterval.isDefined) { senv.enableCheckpointing(config.checkpointInterval.get, CheckpointingMode.AT_LEAST_ONCE); // This is what Kafka supports ATM, see https://ci.apache.org/projects/flink/flink-docs-release-1.8/dev/connectors/guarantees.html } diff --git a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala index d088367b..510a0228 100644 --- a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala +++ b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala @@ -27,10 +27,13 @@ package io.rml.framework.api import java.io.File import io.rml.framework.core.extractors.MappingReader +import io.rml.framework.core.function.FunctionLoader import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping, Uri} import io.rml.framework.flink.item.Item -import scala.collection.mutable.{Map => MutableMap} +import scala.collection.mutable +import scala.collection.mutable.{MutableList, Map => MutableMap} +import scala.reflect.io.Path object RMLEnvironment { @@ -38,6 +41,9 @@ object RMLEnvironment { private val sources: MutableMap[Uri, Iterable[Item]] = MutableMap() private var generatorBaseIRI: Option[String] = None private var mappingFileBaseIRI: Option[String] = None + private val functionDescriptionFilePaths : mutable.MutableList[Path] = mutable.MutableList() + private val functionMappingFilePaths : mutable.MutableList[Path] = mutable.MutableList() + private var functionLoader : Option[FunctionLoader] = None def setGeneratorBaseIRI(baseIRI: Option[String]) = { generatorBaseIRI = baseIRI @@ -70,6 +76,31 @@ object RMLEnvironment { sources.put(uri, iterable) } + def getFunctionDescriptionFilePaths() = { + this.functionDescriptionFilePaths.toList + } + def addFunctionDescriptionFilePath(path : Path) = { + assert(path.exists) + this.functionDescriptionFilePaths += path + } + + def getFunctionMappingFilePaths() = { + this.functionMappingFilePaths.toList + } + def addFunctionMappingFilePaths(path : Path) = { + assert(path.exists) + this.functionMappingFilePaths += path + } + + def intializeFunctionLoader() = { + this.functionLoader = Some(FunctionLoader.apply(getFunctionDescriptionFilePaths(), getFunctionMappingFilePaths())) + this.functionLoader + } + def getFunctionLoader() = { + this.functionLoader.getOrElse{ + intializeFunctionLoader().getOrElse(throw new Exception("Unable to intialize function loader")) + } + } def getSource(uri: Uri): Option[Iterable[Item]] = { sources.get(uri) } diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index f7698f1d..f9a37d29 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -9,8 +9,13 @@ import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode} import io.rml.framework.core.util.Turtle +import io.rml.framework.core.util.Util +import org.apache.flink.api.scala.ExecutionEnvironment +import org.apache.flink.runtime.taskmanager.RuntimeEnvironment import scala.collection.mutable.{Map => MutableMap} +import scala.io.Source +import scala.reflect.io.Path abstract class FunctionLoader extends Logging { /** @@ -79,62 +84,59 @@ abstract class FunctionLoader extends Logging { object FunctionLoader extends Logging{ private var singletonFunctionLoader : Option[FunctionLoader] = None - private val defaultFunctionDescriptionFilePaths = List( - "functions_grel.ttl", - "functions_idlab.ttl" - ) - /** * Private helper method for reading in the function descriptions as an RDFGraph. * @param filePath * @return RDFGraph containing the function descriptions. */ private def readFunctionDescriptionsFromFile(filePath : String): RDFGraph = { - val functionDescriptionsFile = new File(getClass.getClassLoader.getResource(filePath).getFile) - if (!functionDescriptionsFile.exists()) - throw new FileNotFoundException(s"Couldn't find ${functionDescriptionsFile.getName}") - logDebug(s"FunctionLoader is reading function descriptions from : ${filePath}") - RDFGraph.fromFile(functionDescriptionsFile, RMLEnvironment.getGeneratorBaseIRI(), Turtle) + RDFGraph.fromFile(new File(filePath), RMLEnvironment.getGeneratorBaseIRI(), Turtle) } /** * Construction of the (singleton) FunctionLoader instance. * When the functionDescriptionFilePaths-list is empty, the default function descriptions are used. - * @param functionDescriptionFilePaths filepaths to the function descriptions. Default value is an empty list. + * @return FunctionLoader */ - def apply(functionDescriptionFilePaths : List[String] = List()): FunctionLoader = { - - if(singletonFunctionLoader.isEmpty) { - - // The functionDescriptionsGraph is populated by iterating over the filepaths of the function description files. - // When no filepaths are provided (i.e. functionDescriptionFilePaths is empty), the function loader will use the - // default function description files (i.e. defaultFunctionDescriptionFilePaths) - val fdit = if(functionDescriptionFilePaths.isEmpty) defaultFunctionDescriptionFilePaths.iterator else functionDescriptionFilePaths.iterator - - // construct the initial functionDescriptionTriplesGraph using the first functiondescription filepath - val functionDescriptionsGraph : Option[RDFGraph] = - if(fdit.hasNext) - Some(readFunctionDescriptionsFromFile(fdit.next())) - else - None - - // If more function description filepaths are specified, they will be read in. - // The resulting triples will be added to the functionDescriptionsGraph - while (fdit.hasNext) { - val fdescGraph = readFunctionDescriptionsFromFile(fdit.next()) - functionDescriptionsGraph.get.addTriples(fdescGraph.listTriples) + def apply(functionDescriptionPaths : List[Path] = RMLEnvironment.getFunctionDescriptionFilePaths(), + functionMappingPaths : List[Path] = RMLEnvironment.getFunctionMappingFilePaths() + ): FunctionLoader = { + if(singletonFunctionLoader.isEmpty) { + + // The functionDescriptionsGraph is populated by iterating over the filepaths of the function description files. + // These function description files are obtained from the RMLEnvironment. + val fdit =functionDescriptionPaths.map(_.path).iterator + // construct the initial functionDescriptionTriplesGraph using the first functiondescription filepath + val functionDescriptionsGraph : Option[RDFGraph] = + if(fdit.hasNext) + Some(readFunctionDescriptionsFromFile(fdit.next())) + else + None + + // If more function description filepaths are specified, they will be read in. + // The resulting triples will be added to the functionDescriptionsGraph + while (fdit.hasNext) { + val fdescGraph = readFunctionDescriptionsFromFile(fdit.next()) + functionDescriptionsGraph.get.addTriples(fdescGraph.listTriples) + } + + // construct functionLoader + if(functionDescriptionsGraph.isDefined) { + singletonFunctionLoader = Some(StdFunctionLoader(functionDescriptionsGraph.get)) + // now parse the mappings + functionMappingPaths.foreach(fmp=>singletonFunctionLoader.get.parseFunctionMapping(new File(fmp.path))) + + } + else + throw new Exception("Function description graph is none...") } - - // construct functionLoader - if(functionDescriptionsGraph.isDefined) - singletonFunctionLoader = Some(StdFunctionLoader(functionDescriptionsGraph.get)) - else - throw new Exception("Function description graph is none...") + singletonFunctionLoader.get } - singletonFunctionLoader.get - } + + + } diff --git a/src/test/scala/io/rml/framework/FunctionMappingTest.scala b/src/test/scala/io/rml/framework/FunctionMappingTest.scala new file mode 100644 index 00000000..4a0e1805 --- /dev/null +++ b/src/test/scala/io/rml/framework/FunctionMappingTest.scala @@ -0,0 +1,53 @@ +package io.rml.framework + +import java.io.File + +import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.function.FunctionLoader +import org.scalatest.{BeforeAndAfter, FunSuite} + +import scala.reflect.io.Path + + +object FunctionMappingSetup { + def setupFunctionLoader() = { + // function descriptions + val functionDescriptionFilePaths = List( + "functions_grel.ttl", + "functions_idlab.ttl" + ).map(fp=> + { + val f = new File(getClass.getClassLoader.getResource(fp).getFile) + Path.apply(f) + } + ) + + // add them to the RMLEnvironment + functionDescriptionFilePaths.foreach(p=>RMLEnvironment.addFunctionDescriptionFilePath(p)) + + + // function mappings + val functionMappingPaths = List( + "grel_java_mapping.ttl", + "idlab_java_mapping.ttl" + ).map(fp=> + { + val f = new File(getClass.getClassLoader.getResource(fp).getFile) + Path.apply(f) + } + ) + + // add them to the RMLEnvironment + functionMappingPaths.foreach(p=>RMLEnvironment.addFunctionMappingFilePaths(p)) + + // singleton FunctionLoader created and initialized with function descriptions and mappings from the RMLENvironment + val functionLoader = FunctionLoader() + } +} +trait FunctionMappingTest extends FunSuite with BeforeAndAfter { + + + before { + FunctionMappingSetup.setupFunctionLoader() + } +} \ No newline at end of file diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index b65376dc..baa91dbc 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -39,28 +39,8 @@ import scala.util.control.Exception class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour with BeforeAndAfter { - private def setupFunctionLoader() : Unit = { - // function descriptions - val functionDescriptionFilePaths = List( - "functions_grel.ttl", - "functions_idlab.ttl" - ) - - // function mappings - val grelJavaMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) - val idlabJavaMappingFile = new File(getClass.getClassLoader.getResource("idlab_java_mapping.ttl").getFile) - - // singleton FunctionLoader created and initialized with given function descriptions - val functionLoader = FunctionLoader(functionDescriptionFilePaths) - - // Parse the function mapping files. - // The functionloader will construct a mapping between function uris and the corresponding function meta data objects - functionLoader - .parseFunctionMapping(grelJavaMappingFile) - .parseFunctionMapping(idlabJavaMappingFile) - } before { - setupFunctionLoader() + FunctionMappingSetup.setupFunctionLoader() } diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index c1e0e8c0..b9b126bc 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -27,16 +27,17 @@ package io.rml.framework import java.io.File import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.FunctionLoader import io.rml.framework.core.util.Util import io.rml.framework.engine.NopPostProcessor import io.rml.framework.util.TestUtil import io.rml.framework.util.logging.Logger import org.apache.flink.api.scala.ExecutionEnvironment import org.apache.flink.streaming.api.scala._ -import org.scalatest.{DoNotDiscover, FunSuite, Matchers} +import org.scalatest.{FunSuite, Matchers} + + +class SandboxTests extends FunSuite with Matchers with FunctionMappingTest { -class SandboxTests extends FunSuite with Matchers { private def executeTest(mappingFile: String): Unit = { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.org/base/")) @@ -47,26 +48,6 @@ class SandboxTests extends FunSuite with Matchers { val testDir = Util.getFile(new File(mappingFile).getParent) val mappingFileAbs = new File(testDir, new File(mappingFile).getName) - // function descriptions - val functionDescriptionFilePaths = List( - "functions_grel.ttl", - "functions_idlab.ttl" - ) - - // function mappings - val grelJavaMappingFile = new File(getClass.getClassLoader.getResource("grel_java_mapping.ttl").getFile) - val idlabJavaMappingFile = new File(getClass.getClassLoader.getResource("idlab_java_mapping.ttl").getFile) - - // singleton FunctionLoader created and initialized with given function descriptions - val functionLoader = FunctionLoader(functionDescriptionFilePaths) - - // Parse the function mapping files. - // The functionloader will construct a mapping between function uris and the corresponding function meta data objects - functionLoader - .parseFunctionMapping(grelJavaMappingFile) - .parseFunctionMapping(idlabJavaMappingFile) - - // read the mapping val formattedMapping = Util.readMappingFile(mappingFileAbs.getAbsolutePath) From de1159c93f970dd5da917c887bde72d471072da4 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 26 Jun 2020 15:57:43 +0200 Subject: [PATCH 098/169] updated functions readme for deploying on Flink --- documentation/README_Functions.md | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/documentation/README_Functions.md b/documentation/README_Functions.md index 27bff65c..4740b30e 100644 --- a/documentation/README_Functions.md +++ b/documentation/README_Functions.md @@ -1,4 +1,47 @@ # README: Functions + + +When deploying and running jobs on Flink, make sure +- to place the external jar files, `IDLabFunctions.jar` and `GrelFunctions.jar`, in Flink's `lib` directory +- to place the following files in the directory where the `flink run ...` command is issued. +These files can be obtained from `src/main/resources`: + - `functions_grel.ttl` + - `functions_grel.ttl` + - `grel_java_mapping.ttl` + - `idlab_java_mapping.ttl` +--- + +## Example: RML Streamer + Flink +Flink's `lib` directory should contain the jar-files with the custom functions. In this example, these are marked with `*` +``` +flink-1.10.1-scala_2.11 + └── lib + ├── GrelFunctions.jar * + ├── IDLabFunctions.jar * + ├── flink-dist_2.11-1.10.1.jar + ├── flink-table-blink_2.11-1.10.1.jar + ├── flink-table_2.11-1.10.1.jar + ├── log4j-1.2.17.jar + └── slf4j-log4j12-1.7.15.jar +``` +When running the RML Streamer on Flink, the directory should look like +``` +. +├── RMLStreamer-2.0.1-SNAPSHOT.jar +├── functions_grel.ttl +├── functions_idlab.ttl +├── grel_java_mapping.ttl +├── idlab_java_mapping.ttl +├── mapping.ttl +└── input_data.csv +``` +Note that the function descriptions and function mappings are present. + +The command for running the RML Streamer on Flink should look like +``` +~/flink/flink-1.10.1-scala_2.11/bin/flink run -c io.rml.framework.Main RMLStreamer-2.0.1-SNAPSHOT.jar toFile --output-path $(pwd)'/out.ttl' -m mapping.ttl +``` + ## Test Cases ### FnO Tests The official FnO testcases that are working can be found at `test/resources/fno-testcases`. From 39ea48b6299ddc6a1b6627f43011494becd6984d Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 26 Jun 2020 16:41:24 +0200 Subject: [PATCH 099/169] refactored --- src/main/scala/io/rml/framework/Main.scala | 65 ++++++++++++------- .../io/rml/framework/api/RMLEnvironment.scala | 2 - .../io/rml/framework/core/util/Util.scala | 1 - 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index 2c4f42d3..4ac6c2df 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -26,6 +26,7 @@ package io.rml.framework **/ +import java.io.FileNotFoundException import java.util.Properties import io.rml.framework.api.RMLEnvironment @@ -91,29 +92,10 @@ object Main extends Logging { val formattedMapping = Util.readMappingFile(config.mappingFilePath) - // Adding the default function descripion and default function mapping files to the RMLEnvironment. - // RMLStreamer will look for these files in directory of the JAR-file. - // TODO: support adding function related files using CLI arguments - val defaultFunctionDescriptionFilePaths = List( - "./functions_grel.ttl", - "./functions_idlab.ttl" - ) + // Default function config + // TODO: support adding variable function related files using CLI arguments + loadDefaultFunctionConfiguration() - val defaultFunctionMappingFilePaths = List( - "./grel_java_mapping.ttl", - "./idlab_java_mapping.ttl" - ) - // adding default function description file paths to the RMLEnvironment - defaultFunctionDescriptionFilePaths.foreach(strPath=> { - val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) - RMLEnvironment.addFunctionDescriptionFilePath(p) - }) - - // adding default function description file paths to the RMLEnvironment - defaultFunctionMappingFilePaths.foreach(strPath=> { - val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) - RMLEnvironment.addFunctionMappingFilePaths(p) - }) // set up execution environments, Flink needs these to know how to operate (local, cluster mode, ...) @@ -610,5 +592,44 @@ object Main extends Logging { } else head } + /** + *Adding the default function descripion and default function mapping files to the RMLEnvironment. + *RMLStreamer will look for these files in directory where the RMLStreamer is executed from. + *Note: make sure to add jars with custom functions to Flink's `/lib` directory. + */ + private def loadDefaultFunctionConfiguration() = { + + val defaultFunctionDescriptionFilePaths = List( + "./functions_grel.ttl", + "./functions_idlab.ttl" + ) + + val defaultFunctionMappingFilePaths = List( + "./grel_java_mapping.ttl", + "./idlab_java_mapping.ttl" + ) + + // adding default function description file paths to the RMLEnvironment + defaultFunctionDescriptionFilePaths.foreach(strPath=> { + try + { + val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) + RMLEnvironment.addFunctionDescriptionFilePath(p) + } + catch { + case e : Exception => logWarning(s"Can't add function description file to RMLEnvironment ( $strPath ). This will result in errors when using functions! Exception: ${e.getMessage}") + } + }) + + // adding default function description file paths to the RMLEnvironment + defaultFunctionMappingFilePaths.foreach(strPath=> { + try { + val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) + RMLEnvironment.addFunctionMappingFilePaths(p) + }catch { + case e : Exception => logWarning(s"Can't add function mapping file to RMLEnvironment ( $strPath ). This will result in errors when using functions! Exception: ${e.getMessage}") + } + }) + } } diff --git a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala index 510a0228..6c5163dc 100644 --- a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala +++ b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala @@ -80,7 +80,6 @@ object RMLEnvironment { this.functionDescriptionFilePaths.toList } def addFunctionDescriptionFilePath(path : Path) = { - assert(path.exists) this.functionDescriptionFilePaths += path } @@ -88,7 +87,6 @@ object RMLEnvironment { this.functionMappingFilePaths.toList } def addFunctionMappingFilePaths(path : Path) = { - assert(path.exists) this.functionMappingFilePaths += path } diff --git a/src/main/scala/io/rml/framework/core/util/Util.scala b/src/main/scala/io/rml/framework/core/util/Util.scala index bc6fb5f0..08b1d379 100644 --- a/src/main/scala/io/rml/framework/core/util/Util.scala +++ b/src/main/scala/io/rml/framework/core/util/Util.scala @@ -205,7 +205,6 @@ object Util { val result = if (file_1.isAbsolute) { new File(path) } else { - println(path) val classLoader = getClass.getClassLoader new File(classLoader.getResource(path).getFile) } From 72b8a00fd4bed45fe2053a75810b85312a1578b3 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 30 Jun 2020 16:03:28 +0200 Subject: [PATCH 100/169] added streaming tests (kafka + tcp) + updated implementation report #91 --- .../resources/report/stream-fno/result.csv | 30 +++ .../kafka/RMLFNOTC0001-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0001-CSV/mapping.ttl | 49 +++++ .../kafka/RMLFNOTC0001-CSV/output.ttl | 1 + .../kafka/RMLFNOTC0002-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0002-CSV/mapping.ttl | 48 +++++ .../kafka/RMLFNOTC0002-CSV/output.ttl | 1 + .../kafka/RMLFNOTC0003-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0003-CSV/mapping.ttl | 51 +++++ .../kafka/RMLFNOTC0003-CSV/output.ttl | 1 + .../kafka/RMLFNOTC0004-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0004-CSV/mapping.ttl | 49 +++++ .../kafka/RMLFNOTC0004-CSV/output.ttl | 1 + .../kafka/RMLFNOTC0005-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0005-CSV/mapping.ttl | 47 +++++ .../kafka/RMLFNOTC0005-CSV/output.ttl | 1 + .../kafka/RMLFNOTC0006-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0006-CSV/mapping.ttl | 50 +++++ .../kafka/RMLFNOTC0006-CSV/output.nq | 1 + .../kafka/RMLFNOTC0007-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0007-CSV/mapping.ttl | 48 +++++ .../kafka/RMLFNOTC0007-CSV/output.ttl | 0 .../kafka/RMLFNOTC0008-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0008-CSV/mapping.ttl | 48 +++++ .../kafka/RMLFNOTC0008-CSV/output.ttl | 1 + .../kafka/RMLFNOTC0013-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0013-CSV/mapping.ttl | 48 +++++ .../kafka/RMLFNOTC0013-CSV/output.ttl | 1 + .../kafka/RMLFNOTC0018-CSV/datasource.csv | 2 + .../kafka/RMLFNOTC0018-CSV/mapping.ttl | 61 ++++++ .../kafka/RMLFNOTC0018-CSV/output.ttl | 1 + .../kafka/RMLFNOTCA004/datasource.csv | 2 + .../kafka/RMLFNOTCA004/mapping.ttl | 57 ++++++ .../kafka/RMLFNOTCA004/output.ttl | 1 + .../kafka/RMLFNOTCA004b/datasource.csv | 2 + .../kafka/RMLFNOTCA004b/mapping.ttl | 57 ++++++ .../kafka/RMLFNOTCA004b/output.ttl | 0 .../tcp/RMLFNOTC0001-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0001-CSV/mapping.ttl | 48 +++++ .../tcp/RMLFNOTC0001-CSV/output.ttl | 1 + .../tcp/RMLFNOTC0002-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0002-CSV/mapping.ttl | 47 +++++ .../tcp/RMLFNOTC0002-CSV/output.ttl | 1 + .../tcp/RMLFNOTC0003-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0003-CSV/mapping.ttl | 50 +++++ .../tcp/RMLFNOTC0003-CSV/output.ttl | 1 + .../tcp/RMLFNOTC0004-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0004-CSV/mapping.ttl | 48 +++++ .../tcp/RMLFNOTC0004-CSV/output.ttl | 1 + .../tcp/RMLFNOTC0005-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0005-CSV/mapping.ttl | 46 +++++ .../tcp/RMLFNOTC0005-CSV/output.ttl | 1 + .../tcp/RMLFNOTC0006-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0006-CSV/mapping.ttl | 49 +++++ .../tcp/RMLFNOTC0006-CSV/output.nq | 1 + .../tcp/RMLFNOTC0007-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0007-CSV/mapping.ttl | 47 +++++ .../tcp/RMLFNOTC0007-CSV/output.ttl | 0 .../tcp/RMLFNOTC0008-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0008-CSV/mapping.ttl | 47 +++++ .../tcp/RMLFNOTC0008-CSV/output.ttl | 1 + .../tcp/RMLFNOTC0013-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0013-CSV/mapping.ttl | 47 +++++ .../tcp/RMLFNOTC0013-CSV/output.ttl | 1 + .../tcp/RMLFNOTC0018-CSV/datasource.csv | 2 + .../tcp/RMLFNOTC0018-CSV/mapping.ttl | 60 ++++++ .../tcp/RMLFNOTC0018-CSV/output.ttl | 1 + .../tcp/RMLFNOTCA004/datasource.csv | 2 + .../tcp/RMLFNOTCA004/mapping.ttl | 56 ++++++ .../fno-testcases/tcp/RMLFNOTCA004/output.ttl | 1 + .../tcp/RMLFNOTCA004b/datasource.csv | 2 + .../tcp/RMLFNOTCA004b/mapping.ttl | 56 ++++++ .../tcp/RMLFNOTCA004b/output.ttl | 0 .../framework/KafkaStreamTestSyncFnO.scala | 178 ++++++++++++++++++ .../rml/framework/TCPStreamTestSyncFnO.scala | 156 +++++++++++++++ 75 files changed, 1646 insertions(+) create mode 100644 src/test/resources/report/stream-fno/result.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/output.nq create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/output.nq create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/output.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/datasource.csv create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/mapping.ttl create mode 100644 src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/output.ttl create mode 100644 src/test/scala/io/rml/framework/KafkaStreamTestSyncFnO.scala create mode 100644 src/test/scala/io/rml/framework/TCPStreamTestSyncFnO.scala diff --git a/src/test/resources/report/stream-fno/result.csv b/src/test/resources/report/stream-fno/result.csv new file mode 100644 index 00000000..e941b368 --- /dev/null +++ b/src/test/resources/report/stream-fno/result.csv @@ -0,0 +1,30 @@ +testid,result +RMLFNOTC0000-CSV,failed +RMLFNOTC0001-CSV,passed +RMLFNOTC0002-CSV,passed +RMLFNOTC0003-CSV,passed +RMLFNOTC0004-CSV,passed +RMLFNOTC0005-CSV,passed +RMLFNOTC0006-CSV,passed +RMLFNOTC0007-CSV,passed +RMLFNOTC0008-CSV,passed +RMLFNOTC0009-CSV,failed +RMLFNOTC0010-CSV,failed +RMLFNOTC0011-CSV,failed +RMLFNOTC0012-CSV,failed +RMLFNOTC0013-CSV,passed +RMLFNOTC0014-CSV,failed +RMLFNOTC0015-CSV,failed +RMLFNOTC0016-CSV,failed +RMLFNOTC0017-CSV,failed +RMLFNOTC0018-CSV,passed +RMLFNOTC0019-CSV,failed +RMLFNOTC0020-JSON,failed +RMLFNOTC0021-JSON,failed +RMLFNOTC0022-CSV,failed +RMLFNOTC0023-CSV,failed +RMLFNOTCA001,failed +RMLFNOTCA004,passed +RMLFNOTCA004b,passed +RMLFNOTCA005,failed +RMLFNOTCA006,failed diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/mapping.ttl new file mode 100644 index 00000000..63e5895c --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/mapping.ttl @@ -0,0 +1,49 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/output.ttl new file mode 100644 index 00000000..b0369690 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0001-CSV/output.ttl @@ -0,0 +1 @@ + "VENUS" . diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/mapping.ttl new file mode 100644 index 00000000..2744f4aa --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/mapping.ttl @@ -0,0 +1,48 @@ +# Function on object, 1 constant parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:constant "name" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/output.ttl new file mode 100644 index 00000000..fb8edf94 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0002-CSV/output.ttl @@ -0,0 +1 @@ + "NAME" . diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/mapping.ttl new file mode 100644 index 00000000..3f024829 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/mapping.ttl @@ -0,0 +1,51 @@ +# Function on object, 2 parameters + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:escape ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Comment" ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:modeParameter ; + rr:objectMap [ rr:constant "html" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/output.ttl new file mode 100644 index 00000000..af03220c --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0003-CSV/output.ttl @@ -0,0 +1 @@ + "A&B" . diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/mapping.ttl new file mode 100644 index 00000000..3c13e760 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/mapping.ttl @@ -0,0 +1,49 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicateMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ]; + rr:objectMap [ rr:constant foaf:name ; rr:termType rr:IRI ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/output.ttl new file mode 100644 index 00000000..4aa4759e --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0004-CSV/output.ttl @@ -0,0 +1 @@ + . diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/datasource.csv new file mode 100644 index 00000000..c33048c8 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,url +1,Venus,www.example.com diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/mapping.ttl new file mode 100644 index 00000000..4507a467 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/mapping.ttl @@ -0,0 +1,47 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "url" ] ] + ] ; + rr:termType rr:IRI + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/output.ttl new file mode 100644 index 00000000..80493637 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0005-CSV/output.ttl @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/mapping.ttl new file mode 100644 index 00000000..bda80750 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/mapping.ttl @@ -0,0 +1,50 @@ +# Function on graph, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] ; + rr:graphMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/output.nq b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/output.nq new file mode 100644 index 00000000..2258872a --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0006-CSV/output.nq @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/mapping.ttl new file mode 100644 index 00000000..8dc69696 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/mapping.ttl @@ -0,0 +1,48 @@ +# Function on object, 1 false reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "WrongReference" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0007-CSV/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/mapping.ttl new file mode 100644 index 00000000..834cf02c --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/mapping.ttl @@ -0,0 +1,48 @@ +# Function on object, 1 template parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:template "Name: {Name}" ; rr:termType rr:Literal ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/output.ttl new file mode 100644 index 00000000..5b69f570 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0008-CSV/output.ttl @@ -0,0 +1 @@ + "NAME: VENUS". diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/mapping.ttl new file mode 100644 index 00000000..cd60f869 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/mapping.ttl @@ -0,0 +1,48 @@ +# Function on object returns empty string + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:constant "" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/output.ttl new file mode 100644 index 00000000..6629e021 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0013-CSV/output.ttl @@ -0,0 +1 @@ + "" . diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/datasource.csv new file mode 100644 index 00000000..12614593 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/datasource.csv @@ -0,0 +1,2 @@ +id,name +0,ben & pieter \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/mapping.ttl new file mode 100644 index 00000000..205144cf --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/mapping.ttl @@ -0,0 +1,61 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{id}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:escape ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "name" ] ] + ] + ] ; + ]; + rr:predicateObjectMap [ + rr:predicate grel:modeParameter ; + rr:objectMap [ rr:constant "html" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/output.ttl new file mode 100644 index 00000000..2296c1ec --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTC0018-CSV/output.ttl @@ -0,0 +1 @@ + "BEN & PIETER" . diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/mapping.ttl new file mode 100644 index 00000000..023c01c3 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/mapping.ttl @@ -0,0 +1,57 @@ +# test true condition + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:trueCondition ] + ]; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:strBoolean ; + rr:objectMap [ rr:constant "true"] + ] ; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] + ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/output.ttl new file mode 100644 index 00000000..de68d8c0 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004/output.ttl @@ -0,0 +1 @@ + "Venus". \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/datasource.csv b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/mapping.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/mapping.ttl new file mode 100644 index 00000000..649ce9ea --- /dev/null +++ b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/mapping.ttl @@ -0,0 +1,57 @@ +# test true condition + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + + rdf:type rmls:KafkaStream ; + rmls:broker "localhost:9092"; + rmls:groupId "2"; + rmls:topic "demo" + ]; + rml:referenceFormulation ql:CSV +]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:trueCondition ] + ]; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:strBoolean ; + rr:objectMap [ rr:constant "false"] + ] ; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] + ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/output.ttl b/src/test/resources/stream/fno-testcases/kafka/RMLFNOTCA004b/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/mapping.ttl new file mode 100644 index 00000000..694e17e4 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/mapping.ttl @@ -0,0 +1,48 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/output.ttl new file mode 100644 index 00000000..b0369690 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/output.ttl @@ -0,0 +1 @@ + "VENUS" . diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/mapping.ttl new file mode 100644 index 00000000..6b6aa1f2 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/mapping.ttl @@ -0,0 +1,47 @@ +# Function on object, 1 constant parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:constant "name" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/output.ttl new file mode 100644 index 00000000..fb8edf94 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/output.ttl @@ -0,0 +1 @@ + "NAME" . diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/mapping.ttl new file mode 100644 index 00000000..5e3289ed --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/mapping.ttl @@ -0,0 +1,50 @@ +# Function on object, 2 parameters + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:escape ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Comment" ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:modeParameter ; + rr:objectMap [ rr:constant "html" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/output.ttl new file mode 100644 index 00000000..af03220c --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/output.ttl @@ -0,0 +1 @@ + "A&B" . diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/mapping.ttl new file mode 100644 index 00000000..0ac32471 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/mapping.ttl @@ -0,0 +1,48 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicateMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ]; + rr:objectMap [ rr:constant foaf:name ; rr:termType rr:IRI ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/output.ttl new file mode 100644 index 00000000..4aa4759e --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/output.ttl @@ -0,0 +1 @@ + . diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/datasource.csv new file mode 100644 index 00000000..c33048c8 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,url +1,Venus,www.example.com diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/mapping.ttl new file mode 100644 index 00000000..54a8a36c --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/mapping.ttl @@ -0,0 +1,46 @@ +# Function on predicate, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "url" ] ] + ] ; + rr:termType rr:IRI + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/output.ttl new file mode 100644 index 00000000..80493637 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/output.ttl @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/mapping.ttl new file mode 100644 index 00000000..735a42f0 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/mapping.ttl @@ -0,0 +1,49 @@ +# Function on graph, 1 parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ rml:reference "Name"] ; + rr:graphMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:toUpperCaseURL ] ] ; + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] ] + ] ; + rr:termType rr:IRI + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/output.nq b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/output.nq new file mode 100644 index 00000000..2258872a --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/output.nq @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/mapping.ttl new file mode 100644 index 00000000..3c123e13 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/mapping.ttl @@ -0,0 +1,47 @@ +# Function on object, 1 false reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "WrongReference" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/mapping.ttl new file mode 100644 index 00000000..a948b384 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/mapping.ttl @@ -0,0 +1,47 @@ +# Function on object, 1 template parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:template "Name: {Name}" ; rr:termType rr:Literal ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/output.ttl new file mode 100644 index 00000000..5b69f570 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/output.ttl @@ -0,0 +1 @@ + "NAME: VENUS". diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/mapping.ttl new file mode 100644 index 00000000..5ab8b98f --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/mapping.ttl @@ -0,0 +1,47 @@ +# Function on object returns empty string + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rr:constant "" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/output.ttl new file mode 100644 index 00000000..6629e021 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/output.ttl @@ -0,0 +1 @@ + "" . diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/datasource.csv new file mode 100644 index 00000000..12614593 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/datasource.csv @@ -0,0 +1,2 @@ +id,name +0,ben & pieter \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/mapping.ttl new file mode 100644 index 00000000..067af2ce --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/mapping.ttl @@ -0,0 +1,60 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix rdf: . +@prefix rmls: . + +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{id}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:escape ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "name" ] ] + ] + ] ; + ]; + rr:predicateObjectMap [ + rr:predicate grel:modeParameter ; + rr:objectMap [ rr:constant "html" ] ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/output.ttl new file mode 100644 index 00000000..2296c1ec --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/output.ttl @@ -0,0 +1 @@ + "BEN & PIETER" . diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/mapping.ttl new file mode 100644 index 00000000..c7223981 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/mapping.ttl @@ -0,0 +1,56 @@ +# test true condition + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:trueCondition ] + ]; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:strBoolean ; + rr:objectMap [ rr:constant "true"] + ] ; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] + ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/output.ttl new file mode 100644 index 00000000..de68d8c0 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/output.ttl @@ -0,0 +1 @@ + "Venus". \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/datasource.csv b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/datasource.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/datasource.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/mapping.ttl new file mode 100644 index 00000000..ebf90bf2 --- /dev/null +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/mapping.ttl @@ -0,0 +1,56 @@ +# test true condition + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix rdf: . +@prefix rmls: . + +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source [ + rdf:type rmls:TCPSocketStream ; + rmls:hostName "localhost" ; + rmls:port "9999" ; + rmls:type "PULL" + ]; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:trueCondition ] + ]; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:strBoolean ; + rr:objectMap [ rr:constant "false"] + ] ; + + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:reference "Name" ] + ] + ] + ] + ]. \ No newline at end of file diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/output.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/output.ttl new file mode 100644 index 00000000..e69de29b diff --git a/src/test/scala/io/rml/framework/KafkaStreamTestSyncFnO.scala b/src/test/scala/io/rml/framework/KafkaStreamTestSyncFnO.scala new file mode 100644 index 00000000..93303a3d --- /dev/null +++ b/src/test/scala/io/rml/framework/KafkaStreamTestSyncFnO.scala @@ -0,0 +1,178 @@ +/** + * MIT License + * + * Copyright (C) 2017 - 2020 RDF Mapping Language (RML) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **/ +package io.rml.framework + +import java.io.File +import java.util.Properties + +import io.rml.framework.util.server.TestData +import kafka.server.{KafkaConfig, KafkaServerStartable} +import org.apache.curator.test.TestingServer +import org.apache.kafka.clients.admin.AdminClient +import org.apache.kafka.clients.producer.{KafkaProducer, ProducerRecord} + +import scala.concurrent.ExecutionContextExecutor + +class KafkaStreamTestSyncFnO extends StreamTestSync{ + // initialise zookeeper, but do not start yet. + var zookeeper: TestingServer = _ + var kafka: KafkaServerStartable = _ + var admin: AdminClient = _ + var client: KafkaProducer[String, String] = _ + + + override def testFolder: String = "stream/fno-testcases/kafka" + + override def passingTests: Array[(String, String)] = Array( + (testFolder, "noopt") + + ) + + override def setup(): Unit = { + super.setup() + logInfo("Setting up FunctionLoader") + FunctionMappingSetup.setupFunctionLoader() + logInfo("Starting Zookeeper...") + zookeeper = new TestingServer( + getZkPort, + new File(getTempDir, "kafkazookeeper") + ) + logInfo("Zookeeper started.") + + logInfo("Starting Kafka...") + val config = new KafkaConfig(serverProperties) + kafka = new KafkaServerStartable(config) + kafka.startup() + logInfo("Kafka started.") + + logInfo("Creating Kafka admin client...") + admin = AdminClient.create(serverProperties) + logInfo("Kafka admin client created.") + + logInfo("Creating Kafka client...") + client = new KafkaProducer[String, String](producerProps) + logInfo("Creating Kafka client created.") + } + + + override def beforeTestCase(): Unit = { + // topics seem to be created automatically... + + /*logInfo("Creating Kafka input topic...") + val topicName = "demo" + val numPartitions = 1 + val replicationFactor = 1 + val topic = new NewTopic(topicName, numPartitions, replicationFactor.toShort) + val createTopicsResult = admin.createTopics(ArrayBuffer(topic).asJava) + createTopicsResult.all().get() // wait for completion of creating topics + Thread.sleep(2000) + logInfo("Creating Kafka input topic done.") */ + } + + override def afterTestCase(): Unit = { + logInfo("Deleting Kafka input topic(s)...") + val topics = admin.listTopics().names().get() + val deleteResults = admin.deleteTopics(topics) + deleteResults.all().get() + Thread.sleep(2000) // wait a bit for the topic to be *really* deleted! + logInfo("Kafka input topic(s) deleted.") + } + + override def teardown(): Unit = { + logInfo("Stopping Kafka admin client...") + if (admin != null) { + admin.close() + } + logInfo("Kafka admin client stopped.") + + logInfo("Shutting down Kafka...") + if (kafka != null) { + kafka.shutdown() + kafka.awaitShutdown() + } + logInfo("Kafka stopped.") + + logInfo("Shutting down Zookeeper") + if (zookeeper != null) { + zookeeper.close() + } + logInfo("Zookeeper stopped.") + } + + + override def writeData(input: List[TestData])(implicit executur: ExecutionContextExecutor): Unit = { + for (batch <- input) { + + val topic = if (input.size > 1) + batch.filename.replaceAll("\\..*", "") + else + "demo" + + for (in <- batch.data) { + logInfo(s"Writing record to Kafka: [${in}]") + val result = client.send(new ProducerRecord[String, String](topic, in)) + result.get() // wait until data is sent. + } + } + } + + ///////////////////////// + // some helper methods // + ///////////////////////// + private def serverProperties: Properties = { + val props = new Properties() + props.put("zookeeper.connect", "localhost:2181") + props.put("bootstrap.servers", "localhost:9092") + props.put("broker.id", "1") + props.put("port", "9092") + props.put("log.dir", new File(getTempDir, "kafka").getAbsolutePath) + props.put("host.name", "localhost") + props.put("delete.topic.enable", "true") + props.put("offsets.topic.replication.factor", "1") // by default it will expect 3 + props.put("offsets.topic.num.partitions", "1") // by default it will expect 3 + props + } + + private def producerProps: Properties = { + val props = new Properties() + props.put("bootstrap.servers", "localhost:9092") + props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer") + props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer") + props.put("acks", "1") + props + } + + private def getZkPort: Int = { + val inetAddress = serverProperties.getProperty("zookeeper.connect") + if (inetAddress == null || inetAddress.isEmpty || !inetAddress.contains(":")) { + throw new IllegalArgumentException("The given connection address in string is invalid.") + } + inetAddress.split(":")(1).toInt + } +} + +object KafkaStreamTestSyncFnO { + +} diff --git a/src/test/scala/io/rml/framework/TCPStreamTestSyncFnO.scala b/src/test/scala/io/rml/framework/TCPStreamTestSyncFnO.scala new file mode 100644 index 00000000..32a1a8f7 --- /dev/null +++ b/src/test/scala/io/rml/framework/TCPStreamTestSyncFnO.scala @@ -0,0 +1,156 @@ +/** + * MIT License + * + * Copyright (C) 2017 - 2020 RDF Mapping Language (RML) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **/ +package io.rml.framework + +import java.net.InetSocketAddress +import java.nio.charset.StandardCharsets +import java.util.concurrent.TimeUnit + +import io.netty.bootstrap.ServerBootstrap +import io.netty.buffer.ByteBuf +import io.netty.channel.nio.NioEventLoopGroup +import io.netty.channel.socket.SocketChannel +import io.netty.channel.socket.nio.NioServerSocketChannel +import io.netty.channel.{ChannelFuture, ChannelHandlerContext, ChannelInboundHandlerAdapter, ChannelInitializer} +import io.netty.util.{CharsetUtil, ReferenceCountUtil} +import io.rml.framework.util.logging.Logger +import io.rml.framework.util.server.TestData + +import scala.concurrent.{ExecutionContextExecutor, Future, Promise} + +class TCPStreamTestSyncFnO extends StreamTestSync { + var serverChannel: ChannelFuture = _ + var group: NioEventLoopGroup = _ + var lock: AnyRef with Specializable = _ + var promiseChContext: Promise[ChannelHandlerContext] = _ + + override def testFolder: String = "stream/fno-testcases/tcp" + + override def passingTests: Array[(String, String)] = Array( + ("stream/fno-testcases/tcp", "noopt") + ) + + + override def setup(): Unit = { + super.setup() + FunctionMappingSetup.setupFunctionLoader() + lock = AnyRef + promiseChContext = Promise[ChannelHandlerContext]() + logInfo("Setting up event loop group...") + group = new NioEventLoopGroup() + logInfo("Setting up event loop group done.") + logInfo("Setting up server bootstrap") + val serverBootstrap = new ServerBootstrap() + serverBootstrap.group(group) + serverBootstrap.channel(classOf[NioServerSocketChannel]) + serverBootstrap.localAddress(new InetSocketAddress("localhost", 9999)) + serverBootstrap.childHandler(new ChannelInitializer[SocketChannel]() { + override protected def initChannel(socketChannel: SocketChannel): Unit = { + socketChannel.pipeline.addLast( + new TCPServerHandler(Iterator.empty)) + } + }) + + serverChannel = serverBootstrap.bind.sync + + } + + override def beforeTestCase(): Unit = {} + + override def afterTestCase(): Unit = {} + + override def teardown(): Unit = { + Logger.logInfo("Stopping TCP server") + if (serverChannel != null) { + serverChannel.channel().closeFuture().await(10, TimeUnit.SECONDS) + } + if (group != null) { + group.shutdownGracefully(2, 10, TimeUnit.SECONDS).await() + } + Logger.logInfo("TCP server stopped.") + } + + override def writeData(input: List[TestData])(implicit executor: ExecutionContextExecutor): Unit = { + getChCtxFuture map { ctx => + Logger.logInfo(ctx.channel().toString) + for (batch <- input) { + for (el <- batch.data) { + el.split("\n").foreach(Logger.logInfo) + val bytesToSend = el.getBytes(StandardCharsets.UTF_8) + val byteBuff = ctx.alloc.buffer(bytesToSend.length) + byteBuff.writeBytes(bytesToSend) + ctx.channel.writeAndFlush(byteBuff).await() + } + } + } + } + + + def getChCtxFuture: Future[ChannelHandlerContext] = lock.synchronized { + promiseChContext.future + } + + + class TCPServerHandler(messages: Iterator[String]) extends ChannelInboundHandlerAdapter { + @throws[Exception] + override def channelRead(ctx: ChannelHandlerContext, msge: Any): Unit = { + val inBuffer = msge.asInstanceOf[ByteBuf] + val received = inBuffer.toString(CharsetUtil.UTF_8) + ReferenceCountUtil.release(msge) + + Logger.logInfo("TCPServer received: " + received) + + } + + + @throws[Exception] + override def channelReadComplete(ctx: ChannelHandlerContext): Unit = { + ctx.flush() + } + + override def channelActive(ctx: ChannelHandlerContext): Unit = { + lock.synchronized { + + + if (promiseChContext.isCompleted) { + promiseChContext = Promise[ChannelHandlerContext]() + } + promiseChContext success ctx + + messages.foreach(msg => { + val byteBufMsg = ctx.alloc.buffer(msg.length) + byteBufMsg.writeBytes(msg.getBytes) + ctx.channel.writeAndFlush(byteBufMsg) + }) + } + } + + @throws[Exception] + override def exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable): Unit = { + Logger.logError("Error while using TCP server: ", cause) + ctx.close + } + } +} From d2997ca9779c9f1efcc78374b0ee3bbf14e89c6e Mon Sep 17 00:00:00 2001 From: Thomas Delva Date: Tue, 30 Jun 2020 17:52:12 +0200 Subject: [PATCH 101/169] Hotfix for function parameter types for aaabim functions --- .../io/rml/framework/core/function/FunctionUtils.scala | 3 +++ .../io/rml/framework/core/function/model/Parameter.scala | 6 ++++++ .../scala/io/rml/framework/core/vocabulary/RMLVoc.scala | 4 +++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala index 54a78528..7a1fbff2 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala @@ -2,6 +2,7 @@ package io.rml.framework.core.function import java.io.File import java.net.MalformedURLException +import java.time.Instant import io.rml.framework.api.RMLEnvironment import io.rml.framework.core.function.model.Parameter @@ -65,6 +66,8 @@ object FunctionUtils extends Logging { case Uri(RMLVoc.Type.XSD_INT) => classOf[Int] case Uri(RMLVoc.Type.XSD_STRING) => classOf[String] case Uri(RMLVoc.Type.XSD_DOUBLE) => classOf[Double] + case Uri(RMLVoc.Type.XSD_LONG) => classOf[Long] + case Uri(RMLVoc.Type.XSD_DATETIME) => classOf[Instant] case Uri(RMLVoc.Type.XSD_BOOLEAN) => classOf[Boolean] case Uri(RMLVoc.Type.RDF_LIST) => classOf[List[_]] case Uri(RMLVoc.Type.XSD_ANY) => classOf[Any] diff --git a/src/main/scala/io/rml/framework/core/function/model/Parameter.scala b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala index 1852f714..7136d926 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Parameter.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Parameter.scala @@ -1,5 +1,7 @@ package io.rml.framework.core.function.model +import java.time.Instant + import io.rml.framework.core.model.{Node, Uri} import scala.util.parsing.json.JSON @@ -53,6 +55,8 @@ abstract class Parameter extends Node { val ArrayString = classOf[Array[_]].getName val ObjectString = classOf[Object].getName val BooleanString = classOf[Boolean].getName + val LongString = classOf[Long].getName + val InstantString = classOf[Instant].getName if(paramType== null) throw new NullPointerException("parameter type is null..") @@ -62,6 +66,8 @@ abstract class Parameter extends Node { case ScalaString | "java.lang.String" => Some(paraValue.toString) case IntegerString | "int" => Some(paraValue.toString.toInt) case DoubleString | "double" => Some(paraValue.toString.toDouble) + case LongString | "long" => Some(paraValue.toString.toLong) + case InstantString => Some(Instant.parse(paraValue.toString)) case ObjectString|"java.lang.Object" => Some(paraValue) case ListString | ArrayString | "java.util.List" => diff --git a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala index 808251bb..7aba736c 100644 --- a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala +++ b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala @@ -34,10 +34,12 @@ object RMLVoc { val XSD_STRING = Namespaces("xsd", "string") val XSD_INT = Namespaces("xsd", "int") // signed 32-bit integer val XSD_INTEGER = Namespaces("xsd", "integer") // integer value - val XSD_DOUBLE = Namespaces("xsd", "decimal") + val XSD_DOUBLE = Namespaces("xsd", "double") + val XSD_LONG = Namespaces("xsd", "long") val RDF_LIST = Namespaces("rdf", "List") val XSD_POSITIVE_INTEGER = Namespaces("xsd", "positiveInteger") val XSD_BOOLEAN = Namespaces("xsd", "boolean") + val XSD_DATETIME = Namespaces("xsd", "dateTime") val XSD_ANY = Namespaces("xsd", "any") val RDF_OBJECT = Namespaces("rdf", "object") From fd0a5608313e3ed57bfe9adf07cee34e4aa6f4dc Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 1 Jul 2020 11:53:19 +0200 Subject: [PATCH 102/169] wip: refactoring to ReflectionUtils --- .../core/function/ReflectionUtils.scala | 4 +- .../core/function/model/DynamicFunction.scala | 41 +++++++------------ .../FunctionMapGeneratorAssembler.scala | 3 +- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala b/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala index adab8c4e..90aefe12 100644 --- a/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala +++ b/src/main/scala/io/rml/framework/core/function/ReflectionUtils.scala @@ -18,7 +18,7 @@ object ReflectionUtils { throw new Exception(s"unable to load ${className}") } - def searchByMethodName(cls : Class[_], methodName : String, parameterTypes : Class[_]*) : Option[Method] = { + def searchByMethodNameAndParameterTypes(cls : Class[_], methodName : String, parameterTypes : Class[_]*) : Option[Method] = { try { Some(cls.getDeclaredMethod(methodName, parameterTypes:_*)) } @@ -67,6 +67,8 @@ object ReflectionUtils { def castUsingMethodParameterTypes(method : java.lang.reflect.Method, inputParameterValues : List[AnyRef]) = { println(s"${getClass.getCanonicalName}#castUsingMethodParameterTypes") + + val parameterTypes = method.getParameterTypes parameterTypes .zip(inputParameterValues) diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala index 904735db..7b5230f2 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala @@ -52,20 +52,28 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten .inputParam .sortBy(_.position).flatMap(ip => { - argObjectsGroupedByUri.get(ip.paramUri) + if(argObjectsGroupedByUri.contains(ip.paramUri)) + argObjectsGroupedByUri.get(ip.paramUri) + else + Some(null) }) if(orderedArgValues.size == metaData.inputParam.size){ val method = optMethod.getOrElse(throw new Exception("No method was initialized.")) - val castParameterValues = ReflectionUtils.castUsingMethodParameterTypes(method, orderedArgValues) - val output = method.invoke(null, castParameterValues:_*) + val castParameterValues: Array[AnyRef] = ReflectionUtils.castUsingMethodParameterTypes(method, orderedArgValues) - if(output!=null) { + try { + val output = method.invoke(null, castParameterValues:_*) val result = metaData.outputParam.flatMap(elem => elem.getValue(output)) map (elem => Literal(elem.toString)) Some(result) - }else - None + }catch { + case e : Exception => { + logError(s"The following exception occurred when invoking the method ${method.getName}: ${e.getMessage}." + + s"\nThe result will be set to None.") + None + } + } } else None @@ -73,32 +81,13 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten } - private def findMethod(classObject : Class[_], inputParameters : List[Parameter]) : Option[Method] = { - try { - Some(classObject.getDeclaredMethod(metaData.methodName, metaData.inputParam.map(_.paramType): _*)) - }catch{ - case e : NoSuchMethodException => { - this.logWarning(s"Unable to exactly match the function ${metaData.methodName} in ${metaData.className}.\n" + - s"Let's try to find the method ourself by filtering on method-name ONLY. [TODO]") - // try to find the method ourselfs - val declaredMethods = classObject.getDeclaredMethods - // first filter out methods with the same name - val filteredMethods = declaredMethods.filter(_.getName == metaData.methodName) - // Currently, just return the first available method and assume (hope) it will be correct // TODO: more specific method search - filteredMethods.headOption - } - } - - } - override def initialize(): Function = { if(optMethod.isEmpty) { val jarFile = getClass.getClassLoader.getResource(metaData.source).getFile - val classOfMethod = FunctionUtils.loadClassFromJar(new File(jarFile), metaData.className) - optMethod = findMethod(classOfMethod, metaData.inputParam) + optMethod = ReflectionUtils.searchByMethodNameAndParameterTypes(classOfMethod, metaData.methodName, metaData.inputParam.map(_.paramType): _*) } this } diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index 1c5012db..2c646751 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -45,7 +45,7 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { val functionMap = termMap.asInstanceOf[FunctionMap] val pomAssembler = PredicateObjectGeneratorAssembler() - val assembledPom = functionMap.functionValue + val assembledPom = functionMap.functionValue.sortBy(_.identifier) // sortBy required for retaining correct parameter ordering .flatMap(pomAssembler.assemble) .map { case (predicateGen, objGen, _) => (predicateGen, objGen) @@ -95,7 +95,6 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { function.initialize() - // efkes hier proberen om de method te invoken ipv in de function instantie zelf -- dit omzeilt aanpassingen aan execute signature logDebug(s"executing ${function.toString}") function.execute(paramTriples) } From 09bbc689d09e2272745ab3080ca1891ca5da0cb9 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 1 Jul 2020 12:39:18 +0200 Subject: [PATCH 103/169] wip: refactoring to ReflectionUtils --- src/test/scala/io/rml/framework/SandboxTests.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 0d10d25d..e254de47 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -124,6 +124,7 @@ class SandboxTests extends FunSuite with Matchers with FunctionMappingTest { test("failing/fno-testcases/RMLFNOTC0023-CSV") { + pending executeTest("failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl") } From fd8e99406a871987345988aa30d2b8617179cc80 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 2 Jul 2020 10:32:12 +0200 Subject: [PATCH 104/169] enabled apache flink web ui MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit useful during the debugging → tests that are submitted as jobs can now be monitored through the Web UI (usually: localhost:50000) --- pom.xml | 8 ++++++++ src/test/scala/io/rml/framework/StreamTestSync.scala | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2e992c8a..42f9e473 100644 --- a/pom.xml +++ b/pom.xml @@ -240,6 +240,8 @@ SOFTWARE. ${flink.version} + + org.apache.kafka kafka_${scala.binary.version} @@ -313,6 +315,12 @@ SOFTWARE. ${flink.version} compile + + + org.apache.flink + flink-runtime-web_2.11 + ${flink.version} + diff --git a/src/test/scala/io/rml/framework/StreamTestSync.scala b/src/test/scala/io/rml/framework/StreamTestSync.scala index 81b95bd9..4bfc12e5 100644 --- a/src/test/scala/io/rml/framework/StreamTestSync.scala +++ b/src/test/scala/io/rml/framework/StreamTestSync.scala @@ -115,7 +115,8 @@ abstract class StreamTestSync extends StaticTestSpec with ReadMappingBehaviour w // set up the execution environments implicit val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment - implicit val senv: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment + implicit val senv: StreamExecutionEnvironment = StreamExecutionEnvironment.createLocalEnvironmentWithWebUI() + implicit val executor: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newCachedThreadPool()) // create data stream and sink @@ -200,6 +201,7 @@ abstract class StreamTestSync extends StaticTestSpec with ReadMappingBehaviour w val customConfig = new Configuration() customConfig.setString("io.tmp.dirs", getTempDir.getAbsolutePath) customConfig.setString("rest.bind-port", "50000-51000") // see https://github.com/apache/flink/commit/730eed71ef3f718d61f85d5e94b1060844ca56db + val configuration = new MiniClusterConfiguration.Builder() .setConfiguration(customConfig) .setNumTaskManagers(1) From 5789859be7983336ab3b86a76c8611de950e3a07 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 10 Jul 2020 15:03:12 +0200 Subject: [PATCH 105/169] wip: supporting use of external jars using preprocessing rich map func wip: supporting use of external jars -- refactoring wip: supporting use of external jars -- refactoring - Moved function/FnO-related code from RMLEnvironment to FnOEnvironment - Optimized imports wip: supporting use of external jars -- refactoring + documenting FunctionLoader - renamed `loadFunction` to `createFunction` --- documentation/README_Functions.md | 3 +- src/main/scala/io/rml/framework/Main.scala | 75 ++++++----- .../io/rml/framework/api/FnOEnvironment.scala | 84 +++++++++++++ .../io/rml/framework/api/RMLEnvironment.scala | 25 ---- .../core/function/FunctionLoader.scala | 33 +++-- .../function/flink/FnOEnvironmentLoader.scala | 119 ++++++++++++++++++ .../core/function/model/DynamicFunction.scala | 69 ++++++---- .../core/function/model/Function.scala | 4 - .../FunctionMapGeneratorAssembler.scala | 5 +- .../rml/framework/FunctionMappingTest.scala | 55 ++------ 10 files changed, 314 insertions(+), 158 deletions(-) create mode 100644 src/main/scala/io/rml/framework/api/FnOEnvironment.scala create mode 100644 src/main/scala/io/rml/framework/core/function/flink/FnOEnvironmentLoader.scala diff --git a/documentation/README_Functions.md b/documentation/README_Functions.md index 4740b30e..911eb681 100644 --- a/documentation/README_Functions.md +++ b/documentation/README_Functions.md @@ -2,7 +2,8 @@ When deploying and running jobs on Flink, make sure -- to place the external jar files, `IDLabFunctions.jar` and `GrelFunctions.jar`, in Flink's `lib` directory +- to either place the external jars (e.g. `IDLabFunctions.jar` and `GrelFunctions.jar`) in Flink's `lib` directory, +or package the RMLStreamer along with those jars by placing them in `src/main/resources`. - to place the following files in the directory where the `flink run ...` command is issued. These files can be obtained from `src/main/resources`: - `functions_grel.ttl` diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index 4ac6c2df..caab8a9b 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -27,9 +27,11 @@ package io.rml.framework import java.io.FileNotFoundException +import java.net.URLClassLoader import java.util.Properties -import io.rml.framework.api.RMLEnvironment +import io.rml.framework.api.{FnOEnvironment, RMLEnvironment} +import io.rml.framework.core.function.flink.{FnOEnvironmentLoader, FnOEnvironmentStreamLoader, RichItemIdentityFunction, RichStreamItemIdentityFunction} import io.rml.framework.core.internal.Logging import io.rml.framework.core.model._ import io.rml.framework.core.util.{StreamerConfig, Util} @@ -40,8 +42,11 @@ import io.rml.framework.flink.item.{Item, JoinedItem} import io.rml.framework.flink.source.{EmptyItem, FileDataSet, Source} import io.rml.framework.flink.util.ParameterUtil import io.rml.framework.flink.util.ParameterUtil.{OutputSinkOption, PostProcessorOption} +import org.apache.flink.api.common.functions.RichMapFunction import org.apache.flink.api.common.serialization.SimpleStringSchema import org.apache.flink.api.scala._ +import org.apache.flink.api.scala.typeutils.Types +import org.apache.flink.configuration.Configuration import org.apache.flink.core.fs.FileSystem.WriteMode import org.apache.flink.streaming.api.CheckpointingMode import org.apache.flink.streaming.api.functions.ProcessFunction @@ -50,6 +55,7 @@ import org.apache.flink.util.Collector import scala.collection.{immutable, mutable} import scala.reflect.io.Path +import scala.util.{Failure, Success, Try} /** * @@ -94,7 +100,8 @@ object Main extends Logging { // Default function config // TODO: support adding variable function related files using CLI arguments - loadDefaultFunctionConfiguration() + FnOEnvironment.loadDefaultConfiguration() + FnOEnvironment.intializeFunctionLoader() @@ -203,6 +210,17 @@ object Main extends Logging { } }) + val preProcessingFunction = + if(FnOEnvironment.getFunctionLoader.isDefined){ + val functionLoaderOption = FnOEnvironment.getFunctionLoader + val jarSources = functionLoaderOption.get.getSources + val classNames = functionLoaderOption.get.getClassNames + new FnOEnvironmentStreamLoader(jarSources , classNames) + }else { + logInfo("FunctionLoader in RMLEnvironment is NOT DEFINED") + new RichStreamItemIdentityFunction() + } + // This is the collection of all data streams that are created by the current mapping val processedStreams: immutable.Iterable[DataStream[String]] = sourceEngineMap.map(entry => { @@ -211,6 +229,8 @@ object Main extends Logging { // link the different steps in each pipeline source.stream // this will generate a stream of items // process every item by a processor with a loaded engine + + .map(preProcessingFunction) .map(new StdStreamProcessor(engine)) .name("Execute mapping statements on items") @@ -446,6 +466,17 @@ object Main extends Logging { } }) + val preProcessingFunction = + if(FnOEnvironment.getFunctionLoader.isDefined){ + val functionLoaderOption = FnOEnvironment.getFunctionLoader + val jarSources = functionLoaderOption.get.getSources + val classNames = functionLoaderOption.get.getClassNames + new FnOEnvironmentLoader(jarSources , classNames) + }else { + logInfo("FunctionLoader in RMLEnvironment is NOT DEFINED") + new RichItemIdentityFunction() + } + // This is the collection of all data streams that are created by the current mapping val processedDataSets: immutable.Iterable[DataSet[String]] = sourceEngineMap.map(entry => { @@ -455,6 +486,7 @@ object Main extends Logging { source.dataset // this will generate a dataset of items // process every item by a processor with a loaded engine + .map(preProcessingFunction) .map(new StdStaticProcessor(engine)) .name("Execute mapping statements on items") @@ -592,44 +624,7 @@ object Main extends Logging { } else head } - /** - *Adding the default function descripion and default function mapping files to the RMLEnvironment. - *RMLStreamer will look for these files in directory where the RMLStreamer is executed from. - *Note: make sure to add jars with custom functions to Flink's `/lib` directory. - */ - private def loadDefaultFunctionConfiguration() = { - - val defaultFunctionDescriptionFilePaths = List( - "./functions_grel.ttl", - "./functions_idlab.ttl" - ) - - val defaultFunctionMappingFilePaths = List( - "./grel_java_mapping.ttl", - "./idlab_java_mapping.ttl" - ) - - // adding default function description file paths to the RMLEnvironment - defaultFunctionDescriptionFilePaths.foreach(strPath=> { - try - { - val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) - RMLEnvironment.addFunctionDescriptionFilePath(p) - } - catch { - case e : Exception => logWarning(s"Can't add function description file to RMLEnvironment ( $strPath ). This will result in errors when using functions! Exception: ${e.getMessage}") - } - }) - // adding default function description file paths to the RMLEnvironment - defaultFunctionMappingFilePaths.foreach(strPath=> { - try { - val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) - RMLEnvironment.addFunctionMappingFilePaths(p) - }catch { - case e : Exception => logWarning(s"Can't add function mapping file to RMLEnvironment ( $strPath ). This will result in errors when using functions! Exception: ${e.getMessage}") - } - }) - } + } diff --git a/src/main/scala/io/rml/framework/api/FnOEnvironment.scala b/src/main/scala/io/rml/framework/api/FnOEnvironment.scala new file mode 100644 index 00000000..34b00cab --- /dev/null +++ b/src/main/scala/io/rml/framework/api/FnOEnvironment.scala @@ -0,0 +1,84 @@ +package io.rml.framework.api + +import io.rml.framework.core.function.FunctionLoader +import io.rml.framework.core.internal.Logging +import io.rml.framework.core.util.Util + +import scala.collection.mutable +import scala.reflect.io.Path + +object FnOEnvironment extends Logging{ + private val functionDescriptionFilePaths : mutable.MutableList[Path] = mutable.MutableList() + private val functionMappingFilePaths : mutable.MutableList[Path] = mutable.MutableList() + private var functionLoader : Option[FunctionLoader] = None + val loadedClassesMap : scala.collection.mutable.Map[String, Class[_]] = scala.collection.mutable.Map() + + def getFunctionDescriptionFilePaths() = { + this.functionDescriptionFilePaths.toList + } + def addFunctionDescriptionFilePath(path : Path) : Unit = { + this.functionDescriptionFilePaths += path + } + + def getFunctionMappingFilePaths() = { + this.functionMappingFilePaths.toList + } + def addFunctionMappingFilePaths(path : Path): Unit = { + this.functionMappingFilePaths += path + } + + def intializeFunctionLoader() = { + this.functionLoader = Some(FunctionLoader.apply(getFunctionDescriptionFilePaths(), getFunctionMappingFilePaths())) + this.functionLoader + } + def getFunctionLoader: Option[FunctionLoader] = { + this.functionLoader + } + + /** + * Default FnO Configuration. + * Function descriptions: + * - functions_grel.ttl + * - functions_idlab.ttl + * Function mappings + * - grel_java_mapping.ttl + * - idlab_java_mapping.ttl + * + * RMLStreamer will look for these files in directory where the RMLStreamer is executed from. + * Note: make sure to add jars with custom functions to Flink's `/lib` directory. + */ + def loadDefaultConfiguration() = { + + val defaultFunctionDescriptionFilePaths = List( + "./functions_grel.ttl", + "./functions_idlab.ttl" + ) + + val defaultFunctionMappingFilePaths = List( + "./grel_java_mapping.ttl", + "./idlab_java_mapping.ttl" + ) + + // adding default function description file paths to the RMLEnvironment + defaultFunctionDescriptionFilePaths.foreach(strPath=> { + try + { + val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) + FnOEnvironment.addFunctionDescriptionFilePath(p) + } + catch { + case e : Exception => logWarning(s"Can't add function description file to RMLEnvironment ( $strPath ). This will result in errors when using functions! Exception: ${e.getMessage}") + } + }) + + // adding default function description file paths to the RMLEnvironment + defaultFunctionMappingFilePaths.foreach(strPath=> { + try { + val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) + FnOEnvironment.addFunctionMappingFilePaths(p) + }catch { + case e : Exception => logWarning(s"Can't add function mapping file to RMLEnvironment ( $strPath ). This will result in errors when using functions! Exception: ${e.getMessage}") + } + }) + } +} diff --git a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala index 6c5163dc..fc6afaf3 100644 --- a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala +++ b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala @@ -41,9 +41,6 @@ object RMLEnvironment { private val sources: MutableMap[Uri, Iterable[Item]] = MutableMap() private var generatorBaseIRI: Option[String] = None private var mappingFileBaseIRI: Option[String] = None - private val functionDescriptionFilePaths : mutable.MutableList[Path] = mutable.MutableList() - private val functionMappingFilePaths : mutable.MutableList[Path] = mutable.MutableList() - private var functionLoader : Option[FunctionLoader] = None def setGeneratorBaseIRI(baseIRI: Option[String]) = { generatorBaseIRI = baseIRI @@ -76,29 +73,7 @@ object RMLEnvironment { sources.put(uri, iterable) } - def getFunctionDescriptionFilePaths() = { - this.functionDescriptionFilePaths.toList - } - def addFunctionDescriptionFilePath(path : Path) = { - this.functionDescriptionFilePaths += path - } - def getFunctionMappingFilePaths() = { - this.functionMappingFilePaths.toList - } - def addFunctionMappingFilePaths(path : Path) = { - this.functionMappingFilePaths += path - } - - def intializeFunctionLoader() = { - this.functionLoader = Some(FunctionLoader.apply(getFunctionDescriptionFilePaths(), getFunctionMappingFilePaths())) - this.functionLoader - } - def getFunctionLoader() = { - this.functionLoader.getOrElse{ - intializeFunctionLoader().getOrElse(throw new Exception("Unable to intialize function loader")) - } - } def getSource(uri: Uri): Option[Iterable[Item]] = { sources.get(uri) } diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index f9a37d29..601a9a64 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -1,20 +1,16 @@ package io.rml.framework.core.function -import java.io.{File, FileNotFoundException, IOException} +import java.io.{File, IOException} -import io.rml.framework.api.RMLEnvironment +import io.rml.framework.api.{FnOEnvironment, RMLEnvironment} import io.rml.framework.core.function.model.{Function, FunctionMetaData, Parameter} import io.rml.framework.core.function.std.StdFunctionLoader import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode} import io.rml.framework.core.util.Turtle -import io.rml.framework.core.util.Util -import org.apache.flink.api.scala.ExecutionEnvironment -import org.apache.flink.runtime.taskmanager.RuntimeEnvironment import scala.collection.mutable.{Map => MutableMap} -import scala.io.Source import scala.reflect.io.Path abstract class FunctionLoader extends Logging { @@ -23,21 +19,26 @@ abstract class FunctionLoader extends Logging { */ protected val functionMap: MutableMap[Uri, FunctionMetaData] = MutableMap() + def getSources: List[String] = { + functionMap.values.map(_.source).toList.distinct + } + def getClassNames : List[String] = { + functionMap.values.map(_.className).toList.distinct + } /** - * Searches for the given function uri in the function map and dynamically load - * that function, if present. + * Creates and returns a [[Function]] for [[FunctionMetaData]] given function [[Uri]], if the function uri is present. * - * @param uri Function Uri - * @return [[Option]] of dynamically loaded function + * @param uri: function uri + * @return function (if successful) */ - def loadFunction(uri: Uri): Option[Function] = { - logDebug(s"loadFunction: ${uri.uri}") + def createFunction(uri: Uri): Option[Function] = { + logDebug(s"createFunction: ${uri.uri}") val optFunctionMetaData = functionMap.get(uri) if (optFunctionMetaData.isDefined) { val functionMetaData = optFunctionMetaData.get - logDebug(s"Dynamically loading function: $uri, ${functionMetaData.toString}" ) + logDebug(s"Creating function: $uri, ${functionMetaData.toString}" ) Some(Function(functionMetaData.identifier, functionMetaData)) } else { // when the function uri is not present in the function map, complain. @@ -96,12 +97,10 @@ object FunctionLoader extends Logging{ /** * Construction of the (singleton) FunctionLoader instance. - * When the functionDescriptionFilePaths-list is empty, the default function descriptions are used. - * @return FunctionLoader */ - def apply(functionDescriptionPaths : List[Path] = RMLEnvironment.getFunctionDescriptionFilePaths(), - functionMappingPaths : List[Path] = RMLEnvironment.getFunctionMappingFilePaths() + def apply(functionDescriptionPaths : List[Path] = FnOEnvironment.getFunctionDescriptionFilePaths(), + functionMappingPaths : List[Path] = FnOEnvironment.getFunctionMappingFilePaths() ): FunctionLoader = { if(singletonFunctionLoader.isEmpty) { diff --git a/src/main/scala/io/rml/framework/core/function/flink/FnOEnvironmentLoader.scala b/src/main/scala/io/rml/framework/core/function/flink/FnOEnvironmentLoader.scala new file mode 100644 index 00000000..9c714baa --- /dev/null +++ b/src/main/scala/io/rml/framework/core/function/flink/FnOEnvironmentLoader.scala @@ -0,0 +1,119 @@ +package io.rml.framework.core.function.flink + +import java.net.URLClassLoader + +import io.rml.framework.Main.logError +import io.rml.framework.api.FnOEnvironment +import io.rml.framework.flink.item.Item +import org.apache.flink.api.common.functions.RichMapFunction +import org.apache.flink.configuration.Configuration + +import scala.util.{Failure, Success, Try} + +/** + * AbstractRichIdentityFunction-subtypes do not alter or access the input data. + * They can be used to access the runtime context before or after the map-function is called, + * using the .open() and .close() inherited from RichMapFunction, respectively. + * + * + * @tparam T + */ +abstract class AbstractRichIdentityFunction[T] extends RichMapFunction[T,T] { + /** + * Identity. Passes input to output. + * @param value + * @return + */ + override def map(value: T): T = value +} + +/** + * Trait for RichMapFunction that use streams (i.e. Iterables of types IN|OUT) + * @tparam IN: input type of + * @tparam OUT + */ +trait RichStreamFunction[IN,OUT] extends RichMapFunction[Iterable[IN], Iterable[OUT]] + +/** + * + * @tparam T + */ +abstract class AbstractRichIdentityStreamFunction[T] extends RichStreamFunction[T,T] { + override def map(value: Iterable[T]): Iterable[T] = value +} + +/** + * Concrete class that only passes a stream of [[Item]] + */ +class RichStreamItemIdentityFunction extends AbstractRichIdentityStreamFunction[Item] + +/** + * Concrete class that only passes [[Item]] + */ +class RichItemIdentityFunction extends AbstractRichIdentityFunction[Item] + +/** + * + * Looks for the given list of [[jarNames]] using the runtime context's classloader which is used + * to load the given [[classNames]] into the [[FnOEnvironment]]. + * + * @param jarNames + * @param classNames + */ +class AbstractFnOEnvironmentLoader[T](jarNames : List[String], + classNames : List[String]) extends AbstractRichIdentityFunction[T] { + override def open(parameters: Configuration): Unit = { + + /** + * It usually works to put the job’s JAR file into the /lib directory. The JAR + * will be part of both the classpath (the AppClassLoader) and the dynamic class + * loader (FlinkUserCodeClassLoader). Because the AppClassLoader is the parent of + * the FlinkUserCodeClassLoader (and Java loads parent-first, by default), this + * should result in classes being loaded only once. + * Ref: https://ci.apache.org/projects/flink/flink-docs-stable/monitoring/debugging_classloading.html#avoiding-dynamic-classloading-for-user-code + */ + + // 1. find resource URLs using UserCodeClassLoader + val ucl = getRuntimeContext.getUserCodeClassLoader + val resourceURLs = jarNames.map(jn=>ucl.getResource(jn)) + + // 2. initialize URLClassLoader with resource URLs from step (1.) + val classLoader = new URLClassLoader(resourceURLs.toArray, ucl) + + // 3. load the classes into the FnOEnvironment + classNames.foreach{ + cn => { + // add class object to FnOEnvironment if not existent + if(!FnOEnvironment.loadedClassesMap.contains(cn)) { + //val cls = classLoader.loadClass(cn) + Try(classLoader.loadClass(cn)) match { + case Success(cls) =>FnOEnvironment.loadedClassesMap.put(cn, cls) + case Failure(exception) => logError(s"Unable to load ${cn} into FnO Environment. Details: ${exception.getMessage}") + } + } + } + } + super.open(parameters) + } +} + +/** + * [[FnOEnvironmentStreamLoader]] can be used in a DataStream[Item]. + * Looks for the given list of [[jarNames]] using the runtime context's classloader which is used + * to load the given [[classNames]] into the [[FnOEnvironment]]. + * + * @param jarNames + * @param classNames + */ +class FnOEnvironmentStreamLoader(jarNames : List[String], classNames : List[String]) + extends AbstractFnOEnvironmentLoader[Iterable[Item]](jarNames = jarNames,classNames = classNames) +/** + * [[FnOEnvironmentLoader]] can be used in a DataSet[Item]. + * Looks for the given list of [[jarNames]] using the runtime context's classloader which is used + * to load the given [[classNames]] into the [[FnOEnvironment]]. + * + * @param jarNames + * @param classNames + */ +class FnOEnvironmentLoader(jarNames : List[String], classNames : List[String]) + extends AbstractFnOEnvironmentLoader[Item](jarNames = jarNames,classNames = classNames) diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala index 7b5230f2..7b8aedfb 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicFunction.scala @@ -3,6 +3,7 @@ package io.rml.framework.core.function.model import java.io.{File, IOException, ObjectInputStream, ObjectOutputStream} import java.lang.reflect.Method +import io.rml.framework.api.{FnOEnvironment, RMLEnvironment} import io.rml.framework.core.function.{FunctionUtils, ReflectionUtils} import io.rml.framework.core.model.{Entity, Literal, Uri} import io.rml.framework.flink.sink.FlinkRDFQuad @@ -10,6 +11,7 @@ import io.rml.framework.flink.sink.FlinkRDFQuad /** * A dynamic function is loaded from an external jar at-runtime. + * * @param identifier [[String]] used to identify this DynamicFunction * @param metaData contains information required for loading, initializing the function */ @@ -23,11 +25,35 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten out.defaultWriteObject() } + /** + * There are two ways in which the method can be loaded: + * 1. From the FnOEnvironment. This means that the class was by Flink's UserCodeClassLoader was able to retrieve + * the class from an external jar (located in FLINK_HOME/lib) + * 2. From a jar that is bundled with the RMLStreamer. + * @return + */ + private def loadMethod() : Option[Method] = { + val optClass = FnOEnvironment.loadedClassesMap.get(metaData.className) + if (optClass.isDefined) { + logDebug(s"The class ${metaData.className} was found in the external jars. Will try to load the function ${metaData.methodName}") + optMethod = ReflectionUtils.searchByMethodNameAndParameterTypes(optClass.get, metaData.methodName, metaData.inputParam.map(_.paramType): _*) + } else { + logInfo(s"Could not find ${metaData.className} for this function in the FnOEnvironment" + + s" (i.e. the class could not be found in an external jar)." + + s"If the specified source (${metaData.source}) is included in the RML Streamer's resources, " + + s"and the class (${metaData.className}) can be found, " + + s"then ${metaData.methodName} will be loaded from there.") + val jarFile = getClass.getClassLoader.getResource(metaData.source).getFile + val classOfMethod = FunctionUtils.loadClassFromJar(new File(jarFile), metaData.className) + optMethod = ReflectionUtils.searchByMethodNameAndParameterTypes(classOfMethod, metaData.methodName, metaData.inputParam.map(_.paramType): _*) + } + optMethod + } override def execute(paramTriples: List[FlinkRDFQuad]): Option[Iterable[Entity]] = { // if a group (key: uri) results in a list with 1 element, extract that single element // otherwise, when a group has a list with more than 1 element, keep it as a list - val argResourcesGroupedByUri = paramTriples.groupBy(_.predicate).map{ + val argResourcesGroupedByUri = paramTriples.groupBy(_.predicate).map { pair => { pair._2.length match { case 0 => pair._1.uri -> None @@ -37,11 +63,11 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten } } - val argObjectsGroupedByUri = argResourcesGroupedByUri.map{ + val argObjectsGroupedByUri = argResourcesGroupedByUri.map { pair => { - if(pair._2.isInstanceOf[Iterable[FlinkRDFQuad]]){ - pair._1 -> pair._2.asInstanceOf[Iterable[FlinkRDFQuad]].map(x=>x.`object`.value.toString) - }else{ + if (pair._2.isInstanceOf[Iterable[FlinkRDFQuad]]) { + pair._1 -> pair._2.asInstanceOf[Iterable[FlinkRDFQuad]].map(x => x.`object`.value.toString) + } else { pair._1 -> pair._2.asInstanceOf[FlinkRDFQuad].`object`.value.toString } @@ -52,23 +78,24 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten .inputParam .sortBy(_.position).flatMap(ip => { - if(argObjectsGroupedByUri.contains(ip.paramUri)) + if (argObjectsGroupedByUri.contains(ip.paramUri)) argObjectsGroupedByUri.get(ip.paramUri) else Some(null) }) - if(orderedArgValues.size == metaData.inputParam.size){ - val method = optMethod.getOrElse(throw new Exception("No method was initialized.")) + if (orderedArgValues.size == metaData.inputParam.size) { + + val method = loadMethod.getOrElse(throw new Exception("No method was initialized.")) val castParameterValues: Array[AnyRef] = ReflectionUtils.castUsingMethodParameterTypes(method, orderedArgValues) try { - val output = method.invoke(null, castParameterValues:_*) + val output = method.invoke(null, castParameterValues: _*) val result = metaData.outputParam.flatMap(elem => elem.getValue(output)) map (elem => Literal(elem.toString)) Some(result) - }catch { - case e : Exception => { + } catch { + case e: Exception => { logError(s"The following exception occurred when invoking the method ${method.getName}: ${e.getMessage}." + s"\nThe result will be set to None.") None @@ -78,25 +105,17 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten else None - } - override def initialize(): Function = { - if(optMethod.isEmpty) { - val jarFile = getClass.getClassLoader.getResource(metaData.source).getFile - val classOfMethod = FunctionUtils.loadClassFromJar(new File(jarFile), metaData.className) - optMethod = ReflectionUtils.searchByMethodNameAndParameterTypes(classOfMethod, metaData.methodName, metaData.inputParam.map(_.paramType): _*) - } - this - } + @throws(classOf[IOException]) @throws(classOf[ClassNotFoundException]) private def readObject(in: ObjectInputStream): Unit = { in.defaultReadObject() optMethod = None - initialize() + } override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { @@ -108,13 +127,13 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten if (paramsOrdered.size == inputParams.size) { val method = optMethod.get - val castedParameterValues = ReflectionUtils.castUsingMethodParameterTypes(method,paramsOrdered) + val castedParameterValues = ReflectionUtils.castUsingMethodParameterTypes(method, paramsOrdered) val output = method.invoke(null, castedParameterValues: _*) - if(output!=null) { + if (output != null) { val result = outputParams.flatMap(elem => elem.getValue(output)) map (elem => Literal(elem.toString)) Some(result) - }else + } else None } else { //TODO: complain about inputparams size != params ordered @@ -124,8 +143,6 @@ case class DynamicFunction(identifier: String, metaData: FunctionMetaData) exten } - - override def getMethod: Option[Method] = { optMethod } diff --git a/src/main/scala/io/rml/framework/core/function/model/Function.scala b/src/main/scala/io/rml/framework/core/function/model/Function.scala index 21f8900c..bbfb5461 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Function.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Function.scala @@ -18,10 +18,6 @@ abstract class Function extends Node with Logging{ @deprecated("Please use execute(paramTriples: List[FlinkRDFQuad]) instead") def execute(argumentsMap: Map[Uri, String]): Option[Iterable[Entity]] - def initialize(): Function = { - logDebug("initializing Function") - this - } } diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index 2c646751..cd19579f 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -74,7 +74,7 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { .value .toString) - val loadedFunctionOption = FunctionLoader().loadFunction(functionName) + val loadedFunctionOption = FunctionLoader().createFunction(functionName) loadedFunctionOption.getOrElse{ // complain about function that isn't present throw new RMLException("Can't load function..") @@ -94,8 +94,7 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { val paramTriples = triples.filter(triple => triple.predicate.uri != Uri(RMLVoc.Property.EXECUTES)) - function.initialize() - logDebug(s"executing ${function.toString}") + function.execute(paramTriples) } } diff --git a/src/test/scala/io/rml/framework/FunctionMappingTest.scala b/src/test/scala/io/rml/framework/FunctionMappingTest.scala index 4a0e1805..722002e9 100644 --- a/src/test/scala/io/rml/framework/FunctionMappingTest.scala +++ b/src/test/scala/io/rml/framework/FunctionMappingTest.scala @@ -1,53 +1,24 @@ package io.rml.framework -import java.io.File - -import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.FunctionLoader -import org.scalatest.{BeforeAndAfter, FunSuite} - -import scala.reflect.io.Path - +import io.rml.framework.api.FnOEnvironment +import org.scalatest.{BeforeAndAfter, BeforeAndAfterAll, FunSuite} +import io.rml.framework.core.internal.Logging object FunctionMappingSetup { def setupFunctionLoader() = { - // function descriptions - val functionDescriptionFilePaths = List( - "functions_grel.ttl", - "functions_idlab.ttl" - ).map(fp=> - { - val f = new File(getClass.getClassLoader.getResource(fp).getFile) - Path.apply(f) - } - ) - - // add them to the RMLEnvironment - functionDescriptionFilePaths.foreach(p=>RMLEnvironment.addFunctionDescriptionFilePath(p)) - - - // function mappings - val functionMappingPaths = List( - "grel_java_mapping.ttl", - "idlab_java_mapping.ttl" - ).map(fp=> - { - val f = new File(getClass.getClassLoader.getResource(fp).getFile) - Path.apply(f) - } - ) - - // add them to the RMLEnvironment - functionMappingPaths.foreach(p=>RMLEnvironment.addFunctionMappingFilePaths(p)) - - // singleton FunctionLoader created and initialized with function descriptions and mappings from the RMLENvironment - val functionLoader = FunctionLoader() + // singleton FunctionLoader created and initialized with default function descriptions and function mappings + FnOEnvironment.loadDefaultConfiguration() + FnOEnvironment.intializeFunctionLoader() } } -trait FunctionMappingTest extends FunSuite with BeforeAndAfter { - - before { +/** + * Test helper trait that automatically initializes the function loader with the default configuration. + */ +trait FunctionMappingTest extends FunSuite with BeforeAndAfterAll with Logging{ + + override protected def beforeAll(): Unit = { + logInfo("Before All") FunctionMappingSetup.setupFunctionLoader() } } \ No newline at end of file From e17ec6a37d019d4663dc9dfdbbe6d1a8a6740a9c Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 3 Sep 2020 13:34:40 +0200 Subject: [PATCH 106/169] Updated Flink version --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5a79c034..30036349 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you want to deploy it yourself, read on. RMLStreamer runs its jobs on Flink clusters. More information on how to install Flink and getting started can be found [here](https://ci.apache.org/projects/flink/flink-docs-release-1.10/getting-started/tutorials/local_setup.html). At least a local cluster must be running in order to start executing RML Mappings with RMLStreamer. -Please note that this version works with Flink 1.10.0 with Scala 2.11 support, which can be downloaded [here](https://www.apache.org/dyn/closer.lua/flink/flink-1.10.0/). +Please note that this version works with Flink 1.10.1 with Scala 2.11 support, which can be downloaded [here](https://archive.apache.org/dist/flink/flink-1.10.1/flink-1.10.1-bin-scala_2.11.tgz). ### Building RMLStreamer @@ -46,7 +46,7 @@ The resulting `RMLStreamer-.jar`, found in the `target` folder, can be ### Executing RML Mappings Here we give examples for running RMLStreamer from the command line. We use `FLINK_BIN` to denote the Flink CLI tool, -usually found in the `bin` directory of the Flink installation. E.g. `/home/myuser/flink-1.10.0/bin/flink`. +usually found in the `bin` directory of the Flink installation. E.g. `/home/myuser/flink-1.10.1/bin/flink`. For Windows a `flink.bat` script is provided. The general usage is: From a05b7f387e698ec6f18446b5e1cf002ed1bdbac3 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 3 Sep 2020 13:37:20 +0200 Subject: [PATCH 107/169] Use actual values in example to avoid confusion --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30036349..878f886e 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ An example of how to define the generation of an RDF stream from a stream in an rml:logicalSource [ rml:source [ rdf:type rmls:KafkaStream ; - rmls:broker "broker" ; + rmls:broker "localhost:9092" ; rmls:groupId "groupId"; rmls:topic "topic"; ]; From b6c7d74a23db95784099301bc22ceaf2c1723c65 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Mon, 5 Oct 2020 10:48:18 +0200 Subject: [PATCH 108/169] Updating docs + dev set-up docs --- README.md | 2 +- documentation/README_DEVELOPMENT.md | 17 +++++++++++++++++ documentation/images/maven_intellij.png | Bin 0 -> 40375 bytes 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 documentation/README_DEVELOPMENT.md create mode 100644 documentation/images/maven_intellij.png diff --git a/README.md b/README.md index 878f886e..7d292a12 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Please note that this version works with Flink 1.10.1 with Scala 2.11 support, w ### Building RMLStreamer In order to build a jar file that can be deployed on a Flink cluster, you need: -- a Java JDK 8 or higher +- a Java JDK 11 or higher - Apache Maven 3 or higher Clone or download and then build the code in this repository: diff --git a/documentation/README_DEVELOPMENT.md b/documentation/README_DEVELOPMENT.md new file mode 100644 index 00000000..c8d1a996 --- /dev/null +++ b/documentation/README_DEVELOPMENT.md @@ -0,0 +1,17 @@ +# Setting up RMLStreamer for development + +## Prerequisites +* Git +* Java JDK >= 11 +* Maven 3 +* IntelliJ (Eclipse should work too, but consult Flink documentation for set-up) + +## Setting up the environment (IntelliJ) +* Make sure you have the scala plugin installed and enabled in IntelliJ. +* Clone the repository. +* Open IntelliJ. +* Open `pom.xml` as a project. +* IntelliJ probably asks to automatically download the dependencies; this is generally a good idea. +* There should be a `Maven` tool window tab somewhere; open it. If not, you can open it via the menu: `View` > `Tool Windows` > `Maven`. +* Enable the profile `add-dependencies-for-IDEA`. +![Maven profile selection](images/maven_intellij.png) diff --git a/documentation/images/maven_intellij.png b/documentation/images/maven_intellij.png new file mode 100644 index 0000000000000000000000000000000000000000..7a190134c9fbb57594cd4c3099e8c5a7707e0858 GIT binary patch literal 40375 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�nMYCwm%Hl+Hmn5qA0 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

QC=g$-I=ITkiHvhUx2y}drsy;c4C1vN4{T3Q~- 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 L@w!shEa=|=o}{2y literal 0 HcmV?d00001 From c642d1f9d281ea7aff3e9564ee5cdfb9df41ed8b Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Mon, 5 Oct 2020 10:49:28 +0200 Subject: [PATCH 109/169] Updating docs + dev set-up docs --- documentation/README_DEVELOPMENT.md | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/README_DEVELOPMENT.md b/documentation/README_DEVELOPMENT.md index c8d1a996..c4a27cc8 100644 --- a/documentation/README_DEVELOPMENT.md +++ b/documentation/README_DEVELOPMENT.md @@ -14,4 +14,5 @@ * IntelliJ probably asks to automatically download the dependencies; this is generally a good idea. * There should be a `Maven` tool window tab somewhere; open it. If not, you can open it via the menu: `View` > `Tool Windows` > `Maven`. * Enable the profile `add-dependencies-for-IDEA`. + ![Maven profile selection](images/maven_intellij.png) From c3c1b7946c9fa1ea7db31d097e4e5a736c0be6b4 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 10 Jul 2020 10:35:41 +0200 Subject: [PATCH 110/169] wip: supporting relative paths Normally, the logical source of a mapping file was resolved relative to the working directory. Now, the logical source can also be resolved relative to the path of the mapping file. --- .../framework/core/model/FileDataSource.scala | 28 ++++++++---- .../io/rml/framework/core/util/Util.scala | 13 ++++++ .../scenario01/RMLTC0001a-CSV/mapping.ttl | 29 ++++++++++++ .../scenario01/RMLTC0001a-CSV/output.ttl | 2 + .../relative_paths/scenario01/student.csv | 2 + .../scenario02/RMLTC0001a-CSV/mapping.ttl | 29 ++++++++++++ .../scenario02/RMLTC0001a-CSV/output.ttl | 2 + .../scenario02/data/student.csv | 2 + .../RMLTC0001a-CSV/data/student.csv | 2 + .../scenario03/RMLTC0001a-CSV/mapping.ttl | 29 ++++++++++++ .../scenario03/RMLTC0001a-CSV/output.ttl | 2 + .../framework/std/StdMappingReaderTest.scala | 44 +++++++++++++++++++ 12 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 src/test/resources/relative_paths/scenario01/RMLTC0001a-CSV/mapping.ttl create mode 100644 src/test/resources/relative_paths/scenario01/RMLTC0001a-CSV/output.ttl create mode 100644 src/test/resources/relative_paths/scenario01/student.csv create mode 100644 src/test/resources/relative_paths/scenario02/RMLTC0001a-CSV/mapping.ttl create mode 100644 src/test/resources/relative_paths/scenario02/RMLTC0001a-CSV/output.ttl create mode 100644 src/test/resources/relative_paths/scenario02/data/student.csv create mode 100644 src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/data/student.csv create mode 100644 src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/mapping.ttl create mode 100644 src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/output.ttl diff --git a/src/main/scala/io/rml/framework/core/model/FileDataSource.scala b/src/main/scala/io/rml/framework/core/model/FileDataSource.scala index 16ff960e..6d496ff8 100644 --- a/src/main/scala/io/rml/framework/core/model/FileDataSource.scala +++ b/src/main/scala/io/rml/framework/core/model/FileDataSource.scala @@ -27,10 +27,14 @@ package io.rml.framework.core.model import java.io.File +import io.rml.framework.api.RMLEnvironment import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.std.StdFileDataSource +import io.rml.framework.core.util.Util import io.rml.framework.shared.RMLException +import scala.util.{Failure, Success, Try} + /** * */ @@ -49,15 +53,23 @@ object FileDataSource extends Logging { */ def apply(uri: ExplicitNode): DataSource = { val file = new File(uri.toString) - if (file.isAbsolute) { - logDebug(Uri(file.getAbsolutePath).uri) - StdFileDataSource(Uri(file.getAbsolutePath)) - } else { - val url = ClassLoader.getSystemResource(uri.toString) - if (url == null) throw new RMLException(uri.toString + " can't be found.") - val file_2 = new File(url.toURI) - StdFileDataSource(Uri(file_2.getAbsolutePath)) + Try(Util.resolveFileRelativeToSourceFileParent(RMLEnvironment.getMappingFileBaseIRI().get, file.getPath)) match { + case Success(resolvedFile) => { + StdFileDataSource(Uri(resolvedFile.getAbsolutePath)) + } + case Failure(exception) => { + if (file.isAbsolute) { + logDebug(Uri(file.getAbsolutePath).uri) + StdFileDataSource(Uri(file.getAbsolutePath)) + } else { + val url = ClassLoader.getSystemResource(uri.toString) + if (url == null) throw new RMLException(uri.toString + " can't be found.") + val file_2 = new File(url.toURI) + StdFileDataSource(Uri(file_2.getAbsolutePath)) + } + } } + } } diff --git a/src/main/scala/io/rml/framework/core/util/Util.scala b/src/main/scala/io/rml/framework/core/util/Util.scala index 08b1d379..5d0b6bb5 100644 --- a/src/main/scala/io/rml/framework/core/util/Util.scala +++ b/src/main/scala/io/rml/framework/core/util/Util.scala @@ -211,4 +211,17 @@ object Util { result } + + def resolveFileRelativeToSourceFileParent(sourcePathString: String, other : String) = { + val sourcePath = Paths.get(sourcePathString) + + sourcePath + .getParent + .resolve(other) + .toFile + .getCanonicalFile + } + + + } diff --git a/src/test/resources/relative_paths/scenario01/RMLTC0001a-CSV/mapping.ttl b/src/test/resources/relative_paths/scenario01/RMLTC0001a-CSV/mapping.ttl new file mode 100644 index 00000000..7535dc02 --- /dev/null +++ b/src/test/resources/relative_paths/scenario01/RMLTC0001a-CSV/mapping.ttl @@ -0,0 +1,29 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "../student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + rml:reference "Name" + ] + ]. + + diff --git a/src/test/resources/relative_paths/scenario01/RMLTC0001a-CSV/output.ttl b/src/test/resources/relative_paths/scenario01/RMLTC0001a-CSV/output.ttl new file mode 100644 index 00000000..73f40ddf --- /dev/null +++ b/src/test/resources/relative_paths/scenario01/RMLTC0001a-CSV/output.ttl @@ -0,0 +1,2 @@ + "Venus" . + diff --git a/src/test/resources/relative_paths/scenario01/student.csv b/src/test/resources/relative_paths/scenario01/student.csv new file mode 100644 index 00000000..4e683bbe --- /dev/null +++ b/src/test/resources/relative_paths/scenario01/student.csv @@ -0,0 +1,2 @@ +Name +Venus diff --git a/src/test/resources/relative_paths/scenario02/RMLTC0001a-CSV/mapping.ttl b/src/test/resources/relative_paths/scenario02/RMLTC0001a-CSV/mapping.ttl new file mode 100644 index 00000000..af23d810 --- /dev/null +++ b/src/test/resources/relative_paths/scenario02/RMLTC0001a-CSV/mapping.ttl @@ -0,0 +1,29 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "../data/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + rml:reference "Name" + ] + ]. + + diff --git a/src/test/resources/relative_paths/scenario02/RMLTC0001a-CSV/output.ttl b/src/test/resources/relative_paths/scenario02/RMLTC0001a-CSV/output.ttl new file mode 100644 index 00000000..73f40ddf --- /dev/null +++ b/src/test/resources/relative_paths/scenario02/RMLTC0001a-CSV/output.ttl @@ -0,0 +1,2 @@ + "Venus" . + diff --git a/src/test/resources/relative_paths/scenario02/data/student.csv b/src/test/resources/relative_paths/scenario02/data/student.csv new file mode 100644 index 00000000..4e683bbe --- /dev/null +++ b/src/test/resources/relative_paths/scenario02/data/student.csv @@ -0,0 +1,2 @@ +Name +Venus diff --git a/src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/data/student.csv b/src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/data/student.csv new file mode 100644 index 00000000..4e683bbe --- /dev/null +++ b/src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/data/student.csv @@ -0,0 +1,2 @@ +Name +Venus diff --git a/src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/mapping.ttl b/src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/mapping.ttl new file mode 100644 index 00000000..03235d1a --- /dev/null +++ b/src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/mapping.ttl @@ -0,0 +1,29 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "data/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + rml:reference "Name" + ] + ]. + + diff --git a/src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/output.ttl b/src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/output.ttl new file mode 100644 index 00000000..73f40ddf --- /dev/null +++ b/src/test/resources/relative_paths/scenario03/RMLTC0001a-CSV/output.ttl @@ -0,0 +1,2 @@ + "Venus" . + diff --git a/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala b/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala index 009267dc..731c842a 100644 --- a/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala +++ b/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala @@ -25,7 +25,9 @@ package io.rml.framework.std +import io.rml.framework.api.RMLEnvironment import io.rml.framework.core.internal.Logging +import io.rml.framework.core.util.Util import org.scalatest.{BeforeAndAfter, FunSuite, Matchers} import org.scalatestplus.mockito.MockitoSugar @@ -34,6 +36,48 @@ class StdMappingReaderTest extends FunSuite with Matchers with BeforeAndAfter with Logging { + + /** + * ├── scenario01 + * │   ├── RMLTC0001a-CSV + * │   │   ├── mapping.ttl // rml:source "../student.csv"; + * │   │   └── output.ttl + * │   └── student.csv + */ + test("relative paths: scenario01"){ + val mappingFile = "relative_paths/scenario01/RMLTC0001a-CSV/mapping.ttl" + // determine the base IRI of the mapping file + RMLEnvironment.setMappingFileBaseIRI(Some((mappingFile))) + val formattedMapping = Util.readMappingFile(mappingFile) + } + + /** + * ├── scenario02 + * │   ├── RMLTC0001a-CSV + * │   │   ├── mapping.ttl // rml:source "../data/student.csv"; + * │   │   └── output.ttl + * │   └── data + * │   └── student.csv + */ + test("relative paths: scenario02"){ + val mappingFile = "relative_paths/scenario02/RMLTC0001a-CSV/mapping.ttl" + val formattedMapping = Util.readMappingFile(mappingFile) + } + + /** + * └── scenario03 + * └── RMLTC0001a-CSV + * ├── data + * │   └── student.csv + * ├── mapping.ttl // rml:source "data/student.csv"; + * └── output.ttl + */ + test("relative paths: scenario03"){ + val mappingFile = "relative_paths/scenario03/RMLTC0001a-CSV/mapping.ttl" + val formattedMapping = Util.readMappingFile(mappingFile) + } + + /** test("testReadFromFile") { From af6a4e0496b24b5a4929d16883ce3ea7f30b9993 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 10 Jul 2020 10:41:28 +0200 Subject: [PATCH 111/169] forgot to set filebase iri for tests in mappingreadertest --- .../scala/io/rml/framework/std/StdMappingReaderTest.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala b/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala index 731c842a..ce618675 100644 --- a/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala +++ b/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala @@ -61,6 +61,8 @@ class StdMappingReaderTest extends FunSuite with Matchers */ test("relative paths: scenario02"){ val mappingFile = "relative_paths/scenario02/RMLTC0001a-CSV/mapping.ttl" + // determine the base IRI of the mapping file + RMLEnvironment.setMappingFileBaseIRI(Some((mappingFile))) val formattedMapping = Util.readMappingFile(mappingFile) } @@ -74,6 +76,8 @@ class StdMappingReaderTest extends FunSuite with Matchers */ test("relative paths: scenario03"){ val mappingFile = "relative_paths/scenario03/RMLTC0001a-CSV/mapping.ttl" + // determine the base IRI of the mapping file + RMLEnvironment.setMappingFileBaseIRI(Some((mappingFile))) val formattedMapping = Util.readMappingFile(mappingFile) } From 0eab215e09005cf0efd196b3adb8583d34eab2b1 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 10 Jul 2020 11:01:55 +0200 Subject: [PATCH 112/169] =?UTF-8?q?log=20level:=20changed=20from=20DEBUG?= =?UTF-8?q?=20=20=E2=86=92=20INFO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/log4j.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties index 13f68f16..c716fb6e 100644 --- a/src/test/resources/log4j.properties +++ b/src/test/resources/log4j.properties @@ -1,4 +1,4 @@ -log4j.rootLogger=DEBUG, stdout +log4j.rootLogger=INFO, stdout log4j.logger.org.apache.flink=WARN log4j.logger.kafka=ERROR log4j.logger.org.I0Itec.zkclient=ERROR From 4e4a8be7750759922420db950d2315c125b01e26 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 10 Jul 2020 11:42:16 +0200 Subject: [PATCH 113/169] fix: resetting mapping file base iri after each test --- .../scala/io/rml/framework/std/StdMappingReaderTest.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala b/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala index ce618675..241182ab 100644 --- a/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala +++ b/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala @@ -37,6 +37,10 @@ class StdMappingReaderTest extends FunSuite with Matchers with Logging { + after { + // clean up + RMLEnvironment.setMappingFileBaseIRI(None) + } /** * ├── scenario01 * │   ├── RMLTC0001a-CSV From 6d8c4cbf6b7c92c99f870e27405e3622e6426ee7 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 10 Jul 2020 13:58:07 +0200 Subject: [PATCH 114/169] enhancement: relative path to mappingfile #95 Added different approaches for retrieving a file - using the classloader - relative to the user dir --- .../io/rml/framework/core/util/Util.scala | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/util/Util.scala b/src/main/scala/io/rml/framework/core/util/Util.scala index 5d0b6bb5..6dd8c09f 100644 --- a/src/main/scala/io/rml/framework/core/util/Util.scala +++ b/src/main/scala/io/rml/framework/core/util/Util.scala @@ -24,7 +24,7 @@ **/ package io.rml.framework.core.util -import java.io.{ByteArrayInputStream, File, FileInputStream, InputStream} +import java.io.{ByteArrayInputStream, File, FileInputStream, FileNotFoundException, InputStream} import java.net.URI import java.nio.charset.StandardCharsets import java.nio.file.{Files, Paths} @@ -33,12 +33,14 @@ import java.util.regex.Pattern import io.rml.framework.core.extractors.MappingReader import io.rml.framework.core.model.{FormattedRMLMapping, Literal, Node, RMLMapping} import io.rml.framework.shared.ReadException +import io.rml.framework.core.internal.Logging import scala.collection.mutable.ListBuffer import scala.io.Source +import scala.util.{Failure, Success, Try} -object Util { +object Util extends Logging{ // Without support for custom registered languages of length 5-8 of the IANA language-subtag-registry private val regexPatternLanguageTag = Pattern.compile("^((?:(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?:([A-Za-z]{2,3}(-(?:[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4})(-(?:[A-Za-z]{4}))?(-(?:[A-Za-z]{2}|[0-9]{3}))?(-(?:[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?:[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?:x(-[A-Za-z0-9]{1,8})+))?)|(?:x(-[A-Za-z0-9]{1,8})+))$") @@ -190,13 +192,25 @@ object Util { */ def readMappingFile(path: String): FormattedRMLMapping = { val mappingFile = getFile(path) + val mapping = MappingReader().read(mappingFile).asInstanceOf[RMLMapping] FormattedRMLMapping.fromRMLMapping(mapping) } + private def getFileUsingClassLoader(path : String) = { + val classLoader = getClass.getClassLoader + new File(classLoader.getResource(path).getFile) + } + private def getFileRelativeToUserDir(path : String) = { + val userDir = System.getProperty("user.dir") + resolveFileRelativeToSourceFileParent(userDir,path) + } /** * If the given path is absolute, then a File object representing that path is returned. - * If the given path is relative, then a File object representing the path relative to the root class directory is returned. This can also be a path in a jar. + * If the given path is relative, then the following steps are taken to find the file + * - 1. using the classloader (a File object representing the path relative to the root class directory is returned. + * This can also be a path in a jar.) + * - 2. try to find the file relative to the user directory * @param path * @return */ @@ -205,8 +219,25 @@ object Util { val result = if (file_1.isAbsolute) { new File(path) } else { - val classLoader = getClass.getClassLoader - new File(classLoader.getResource(path).getFile) + // Try to find the file use the class loader + val out = Try(getFileUsingClassLoader(path)) match { + case Success(file) => Some(file) + case Failure(exception) => { + logError("can't find file use class loader") + // Try to find the file relative to the user directory + Try(getFileRelativeToUserDir(path)) match { + case Success(file) => Some(file) + case Failure(exception) => { + logError(s"can't find file relative to user dir") + None + } + } + } + } + out.getOrElse( + throw new FileNotFoundException(s"Unable to find ${path}") + ) + } result } From cbcc54b6284caeb3a1d7551e09253ae02350f5ae Mon Sep 17 00:00:00 2001 From: Jasper Van den Bossche Date: Mon, 26 Oct 2020 10:55:59 +0100 Subject: [PATCH 115/169] update netty connector to snapshot in pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 42f9e473..f212af3b 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ SOFTWARE. org.apache.bahir flink-connector-netty_${scala.binary.version} - 1.0 + 1.1-SNAPSHOT org.apache.flink From 9cd5b616398562b413a4fb6b8c3e992db4369982 Mon Sep 17 00:00:00 2001 From: Jasper Van den Bossche Date: Mon, 26 Oct 2020 11:46:58 +0100 Subject: [PATCH 116/169] add documentation about pom.xml update --- documentation/README_Netty_Snapshot.md | 19 +++++++++++++++++++ documentation/img/dependencies.png | Bin 0 -> 47722 bytes documentation/img/reload_dependencies.png | Bin 0 -> 88799 bytes 3 files changed, 19 insertions(+) create mode 100644 documentation/README_Netty_Snapshot.md create mode 100644 documentation/img/dependencies.png create mode 100644 documentation/img/reload_dependencies.png diff --git a/documentation/README_Netty_Snapshot.md b/documentation/README_Netty_Snapshot.md new file mode 100644 index 00000000..f3fa9387 --- /dev/null +++ b/documentation/README_Netty_Snapshot.md @@ -0,0 +1,19 @@ +# README: Flink Netty Connector Snapshot + +The `pom.xml` has been updated and swapped the old netty connector for the current snapshot. When using Intellij, it will ask to reload the dependencies. Click on it, after building you will see `flink-connector-netty_2.11:1.1-SNAPSHOT` will be added to the list of maven dependencies. + +![](img/reload_dependencies.png) + +When updating the `pom.xml` file, the icon in the top right corner will ask to reload the decencies, which in this case will update to the snapshot. + +![](img/dependencies.png) + +Once you build with the newly updated `pom.xml`, the snapshot version will appear in the dependency list instead of the old version. + +### Testing the build on a Flink 1.11 cluster + +Download [Apache Flink 1.11.2 for Scala 2.11](https://www.apache.org/dyn/closer.lua/flink/flink-1.11.2/flink-1.11.2-bin-scala_2.11.tgz) from the [Apache Flink downloads page](https://flink.apache.org/downloads.html) and untar the file. + +Make sure all function files are in place (see: [documentation](https://gitlab.ilabt.imec.be/rml/proc/rml-streamer/-/blob/development/documentation/README_Functions.md)) and execute the `flink-1.11.2/bin/start-cluster.sh` and submit your job. Once you are done running all your jobs, stop the cluster by running the `flink-1.11.2/bin/stop-cluster.sh` script. + +Normally no errors should occur. \ No newline at end of file diff --git a/documentation/img/dependencies.png b/documentation/img/dependencies.png new file mode 100644 index 0000000000000000000000000000000000000000..7c87dae48c45e1b24bc847d79665ab0d62cd7ebe GIT binary patch literal 47722 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%0D*RHaZvVx`3{O)I%9F{B; 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%0Du2Zw!L?? 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 literal 0 HcmV?d00001 diff --git a/documentation/img/reload_dependencies.png b/documentation/img/reload_dependencies.png new file mode 100644 index 0000000000000000000000000000000000000000..e64f7e09ab12389b05ab096a211a1b05171fffab GIT binary patch literal 88799 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 z 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 z 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 Date: Wed, 28 Oct 2020 17:18:22 +0100 Subject: [PATCH 117/169] support the most recent version of flink, 1.11.2 --- pom.xml | 2 +- src/main/scala/io/rml/framework/flink/source/CSVStream.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f212af3b..764a0d22 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ SOFTWARE. UTF-8 - 1.10.1 + 1.11.2 1.7.26 2.13.3 3.11.0 diff --git a/src/main/scala/io/rml/framework/flink/source/CSVStream.scala b/src/main/scala/io/rml/framework/flink/source/CSVStream.scala index 0b252b63..c10df2fd 100644 --- a/src/main/scala/io/rml/framework/flink/source/CSVStream.scala +++ b/src/main/scala/io/rml/framework/flink/source/CSVStream.scala @@ -37,7 +37,7 @@ import org.apache.flink.api.common.typeinfo.TypeInformation import org.apache.flink.api.scala._ import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment} import org.apache.flink.table.api.Table -import org.apache.flink.table.api.scala.StreamTableEnvironment +import org.apache.flink.table.api.bridge.scala.StreamTableEnvironment import org.apache.flink.table.descriptors.FileSystem import org.apache.flink.types.Row From 445c4129ec56e4c3e09135cd67bedcd96bace528 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Fri, 30 Oct 2020 12:54:42 +0100 Subject: [PATCH 118/169] At this moment RMLStreamer does not work on Java 14+ --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7d292a12..fe856692 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ Please note that this version works with Flink 1.10.1 with Scala 2.11 support, w ### Building RMLStreamer In order to build a jar file that can be deployed on a Flink cluster, you need: -- a Java JDK 11 or higher -- Apache Maven 3 or higher +- a Java JDK >= 11 and <= 13 +- Apache Maven 3 or higher Clone or download and then build the code in this repository: From 180d7f74556761ec9e8cb3fbee9b66ba002c0641 Mon Sep 17 00:00:00 2001 From: Jasper Van den Bossche Date: Wed, 4 Nov 2020 14:39:17 +0100 Subject: [PATCH 119/169] use jitpack to get most recent netty connector snapshot --- pom.xml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 764a0d22..8737a40a 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,13 @@ SOFTWARE. mit + + + jitpack.io + https://jitpack.io + + + v@ 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

gn+vWF&|O}UdI#9>5PXyP31un+7kt}JfMD)IqD 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�-cN_K5T=gfDWaer{UQ2X>6{ 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 H+eiE_+ukGs literal 0 HcmV?d00001 From 57bf301eae662dc52d79b6e6dfc42b68253c326c Mon Sep 17 00:00:00 2001 From: Jasper Van den Bossche Date: Wed, 4 Nov 2020 17:29:23 +0100 Subject: [PATCH 122/169] fix img paths in documentation --- documentation/README_Netty_Snapshot.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/README_Netty_Snapshot.md b/documentation/README_Netty_Snapshot.md index c5c9da79..68f0efdc 100644 --- a/documentation/README_Netty_Snapshot.md +++ b/documentation/README_Netty_Snapshot.md @@ -24,17 +24,17 @@ Since there is no recent official release of Bahir-Flink-Netty, [JitPack](https: 1. Copy the repo url - ![Step 1: copy the repo link](/Users/macbookpro/Documents/imec/rml-streamer/documentation/img/copy_repo_link.png) + ![Step 1: copy the repo link](img/copy_repo_link.png) 2. Paste the repo url and look up the repo on JitPack - ![Step 2: look up repo on JitPack](/Users/macbookpro/Documents/imec/rml-streamer/documentation/img/paste_repo_link.png) + ![Step 2: look up repo on JitPack](img/paste_repo_link.png) 3. Get the build, commit, ... you need - ![Step 3: get desired version](/Users/macbookpro/Documents/imec/rml-streamer/documentation/img/get_build.png) + ![Step 3: get desired version](img/get_build.png) 4. Copy the `pom.xml` patches - ![Step 4: copy patches](/Users/macbookpro/Documents/imec/rml-streamer/documentation/img/copy_patch.png) + ![Step 4: copy patches](img/copy_patch.png) From bef8c895f6983a0de0a14c01abd8cdbe91bffa08 Mon Sep 17 00:00:00 2001 From: Jasper Van den Bossche Date: Thu, 5 Nov 2020 10:15:58 +0100 Subject: [PATCH 123/169] upgrade kafka + flink --- pom.xml | 4 ++-- src/main/scala/io/rml/framework/flink/source/CSVStream.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 3b8ef1a3..0949a9c8 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ SOFTWARE. UTF-8 - 1.10.1 + 1.11.2 1.7.26 2.13.3 3.11.0 @@ -252,7 +252,7 @@ SOFTWARE. org.apache.kafka kafka_${scala.binary.version} - 2.2.2 + 2.4.1 test diff --git a/src/main/scala/io/rml/framework/flink/source/CSVStream.scala b/src/main/scala/io/rml/framework/flink/source/CSVStream.scala index 0b252b63..c10df2fd 100644 --- a/src/main/scala/io/rml/framework/flink/source/CSVStream.scala +++ b/src/main/scala/io/rml/framework/flink/source/CSVStream.scala @@ -37,7 +37,7 @@ import org.apache.flink.api.common.typeinfo.TypeInformation import org.apache.flink.api.scala._ import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment} import org.apache.flink.table.api.Table -import org.apache.flink.table.api.scala.StreamTableEnvironment +import org.apache.flink.table.api.bridge.scala.StreamTableEnvironment import org.apache.flink.table.descriptors.FileSystem import org.apache.flink.types.Row From e9735b083951f1bd49ab80cefaf4578627043446 Mon Sep 17 00:00:00 2001 From: Jasper Van den Bossche Date: Thu, 5 Nov 2020 17:20:38 +0100 Subject: [PATCH 124/169] update documentation subprojects --- documentation/img/select_subproject.png | Bin 0 -> 210601 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 documentation/img/select_subproject.png diff --git a/documentation/img/select_subproject.png b/documentation/img/select_subproject.png new file mode 100644 index 0000000000000000000000000000000000000000..8a7083c180e8d65fc0ad47b2f420a6a142729cce GIT binary patch literal 210601 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

X7;3;E5 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 f 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

*IF&$R#P{cbT;rL7!jheT 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 j! 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

CQy7&Nt%3;&q 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 Date: Mon, 9 Nov 2020 09:46:30 +0100 Subject: [PATCH 125/169] update documentation subprojects --- documentation/README_Netty_Snapshot.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/documentation/README_Netty_Snapshot.md b/documentation/README_Netty_Snapshot.md index 68f0efdc..3257abf9 100644 --- a/documentation/README_Netty_Snapshot.md +++ b/documentation/README_Netty_Snapshot.md @@ -38,3 +38,7 @@ Since there is no recent official release of Bahir-Flink-Netty, [JitPack](https: ![Step 4: copy patches](img/copy_patch.png) +When using a repo that contains different subprojetts, you can also select one of those subprojetts, instead of the entire project. In this example the `flink-netty-connector` is selected from the `bahir-flink` repo. + +![Select a subproject](img/select_subproject.png) + From 90f8e765aa6a67c0436ecd5b63b465e8be3a3276 Mon Sep 17 00:00:00 2001 From: Jasper Van den Bossche Date: Thu, 12 Nov 2020 17:10:59 +0100 Subject: [PATCH 126/169] update flink documentation --- CHANGELOG.md | 4 +++ README.md | 4 +-- docker/docker-compose.yml | 4 +-- documentation/README_Functions.md | 10 +++---- documentation/README_Netty_Snapshot.md | 34 +++++++--------------- documentation/img/dependencies.png | Bin 47722 -> 0 bytes documentation/img/reload_dependencies.png | Bin 88799 -> 0 bytes 7 files changed, 23 insertions(+), 33 deletions(-) delete mode 100644 documentation/img/dependencies.png delete mode 100644 documentation/img/reload_dependencies.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 69200f8d..7416e732 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Function mapping. * Joins of data streams +* Updated Flink from version 1.10.1 to 1.11.2 +* Updated Kafka from version 2.2.2 to 2.4.2 + + ### Changed * Updated Flink from version 1.10.0 to 1.10.1 diff --git a/README.md b/README.md index fe856692..f92b05b9 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you want to deploy it yourself, read on. RMLStreamer runs its jobs on Flink clusters. More information on how to install Flink and getting started can be found [here](https://ci.apache.org/projects/flink/flink-docs-release-1.10/getting-started/tutorials/local_setup.html). At least a local cluster must be running in order to start executing RML Mappings with RMLStreamer. -Please note that this version works with Flink 1.10.1 with Scala 2.11 support, which can be downloaded [here](https://archive.apache.org/dist/flink/flink-1.10.1/flink-1.10.1-bin-scala_2.11.tgz). +Please note that this version works with Flink 1.11.2 with Scala 2.11 support, which can be downloaded [here](https://www.apache.org/dyn/closer.lua/flink/flink-1.11.2/flink-1.11.2-bin-scala_2.11.tgz). ### Building RMLStreamer @@ -46,7 +46,7 @@ The resulting `RMLStreamer-.jar`, found in the `target` folder, can be ### Executing RML Mappings Here we give examples for running RMLStreamer from the command line. We use `FLINK_BIN` to denote the Flink CLI tool, -usually found in the `bin` directory of the Flink installation. E.g. `/home/myuser/flink-1.10.1/bin/flink`. +usually found in the `bin` directory of the Flink installation. E.g. `/home/myuser/flink-1.11.2/bin/flink`. For Windows a `flink.bat` script is provided. The general usage is: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 667d6190..7eae11e4 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: jobmanager: - image: flink:1.10.1-scala_2.11 + image: flink:1.11.2-scala_2.11 expose: - "6123" ports: @@ -14,7 +14,7 @@ services: - data:/mnt/data taskmanager: - image: flink:1.10.1-scala_2.11 + image: flink:1.11.2-scala_2.11 expose: - "6121" - "6122" diff --git a/documentation/README_Functions.md b/documentation/README_Functions.md index 911eb681..c05d4bad 100644 --- a/documentation/README_Functions.md +++ b/documentation/README_Functions.md @@ -15,13 +15,13 @@ These files can be obtained from `src/main/resources`: ## Example: RML Streamer + Flink Flink's `lib` directory should contain the jar-files with the custom functions. In this example, these are marked with `*` ``` -flink-1.10.1-scala_2.11 +flink-1.11.2-scala_2.11 └── lib ├── GrelFunctions.jar * ├── IDLabFunctions.jar * - ├── flink-dist_2.11-1.10.1.jar - ├── flink-table-blink_2.11-1.10.1.jar - ├── flink-table_2.11-1.10.1.jar + ├── flink-dist_2.11-1.11.2.jar + ├── flink-table-blink_2.11-1.11.2.jar + ├── flink-table_2.11-1.11.2.jar ├── log4j-1.2.17.jar └── slf4j-log4j12-1.7.15.jar ``` @@ -40,7 +40,7 @@ Note that the function descriptions and function mappings are present. The command for running the RML Streamer on Flink should look like ``` -~/flink/flink-1.10.1-scala_2.11/bin/flink run -c io.rml.framework.Main RMLStreamer-2.0.1-SNAPSHOT.jar toFile --output-path $(pwd)'/out.ttl' -m mapping.ttl +~/flink/flink-1.11.2-scala_2.11/bin/flink run -c io.rml.framework.Main RMLStreamer-2.0.1-SNAPSHOT.jar toFile --output-path $(pwd)'/out.ttl' -m mapping.ttl ``` ## Test Cases diff --git a/documentation/README_Netty_Snapshot.md b/documentation/README_Netty_Snapshot.md index 3257abf9..db9fbb97 100644 --- a/documentation/README_Netty_Snapshot.md +++ b/documentation/README_Netty_Snapshot.md @@ -1,44 +1,30 @@ -# README: Flink Netty Connector Snapshot +# README: Using JitPack -The `pom.xml` has been updated and swapped the old netty connector for the current snapshot. When using Intellij, it will ask to reload the dependencies. Click on it, after building you will see `flink-connector-netty_2.11:1.1-SNAPSHOT` will be added to the list of maven dependencies. +### Using JitPack to get unpublished Maven Dependencies from a GitHub/GitLab repository -![](img/reload_dependencies.png) +If you want to use a Maven dependency that is not yet published on Maven Central or you want a specific version, [JitPack](https://jitpack.io/) can be used to get a specific snapshot from the GitHub/GitLab repository. Using JitPack is very simple, you simly go to the GitHub/GitLab repository and copy its link and paste on the JitPack site. Select the version and build system and get the config generated by JitPack. At the moment, this project uses JitPack for Bahir-Flink. -When updating the `pom.xml` file, the icon in the top right corner will ask to reload the decencies, which in this case will update to the snapshot. +### Step by step by step example -![](img/dependencies.png) +In this example the maven dependency [Bahir-Flink](https://github.com/apache/bahir-flink) is built via JitPack. -Once you build with the newly updated `pom.xml`, the snapshot version will appear in the dependency list instead of the old version. - -### Testing the build on a Flink 1.11 cluster - -Download [Apache Flink 1.11.2 for Scala 2.11](https://www.apache.org/dyn/closer.lua/flink/flink-1.11.2/flink-1.11.2-bin-scala_2.11.tgz) from the [Apache Flink downloads page](https://flink.apache.org/downloads.html) and untar the file. - -Make sure all function files are in place (see: [documentation](https://gitlab.ilabt.imec.be/rml/proc/rml-streamer/-/blob/development/documentation/README_Functions.md)) and execute the `flink-1.11.2/bin/start-cluster.sh` and submit your job. Once you are done running all your jobs, stop the cluster by running the `flink-1.11.2/bin/stop-cluster.sh` script. - -Normally no errors should occur. - -### Using JitPack to get the latest Netty Snapshot - -Since there is no recent official release of Bahir-Flink-Netty, [JitPack](https://jitpack.io/) is used to get the latest snapshot. JitPack is a tool that can get you the a snapshot build from a GitHub/GitLab repo and use it with several build toos including Maven. The usage is very simple, go to the repo you want to use and copy the link and paste it in JitPack. Choose a build, release or commit you want to use and click on 'Get it'. After a couple seconds the the build will be ready and you van copy the `pom.xml` patches. - -1. Copy the repo url +1. Copy the url of the repository you want to use. ![Step 1: copy the repo link](img/copy_repo_link.png) -2. Paste the repo url and look up the repo on JitPack +2. Paste the repository url and look up the repo on JitPack. ![Step 2: look up repo on JitPack](img/paste_repo_link.png) -3. Get the build, commit, ... you need +3. Select the build, commit, ... you need. ![Step 3: get desired version](img/get_build.png) -4. Copy the `pom.xml` patches +4. Copy the `pom.xml` patches and paste them in the `pom.xml` of your project. ![Step 4: copy patches](img/copy_patch.png) -When using a repo that contains different subprojetts, you can also select one of those subprojetts, instead of the entire project. In this example the `flink-netty-connector` is selected from the `bahir-flink` repo. +When using a repository that contains different subprojets, you can also select one of those subprojets, instead of the entire project. In this example the `flink-netty-connector` subproject is selected from the Bahir-Flink repository. ![Select a subproject](img/select_subproject.png) diff --git a/documentation/img/dependencies.png b/documentation/img/dependencies.png deleted file mode 100644 index 7c87dae48c45e1b24bc847d79665ab0d62cd7ebe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47722 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%0D*RHaZvVx`3{O)I%9F{B; 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%0Du2Zw!L?? z0FJ5~6}^R7)KymjWz5&8?28fcdPt2gBukGUCh85vh<=D=aDB$EAwkAy0uYiyI!mp? znKfsVunKt)0C;$;bCNF<8&N&o?4^)y(kXf=x^9`^nvh3jOP_C}(?0wp* zdD;^0MUNduQHOCPD|A0drAF{u5Re)yaznPxsSJ*xlCiW73A?$@XLyaDx=$s4b+p3{ zlf0Bvr0p<0aYW+0P5L_smPe&T0uNkjv@3)>k>JTcu3c|V!!*0lE-x7~$NRaBvZ<0u zkeMd*@}2uei1x=3ko*}I_$`C@lWMU-+TO!-3*$F^0GY_Gz5e#W&9Uj}O8eqd+sWrQ zEj;LDdd+osr|y%Bb*|+GH$#yH8FI$7Q7OuOY58-fAy%FxZ>;t3Y0-Ald%c|hfs{N` zKiWjxz5D+_#zaU8zo4##h@{!n62o-C8>T3C54I0#3vzt!gCPh`-W$Gh>Iy+Mlr2ci zkKc6;&bA`f*m{oD70I}I+vk0Uh-sr|ZC)Uc1|==*!KhY#9k+xB3RendW+&0^pZGz? z{`R~AphALrA&C|u&Wh>=Ba_N__K2>X@}A6ZUJkKi_LoudIm;;Si_%mduy0X@QuH?i^(PEsPj944>beX;;k#6ZkD=O_!9TYqy8&3zYzRWq#-?k`J*}8rf z2sW!GQMf%7BuSc~=9QaibvY>cep74G?}7lelk(uvjE;*yMpKjh$IZU-to7{QB{n&U z+IyR3cy|o6W<2txNk}ZB#&j3Px46h@v3?6CxATxL!UiNhbS*ORa2EXC*5UozP{=}h!o$QTWePT|+ z|Hs=`M#a@E?FM%b?w$mP;4Z=4gA-f^cNyFrf;%C&>)-(b1PGAeFxcSku6OdD_uTIu z`TpLuSc^5&v-hsuRbAax&(qaY?|qk49}16KuYA1fYf3sl(wd-fDC&z3QN$OfR7CrP zXC&e=YylUII-!U$>2M?VoOiQx4ikxvqIFG-f#MU=H$DGohe*%&Xs7J%XAM(PL z4mLVKJU}OZHmMPke(3FEDM&HN(u4Cmm<5QdNu-XEK%=m|;@OSkoP{$J;fN#e3qsjs zJ)i0$EggPThgu(L=+y9eRfVjoHeMOuE~BtStV-DkkMDK$8td*AR-oJbDXt#oZ(*#v zwp9k012TZ?&-=Un1W~ym#gk`#YEY6+SxY)HG<0gjc0aS-;G=x!)eI+Uqfg%5^*AE6 zY_t8jR9{c`8cjha9IsB1M!=Z(?-V=LEHsgCrZjEk)28KQ#!9Cskvr=fc1L04WD<`) z8fe31X<2y$O(RtP{zRWMvrCh9&IzLcYl>;H-2U+sE)+SG_!~Kl;rPGEA-5mL`9qga z&^0RiSa^Z`@6I+O*O~7hWW>+2xX=3&VwxB&T*1q&K||;24BzN@Ke%K1J&oB56Rwc)<^x9@*Rv)B zn(gcowzxmk>Ht;YC1|vo7yUxzpP%$l1 z(##{=tmgR%fz@4s=W|izq6l5j;UQByxviC$3HMjcS147gMJSLZyiK@+*aP1y)QtFk z`i*D*hiU7ZlYPM+ZP5(u5}FdPTuBn-6-FM*m!o8bM8}Yj?BH)!Wc%N1_;^LY5sI(I(t? zoh!JRz2Mq7Lm596UT(2UmBH&EpLA0S%wWO9`g=nDCu9@~1^URdaLf|Lx@p)y-NG$0 z3A}6e+EWKOboky-bd3xA4C-KF)PQ0KbMAR}dppqJzrs%|Ks)?jK%Mmu&0ms#V_q2=UL<-d!G4@7+BERaF0p57I!N#TYDb z@n0aRn?I=B6N@Fne{P1v75~<{CIYrqrx_U%`p;%rDiz!}=U{fjV+kG4<7oV#281s^ z-hvtnA^(B>L4|jMqNqpF;f()=)BX8K*NoW zQ=94THbIX$`$;KVt|M%!M1S@+Z`#7%V(^tBN{>UZBqdN@_Y~CS2>G)XTKtI1+>vJ8 zXEcVwYIIg;zivvP^t|!7c-c7ynXOJAk#PefR_Y=_gWfncXCbMZI#N5ixafgPF0+wC z!v^ox7sAy8J)O@UN~3#rJ%-M*1kXTK#|!B2k%8?|?o>xR*6DfFV1O2OnA7A?+lppb zrO?q#+=<|xMh{RHVeU89%cm8}o@HTSOR%L&9ko=N@^)OI@CGinhyj(aehi=UZxOyh z=Y@8l3waP)Wm=*s@9bxV>5EN?896U)n@*OFgwcs%oAa!DVLqRAdrga)kL4irJuOLA z)la~aLXGngtCb!$$RL&$NVkM=6q@I+(d*7Y*UDjaOe_|(`<>~tyGy*#vJ?7qNbq#= z)hi^eKeYgiJyb;uKyzw=**8m<8&+Fk#9&E}w6!jRlUC#jVAI&#(@~|sX7-HA%$x537}f%?k1%S@g|o%6Au_Dlkw{+d+gT{}HsR7WndX-L76`Z93-y z%Dw$`2IX8EwuARTlx&H?9UsT=COfuF-5cpmiv)3@Jj8>HX9axY^oiSv(PGo;*rZFF z)uYtX)z$q20l&;{pL>^bwYQR0JsfuFu@B}EwRXf&@aHr^OYc78YSmbukI9MK0rV*! zyUNAfXvqXzq$Tb(5|-5QVkYX9pHHJPj+%a=hw)F@!KEEN*}KUPSKJfjn9Da>Lk?voEa^H+lsXh? zFW#Op$FcQ8F$n1vq>~muTWi>RIR9ArBa!){7f5!%k;IDJ4D@kSI9Wt4($%9uo)NX zZzOZuaQYqk3?*Td`fQrt<(!X}8fW?$SI4k1(^Ec!zqaSm4pkF&5^;IqosRx=6gpWd z5(ICrH*lUo7=mHK@k+;sk6VsIijv1? zV-D!5u34I|X@C-jmf<}?XGugON0z;$az5e+&4=GPSri(A#_VRSFSu^Fkq=**?(3M< zW)X-Gx+~;9+PKOsh(#cLKRZ%kMEl-~qHXHCedyhGK{?!D3FdGW09%2AJM3am&(}kU z3G`*rX+hRlg~4ydvS( zL!ez@A+^-SK2#Q_*C#J2^e+(L?|#@wROaPd`8xOgdII zeJmScP!h}WvU%R8%d4O~B_;~)Q^Au$hQH=;# zj^`Wp$JDpX0VPjEUnfBxZviDjy8$Wm7ISA}9(5UhKGtx(WvqRo)4Pi@BgG3UfioEJ zbbh*2Vg;#MG!z6O%E5w5x3U-EEvcLJ&x9i)^kVs5?qn0du- zc*l>23~3pfh&W*EQhnG#_}PxLlHVhfr%|%TFu&@`Tlv7Jx~$TAw+caZhy+AB*zMk| zR+{&ZS6zP+wrWvoTY`5ydN;7O`uR!{Tw-xWub~w&!9{5~!=!Dnbk4i=KEF^J^qZGm z%Uz78TtnVC*bOR1%At-n)$FVKr=L$4@Z@^P86%4~J=*+P>DdRTPq)us(|iaCQ0p{* z92JV8IV|N!ML~CkegRMwhBiU72|^l}7h${)2cBdp&o3LxToL??#*fCX%f7ZX7r0CG zS}G3ExkD>Ki+Z8$rMQ?f#-Tf9c@0W&tt&iM7s*gHmNrWeW z?~ZSP+xtY&PyU)56)46(;3*K^CNwjXn$7 z-SQk_cIMOmDhzZpYm-O8hLX-5{5JUyC_idEvva;weJJ~ooTnk|#0)i^tsoDPodxtk zv^2`kG7JuG(Iqm$I9SgDRAr7&6IwxD*Ea?^bzCS?+N2OWfbKA0X)t9mj9~=| zP-Zo=L*FPPuWL;Af@A9(x6_Ma?D1q2-g41vVwc?~Q<)~sp!2*njra3fce%gCU4F;G zfdbILU3V~cb?sfzSI#b)hV#>vZ0`0N24zrC3tEXUqwr2ro7#qX_X%Ue)(!({*q^SzxTU@)^KGzUIybG zg{EQlq59qV+bhCCb`K9{?trJ^k6CS%SpYfNTQlI>%Kp7MQ-4LT{u1r!8#1hp80Srw z3rNp?WmYO`xj#}ug@*EYt>Mz`_fOn6H(jhXv(<+-J^p zq@u@IM{D((@;>|C)YLq7^rWk1S0VpEN1;a=e0TJiOPurR@M83|q@BW#Hz0jq)a@f8 zuLG8T#(SI6vW5W_^@s#Aja3#tqj90} z+(y6JcOLRUtu6^_;p-m%AL>_lag8}HcyYt*6hUt7j`0*5{L82Q3D;ZGA;Pp*2gyAX z8lDDvAKh(?rqKjUJ{q7MT;S*bk}*{TJK<}zkEh2%8T z1*6kk4yb^qSB>-`S<`rEn;I#3)>TM@ry)T;Hs>33OI8{~K|xvySRhU; zmdnCGKxO?p(;3jNd_TG!do&$~Uz$xFm-5;4wX0V@b3l=MEy>H~cYGq@-Lno*? z(lo+*^6(ss569b-nQxHJu)L=vZI-_(8BT7XS9Xg#_9dZO7WVT-Y_P^-qj@7?j(D|o z$n}YXi&jRs?YVxSUF6)AK|bS~jW|$+#T~aNx-I_6A?E%>Kj6Dif1Hx=7OBGnXR#kWc~6Gprz}UX0Kw{N4g& ztPpPK9bon(eR=ic`k|rsV8nH_BEUdrtkK|@u`e!4Fipzz;6};G4>))DP4JDS_%d~Z zkb`dHoeDz31_SL$)fc^KmJ*NObUd)j5C z4Y<)*tD+l}mr&K85va=ziFs<(Kn~C2{X37B> zZN62W7*DtDLj>j2@8J&VmMo(4%dlCs=P`d(tWKF}SMoP~ieE7K3A!%M6ac}fb;Vk` zoCPh*pRFW`xFYsptOHO*EPv*i5*+2$^8B`4-rqg&?Z}r7<>!2eK*Xm5j-`e8AYxaZ zDNX6jD+N39U?L-vQ<8l88JOociL(D`zpU;&Rtp9D5sfk{J?PZ`O4CeO9Oi{e@a1Nl z@|IYaqTr)~3CzcK%N`QtJ)`dDK!&{ZrZ->MPXonhUvaH$?-z4DeY+czBW!r4%vGlt>?lL;khBGLIYYh>JL(DrW9t=j7L98 zuaMaVKYGiV)59H+HR0&;QJSLgK7yN|Lm}5$&-99>+R0QksMmPaD*a;;pm-QM3>t({ zV`3VGkq;>ETAsS?Pv1$AklcFMYQ3uh>wI^dtsfJ_9BP`2`p&b$8{`I`^v|)7zYQuJ zqD7m*mC4qB{0wWmKNWX152yD&fdpWTo%6UPB*m1iGlj|sk7rI4FfT9EcSK;Rd*fi5 zF@Z~LMAI)pVoW4fd4)k!d6j`4;5fp-9mIeGEIm`lhB&j1AZ@{8C|$;2D@qHUx-j#< zN2zh8pNnOSyU$2?(J&VENggadnVf$u<%JrDp>~rvh(vCh{mgF&484KUH??$5}UsDwSY{9|Xxyae$^UA&x79xkJz7y^!U)8oV7`=j?O@L|};RMy)jyb_>P zhC$W0NDyF@wpX`bQ=w6+2QC?_^v~^2+JsDObBXP=Bm|5Q2i>m7_M_y;XhFo=sh#f? zpA5nEo$V+4Q*Mb^J?#?ya&(oS_Ja4(qDezZLY+3P>TS1FOM9aUiXQ?9D=h42%}eAL zf^822NZwR+nx%StLmPb$`Hi`Ug?vGZl~b5l5)u(#9z&5=iqgct_A06Cd=+hak)@u? zPPf-&(r$3rlosm;8uG`Nod69{+&k2FGqQ$9UjpXl;DYX?f_+7s=_~`ooqi4;-PPO8 z*x~U=g?N@wHg-Gg3ubr^pfj8EC^0Nu|HKt8#KnjNip_NTcF3Ahr2R4Mb)Kn&hu)?U zls*8ecBjnCm+sjTv3AxXIjmXLx;Vmp8?*8dsnSRRw~ICU-|YOyy{)sVxfAccI-V2| z+iHuO7ljgbKSw6XZ*5;1b=xH zG5*WeO?L})NO|$acBF-m#(-<3&I_J;>6W!?pL_l0;aQmx_u+ZO;73 zfKJEYsV&bj*3P6Fstg2ot9a5JJr88K{mqxoLK0vFDTQ&>cJ=AXyHfJ7+o=WzXYSbd zL+pcMAY@T4+_d6w_mlJ%sqpk4b&1C#@5lT3FiA2>Oujxa()<>ke0Pq8=4rJ%y1;^` z&#?5SQ74k@+(U*UqT!(+G`m%25?eL*<(o6jqbG@=#}@>=CJXZ8%#G|Cuh3S%;gm~V zoRqtHirM4i4U)*HJ_|O0aaP;mErHTtuXorxk@srU<59>L`UfwM4MeFxE52>vCNAUd z(sxPET@+0A+u9TXZ#;EIBsthSi(ZkX4x0g7SQ?ls>r$~?bX$u=Uuo7k--Dkp zNasP1d|S+mNDm{zNyHrwMh40cCZ2q`zffhUyJ$!~ux{dVZSvn%M@rO1EW}k23Z21U z4VYoLGxqPx=e**2I=kjx_Hh2-{_r(Pn71|YU9tu@ImEOeVHk6{Ai@B$ed%S`HL|EE zI&z3QY3l?&FdvsP3&|H4lkdpqRhqy&&Iy;Cu?}jTxnpC0C$p5${G(*6+0QfW*B==w*%-q~HaW zr<&=LMsnN}O~*)~3`)$ehl}7H9nHM7vI|7nkjm&LlgxG*xBulf*WJuaksc~09JTdw zrO=p_d(9t9MeVhq3A>2`n(++-hNaV(;Vh1qic-d6weaQVMzNE)!49fW(qjL|jkwpy zXXul8?Wqj%9}BeZZ11(=`qrXd21kxBNNsYgiuOks^H;okCb(Dx{WiphF+$d?Z6PNpd28F@2$6wMj{@ndIcgTuo>@s9NXsr$9Bq508(Q8>x#en_1#^c>nGpTU^3D3m_}o233a@C_uW5IM@IC4` z@u&S~i)%QcPD7P*mRVguB=UJzkv?1put&&7$TpU}x=An+z?O1S#JS@8C)L|u+&E(t zwSMt=-SoCz(22RRN2*DN2b6IX6c+$KiMaqwQ4|OTPjkf6;>`Q_;Wz??Lo*xjwdw!V@Lj-pflDa$N(CX zy`g&v=~nay>Up)^{Wp$+W}fUGsQo?c%!7U3XX%!_BD(sCXvIw^VTy@k6vdHw?ejZj zv*fVn?R$&x(HIUGi&LC=ImeFq49jFJeK>54(^}L%{Tzi=`jP#{xN{&b|ALzfWYRD< z=0z4UHn*6H_O|S|WKJk4SfIWdsqf+ERon#SJgfJKBMysVD+X zNy#7y(CCF084|Bki_?=2Pc4bu&qA3gm;bSKc@ZOiLQxb^UzdL4Bzx7=@utkJ*$cSc zDI!;j-l^bALfvweeNejUnUs0`hJtllu-1ilna_FaQn3E4edlD9fDMyZmVBehg1*J{ zAS%j&^9<2JoE>droQyXkrL}4u71kZn@7m1rnw1yK#4z-$v_T1dimx1yahPxrm7VJ1 zVP@3d&im93by;3#eW?06%agVuaHb*7pyQ??;>td3Yjg?M#IUI96sL_R4Rf*7qn6WP zW$eDO7;0oV@Q}w;arxUiIC#nCvH-#tKwc#xeCg=r&SRW2n>JA9*N8B~QLsFb!MYM^ z##ttqEH{*N@FKjJGzRU$(By%lJ!EkvrCE;6;9D+>i$;5rC-U8e2t_cbcm zxxX&^D(1DyHyxEbzGG)yQgZ(#rhBwA5k&Sf|Wz!YhB(7C1kM#`H^d%0)x;vM)TJORa%Aqvh)J zMm%)l=xx7nrEIf9{U%CE%!Sg*5|8|srny21oRN|W;Cx&C%o+SGmpyPLi?cWS9nlNe z%i()b`^lSbFpgN!n&@x6NT9lw=s&rZT}bdbS!j}#=X znbI^}lcYSrTBlPXBVE%2+fJ{ao_q|L51rmi3qEUAyDK&fEe@fiO#NP1O7hn2-`4i{ zuN0)fhK%)6Igw@~8cMIx9}#ePJETsB_WFpxZJxyb{iusZZT8DRgoDEtT=;Y;Y=^19 z9R9Pd^yBVyO?Ce%fJi3EJLLcgP;TVr+QT6oIFLRSnU{o$EHf--*e0LdJ@R19d4 z2ON}hVL066u#%>_=#wR3#?K)p{KVGdMPJH8AfNBpqUGA-I`9zc!{|VNiZl`R){on* z2NHcVqjF?wxe_EkQWG-x>B$oc{%aLF$_SnJ5nFQd3g!;`NcYf!KN5L5**S#u7m(xq zw9j2SA`Q)F4;Jp{neFs`j*R_c+?YX@u%xB-(I=z6o zC%D7}KaPeOw@SP3+2&GQe}cwRP@SSNl`VqU>)oN%YZ5j95o&i5{dgY1-88+I1)hHRG zJ;rHUqHEeo)a+Z{PlLeQeW(TKtMD&*=_nI+d1)EP1PKsY_paBV4ybdz& zFFsc2@FhJIbPmbdFYB3^s(3=)D%1ha$#jroaon?u=Rhn%92 zDK{!b`z~bOr3{&yLNTI3==0gs-J9tGUS*0TU=O8&;Cp2 z2~M*?bCahs$#6 zU;i@4Kc{MT7s;$tq!GG5Uv0iMC%07a&L0ow!tcF*6jv{_BNkwgCZiVkv5D7UnNoML zgHf*o{WE~fL{%m?-aai`^eey73cfXnlpjl4?M`=Ern$?7Si7N6s>@x8-IDPnUk`eKX4G6 z_S-X8LHa?_Qx&|VS(5FFqXWuCp*PBBG)pa4uOUPIlqdX#w?~#+c$LlU=OLUP6lj() z&;*PJj)SPd&meyxw42!c%mni)r|dIRW7=tIj$uSC2{Mi*H>J&8NfUBS`vXtTMcNA} z`_%G(T>Ck@%JJ!>vh2S(hMXO7L#E1Xwz2{pyg7T3G94D@%{TFWBe83-COP=%&Vn8s zM)N?x=e=|}gCfn5G2o$*K<*Zk01kED?LdC2cT_s-MJR?nN~h=M35S{LHJX_{-!rau zhj<3ZZ&)QBWIV7}C@J9NA)uC&8+8yOfWkZ2XDl)+t8#uj!*&RHzI>sPHXZ_Ye0aJ! z66MqN-*Q8s?=0DoTE~446zz+vU$lC$D*ypS)(;0eQ6W6Pe?WS`vx}uIC!_f+=A^%hNg&c$ru>OFOpp}-Wi%-y{KF~Qq}B*y zA}SyHw8?2C*CYD|(iJ%YZ(m$5US!N$DrwgMPo1cH(sC5z54L^SWWES4?JoV|fI8ST z=7-68-3*u^5u!u0!J%BJ<*akY0UkH5QuiAvxk!vc1ldg89Xp3c9_v)*Y;kp4ZsqpZ z({O01ypXQ=4zqbNEaBxuA0^n4drjbB`>w8*a_@hhxzMXj`=*MGv_cc@g75yaALufm z#F#Pm`P=D_TVk*cX)lge!u9a76huiFjbQnVgw$%jcx=B5 zVH-AT&5OQhz|;8t^^eDGJS9+2($S4Y4B>jH-VT-|tu%QdMz|x)Y`hxK(l>Wzo`%Kr zJ2P4~3g&ltKj#&?9*q}~^*)u;V9`>o_?On5)Sqj>&+Ba&t zp7qBuoydTaYV_MRRpDwPV|kquoX@5g1e;r6x|7;xP%Gn$S^D%soi+yHPM2O&FENmu z3$ntN%Yry6V-^gNwVT-rW^8xRKa)ZRt0+i_(JPkWAL^V}c;a18?|-fMgK8>tSU%-^ ze;>L|K%vQ*&v+1tQAz0RTb&QlWv)8@ge5?S1BZF&D#M4JeW6yb^PDMY`>txu7li@k z_$${pD^@Vx2A%Bv0^BwIvV7WjeLflAx4#M< zpfSg<@Y{R;d^O8sv`Kz-Uf#`p*)7UQ;FlmrOa|zEXXBMe9E|e9bM^Xp9g=X9Q!^)* zircu7vFC}WxPM97plDi&q+sc^>D3tH^Z-e=4JEa3p(L*iKEZ}vpS@YIsHx;%3>u<@ zPDC?DNq1vb2#`N%+_O)&GAkctz!VT)gL(|R$=ac#ICJh6%O!DOwuPwz2yiBSA8bM} zNWPOfjB(7N&Hoa_&jFvYjL_D%HZQffLLlw*z0`(rpf--P|C+Y5ME?=Mv;|jbNft)@Lha~>6ad%5ct$!ei z%}gd({#2&~Xmv#drf>&ezXFN(ndoVz2(R~LRTW%NSIqDy`F95usjsI3bsNRF{c&^g zAIXRj`owQkceoN>K6!%HLk85e5>1=ZA1o;0=-HYpg9 zd^VvwVr&pX*Rrb;5rj@exj>ScH${4LY&H9N9?^NdA82DxkgYM7Jh?G01>5l)di)kY zH@kjA;%*lYweZg}53(hM=eo%MwU9PHdNNzO@O?C+V97MD$G5{Jt6-fX_&(S_LsHbJ zR69kl=q=w6$!e%hZWuVhI{TGC?}Sb2-AS#5rUkmb3Qh^-Ggo;2S3#Z}gnKw8Wuf^m z70<_~%Mu00ShVaR!+jlX`z6Mcl=@^`AxPS_-J~uhE2y82-(qRhJ~@f=7YI>hSleS0IZ^iNW2&EsYJJJrinfB?txQKTmB0;8xaw8@Cl|0dzv zhNWVQ$D{=5lXtWz9pQaa&I<5V< z8-oBaQS$vUurWt`9YH%I^p$wurWEH^o1m>tGjpQv&qV=xS&{zF&HNc0I=a8uOLO&P z%>pssM}|htu?XGP8nhIwP<8_k3PV4C)fXDKGTpbqejGdHu>Q8sz0aUY9U^P#jE*Z) zv>ZA>|NE>|!mH(q^tqu@SRTH{w404fM88w)8ZF-s7U#gP{fV>R?OEB~KKHJ-3u8r` z18sj?h>>C_nzgiAVu7WtJZ=QVySG?-<{ZI2->_H}hD7JNeAeOX%k%_)l!r&UKj+3o zImo04#)H{*>aC15X?+(=ioADWRj3o=1)8jwLAf#r?^O_d5(<1l3)UCw#I~jzo70C% zuF!CCZcDvFy(lfQDn!d>FP!75c%42%cz76bG3+1y$OW~eH?oplwJQeof|bg@ttpA< z=2SmKjJ?KzwqwI{h6G|C|14kxA_TpbdZpdQ(U0tXQ>kQoUUh_OCG)9;WG4@cN?}(Q z685c#iP_Pz85uHe8%po@*TpWPuyxC@TB{B_X>lap+;Ja+oO--;a=(d*b)XM&e)xw7 z=&%wXu8_Q2e0X*2pur|Wo7(~bpKVd2^Px$g%^{p}I5I>TaRfJliV7JSwv9B%Muk_6 zK1TX_oVK(s8aZ50k)1LPWX&(&>5DTiQjgy zgt-}<%p{hghzuJnmPShzDmY4=h72E+6Z0zGCJ^6~Y_H*DjiWg}HZDV3%hh3o-r_HT zpuhej*Pn~VWyFv@$JuD*3jguN-{1eU8I=ZlPXsijWadA={@2Dps>BN%?7rNKQCamj z|Ft<78QMR+5-D_O|9LGH@}?g=EZ%Y7hnStmC0SI2KRU<$hwA_5Ul3XFw`buFH~I72 zsTN^!659NP zoqY4ZH2;6NdZg%v(EWgzcT+L~v;0V(rxIU*u$&y+I^fR4_Fp^6h2oESl`B3X^D-XP zngx^(Tq|66_Z-y34ZZ_>7v{#OkV*972Hx1xXU%x4cC*x0c#e4G>5556A zNJtK(kGfsA<->(n$AO_DCpDU-IZld7FNZ(S8+*QfWIgH9fOjqZx*Ze;#{qgU>YMdlFC(PcFEE0o+uF4|Up^3{JI2`7@#t*O7DF zCgt|~(8hJ3r_x0ZM`1uPNwt3$eV9IKy^cx-SPP9C*U6Ied5NX6Xh=8PI=4WJxn(HN zvGt5=8Y^cIrAW8^)!p7{PG8s?Q`{J%ogS(UT!nzgAeU^WC9iONhbp&+VQ%3X?PlBA z$p1x(K4i@@r;2@#0et8Y7s&#Iq`Uz2Fxf6rFhW1BLw225*~G!L+RzgQpe<{A-X(12 z8tk)LB%j7ysMAVG`uO?qNEvd^Acqw$mdCIZ_@+aa7Y|}Guz56+Ap1uWK14>yN|SdZ z$=xK=#abDowJC1s09=ro}e9^u?ZlfHysv?y(?+bk?ue$IF#B!V94~P1b5!IhM)wgsW&f z$)QR>&S!kf9^kJg^OmZ5t-|+^fJDo|o8x7|_j+AAKU?CRGf%#puXOpgu6V2y)RRJ_ zed_5qR3=duK3pBK@g`7AaB8Rs2WyI7tY79ww(CImTe)*$RCVs-pU1$=L3J*CP{L&h znuvD7OEMl5u-6ajWn3)nH&?VKZ03rvi0sGDI0Qo4luaaX}HLZA{HEW)PHVC=BM>O356O~$e z&9;RotxCGk3ZxqDwsYDt2^3mXQy_t_3m=uPP=)e(?(ee~Z_B3Qme63^P=bV1Kx!Ea z;(zhjI60EK3!%%nf)x^esa02@L)O8hQ4BnXvLv%tFy2RTtQV$+uz*hp6Ymp+1#$Kv$-yiHzaa7CIdM&C-+3(fpBV#ue zu;B3!n6zs&HyD+*AFeIv^2RT9irsiiI?bFA?#!30NLDY`E`h9N*``dd5b>}>ABHMs zZ2O9bQ4voCrqHjt{U2=f#fw?%SE=R-EXGXn-?~J%`~DL1M|<=pj%Rqb{-Nlg%k~#Czxch26!Y?%7F-34T=Tw=j61? z4c@lvV6I|!hnxgF4!b7k&HLC6o?L+$*pQjj+_CV;StcB6MoPfJ-#ispxE)a|ohZ&X?L%H-5GXCO4KK8Bi3A90X7?&l8lJ8_`>UMSd{(2?M z7oMLbRiVPa^%*@>kfl1S{W&Y|H%yDZ$*SLt|Fq9`prFItzAE&{Jgt72?#*q3tM)TQ zt*`PHO0V;YIp53Miv4Q$Jg5*P)JeF+-h4FVob7#>;uwwd6BA1mBVu=6W5@?yw`Fm8 z8inf+<^<&R(Y=Zk>KpvV9}DFy*6f#<*nd|Liyrd3tk-MyagW90dJ1@~m)EM)=HBj- z198AOFLMhw&HN&g+2e(l0G`Wri`gD)mj1R@n(ywqeaFngV(^ic3W^p^%!D&o)?xir zO2ez6jJ;zILDkdKyY<2m(Z*Lbt|GQ=5>738% z%FA}ANrKQEN^L=FeOj+x8@M}UyC%NY>D{DX#P%C4xozf9e`e52S{?TZD=pW1CUzx! zk#nfV;_(k%$h*BtY5_Ekc>*?&zEae(lo?j0>GhaOHnD{H>h}Tg2$)mMs1eV%!6%ba zKzqUP9Ua33tr_7BH(>|g{RQg6W-OfWNUB76=t7T2o+-0fkQrk62|&lYT}lXvcYeJV z4$b%DUgNe2-sH^ckt2uBDt#r} z`dEnqP+Gk4_h@Wv%A$(gM|;1v(rp$&5nDtX9O#rSg*5TYd*uT>KjqV)37Kg_jtWy8 zOC-Bw-MiQ)NpS1QFZf2Y2#<<=8ypEcT)#%HaM3bnNenyguXwh<<4C6Gm?ko=5cm8Y zcI(hXPx1tj_E1o7^ZD&s?jJ|bpzOi+oYjxqjLcN?uH1loUfYW_mMkwG+h1akB`f6j zuqGDMLKBmjz_mv>B{DHC$nI~mdm>Ej;qLniCY$Sycuc$H`zyENnbv#%sCD``&n0>r zl0C(ux*xG5L4XkwXa1=KE76y8G-ADvvNn8W@3g99nU2ZbgnI=)W1J6tB4vB@6se_E zs>`VkS(FdGuPmQ(_pj8fhc#7Wj7Hl3RhPsj&FGQg)K7aVE!d%bC|t;E#;B_^hxh=D_|I{P{kPSNcwG$n|$0!aXLU zQvlV-A^iE~|<*pkd2BPUC-f!GdT z+`^ogprCG<%PN0CKE)$H3TD5@1;!jxS)}89om$uBzMUQmxUJ8y&4qrZMTztX0dd}> ze)4ryq~WhSp(pD@#*IjG7Ao%3bz75w=8p0ohJi-{GwL1$Z5+*Bp{gecO0ITu?LU=m z2g`w$Ezh9-SmvE;(r}qvN@*Eoz;k9uao4EF)q9e_Q7mvLUBhv&@+*cA_8*^uQ12|7 zDlmegpOG6-VETobWp4rn@Avf;bzhl9LhXRqf#$+)N;|^~1eojH#A@+*{O}^}&(2_} z;@Qa~JtC^xCBJn(M=AYHw5?6#RdC%Oud>#0wNDEGTmChV5C(L%1TJUjh$h>&Upe_uT&5{O@?ovSMkVZ;rC8bM{Sc{fkNK2Q1uvh{ji!SNzRJvQbq`UV7pZ)Ih zKJRm`Ykxb3uk%{hoQyHYnB%^G|NDO{-fjTUB*{tUQg`ruUg_U{CxgmDi>JUk&45g?^TcFs&jbrc<(`1 zSI&)wR=%rgNWg&g|~cGA7QP>-+f!$i!+s(RsHB$QITfe4;BQ z8W5;HI#NDy;K2MQ1O%(usIf}ruPk2&*qPdHIIk}a>&-|}yD~k5V(D9$7AR}Dxr z^L!2pgQAr!lL3o*MUlpv@LL4e_GjapIa3wah3$tRU~c$K%G#7T?R`WKRKsa5x-ws} zP}+{WljAflV+4`$bNuFD+ob-@kQxRj!b`^SjN}})P%cPxZq8Mn@`rU^PL>k4g_5KT zO=}q=;~;M(Cze>`#+4evrUcuWe#RXzEqhb)Rk*haGJUOQDY=w1>R)Y-HH5;6`C{76 zeuf`4AtEsczuePpe`51zo`SWm_h!-Py7n$%JD1JA%rj+9>g>$9bmNodA=uxkQ|%RA zZr~Mfgxiyvt$&|8Y{uAq2t2Rp(1Gm6EkW<+iyv#r6z&C=QogAb|x5S8X~NB+t`y2k+R(MDs9_uFpF67bUg} zs^^YNK#1@$Ng}+MBoTL^okOhfBpLGa+(dImA@w!xhy&)arYRaZAusrkBCC0^>j8`y z0s|&sN2Va^Y1F3%QCD$j`>^ozRIA6L^B61X=Yu;*7D#}XTNNlb-q?8C{i#c$vZ{9G zvQl)>ed9PHWnv{@Xdy__e1n?Ew9vDXfC13ws=q_7|$+L>k9}u zJM1>{oscPiWeh9{hWtE}fOewxW;=c^Y*%AuQeRP6Ez3~2-D23p)cG`_s5v&2^YgS+ zU>9zTB>PYIQMyHWd_bB--68wy6jN>F(@D4#oYblfu}h0mk|Ai-sS?kwpHrWa4)b+t zmz+LrTRjq+Bs1rluP?X21HYsW98--q@D;7-=fnh<(2vPh{xzffC<@q|bme;n-e46l zoDzK?5SL~iEok%LCq87#eIqIAFsR(^rR+=zUAsBF6YNhR6BsP5NNv)n|E2t^QEE4` zFfu1}f}3Hlxfzw8)4!4m@5df}A4-=iBlef)B^Wwk^u7`hS=v6rZ9rU< zrJ5~WnRf1n#G^^lkTxQsZHn$AR_5te=CDk&0k|QDLKz_bus$ez& zBwCJ2Ay7rt9QlPiUQ9ImH#7*BW3}DD*LTyWJ_js)HiOy}L+%S*nJBrK80%qvmBB9+ zKT>F#D)=X*lRT4j7#HFx^0wJk<3dmTxisr=5I$L?r`-(J9c3=(-|z)SZFm{k>$qIA z#-CMuo=}||IQeZ_)|O7JFp)WPun=sUEsf>%?bXXYRT(F3TnF{6QMx8G;Yq?hq2s&Q zs|_VIs~X+nr1QP`%P9#Pw}W&DQ#AXtgze+&ro2RAey@nlmbe*y2Y|=N@fea03KI#&Hcgpr}=BX@FV6dVM4E9gsytJIXaOge^zCKFW_Z|T($TZolQqo_f*93HEOyf^Zg1 zk}jgG-hl?GNENmkRF$Rci*-Cp{haCd}%jDG8 z26@_CXbRJ+3jE>vKrV{b)^11Seb*o13!RG)Y<-+LE5($l^T#RS@ekixzpNH_-iSH} zLIEetHT8LO!ffz!KG7EzzgN*&Upw~+!tEv$*lyTR3W1{Ex1FS<$D;GDtlCY1Bi5^C z&w*AT>Osd_zx0$6`So+H*D1~y6Zqc;O*oS7Hxn;&Ssjw15q2S$$pFe1ti!*QFP<%b zlrQG^`7ff?4vUS(PeOKkOq*;LWuV6XIGXClMVlHz55pqKrG#j0-r+VVZO$dq-D+Me zcbn(nFf^EZy(ffFT4-mye(QYNY0S5h9%&k(Ds?uRtE(kxio$)~Qp|M~ zt2NP*|H+%P8Q#4d>43|6dmQvD@{+E#9c&#g|0@*GSp-6X_S$xaE;|zDT36%wi;V=x zxYO38^TtudYy=sDLy}!Lwz5~#XAHTt`u%f?OZfs{i2`Zh6^48=Q=p#_cG(Ui`^i}1 zuNH2H0@Jl!&tO#-)xv2TR#uLnALsPu?mz`IG2vNk1 zrBbd1{2eilZx^99sIAx*GhMTXJSj|y!YBAiSV^Wfpx2L*@)ZkfB^q|)BcZ*sMuy~`2`HWm4L27FENsXuszW56*+yD zq((?$$eMBfk`CCy67mXerwpYfueb0`3fzB6WDCUt-k;+c8)i9 zQqtFu+OJ&P%H~lSy>Ic2UJDYbxOw6lo3l&<6TYdL)&Xn+jn6;2&M^jcXu--SR%*)k zS}YH(vBs$kf%Q`fA~L8gG74Tm9GdD9JXP;zQA+&EZ!`W;w~mh>l$xsZ9=k59OL_EU z+HFFg3>nBUTev(!(9c5#E2FCq7eaZRXs!Biyd(=(lC-M{Ao%*)S^*>W0!?Bzc{(kw zfq*tBMXU~@Nvn@9j-plMJ6m$0k>ju|KUp_L6J?XPU7&Xs1O+yqW5v< z`xtOM%?qD^1fyNiq~3cS1QdwVj2@>@T#;`t5clpedfl4s?CA+b)_~7j{myV3Bn3n9 zi@|{Z+va_jTF=Sb#qy5hgNRhzl#-q7*@gQ16@Nc)Ehf#Lp7UF+@2M#(58=?jbKgXF zYTjSQ=0Kz-DpR|+ThXJSIVP%HVmUzKW^B(OYYyKfkDBlg6)X{I*c*)CZvIea67a$! z@K6E^gIs`JwfOQfl!J#p(@8lY8f+}dpJ5R5YJgIb6WIWszHDgb(}wtWY8+N8d)?W%vr}Gd7>$ZMKQ{n zhAaR-wrnX>OM;K^x}!hVgf^UQdt}Cb_Q-ndqsk8%j~bo}m7O#GY6NuV+nCyc_Q&^~ zp$UETSi|JTcB|9OOdIsV>x`*hp4EUGj?VJ6Fsmh!oSoL zoT%ac%2ZQqHg6keojYgi1i39E_$ODVnLnKH?={n)F5_BXW?8glQ*$3ldNol`J|3z^ z1b^9@d~)M<>T^*_{soXw2;10x2>1Of{n%lUK2~(}fck2;q6@3Jr@Pu^^~1IM?y@W) zfy*H;@+3d^LWb7vBUN}gNDD*R`#X076pS{hI?nK6^gguY!@I(7Af{5E+;tD95W|U< zx=%Ou!_ynY4N7hMtEE9zEAi)16Jqo>|4P%VUQ13Qmwed;F&W7D27>xH*jsZCWK0uF zEcN`0)74U)eWAo1Jt3ILZb(27{8+QQY)71qx$Or!&CrR!VK}}d^lY?~?%cu$!(dhJ z+}(??>tTZQk1)O*@Wp-{sdYq-HA@ zb3d%*2DuZ6le#WgY1=rt_p#(Y86pqvm;KCfb^TFs1-VD_ho|eHfylZJ2DSuW&_j&IPYn*rcFot(b_YqyRm$Y3g{nM7xo?YYH=n*vZ5VgzkYl~EJ zzYV*7^#iJzHzClJtO|2U1$zwex)V$gFGks(0rML@5IL&l4ZnulWs*);J*^_0mYSjd zZa$;KXKb=WY0Z<~&%373QEzNl4!ECh%)Hux6_zYjj2W>i(8o&rMNVJeM_Oliom0tJ z4B)e05)zmdDEL*xs1Cx&MYJIrrkyH0=20P6gy2@(lBtoQL3O$B{su9cu5_m2WSJ`* z+Ns_a%QR$)Z<(qI%kOx3cKC-wf^2_ziP{~g+X znHP94796YK7yl^_K$4{8paVvoBd&Z&;~y_u-bxV2hY6$qQQlzi92h7AR&duX@cs{h zgT&zNgYjlD(f^a!z^B$9ke}45PsaQ;1^+H!@cDN8V3w*1(*GzWa03D3IiWszhx%9k zKS%w4riqB4GuFQbEqZG-Unjfa`dlHLMqEty1z;Eu-W`iQII}&?p9479R~JBUS|Y7B z%YSYB26(szUyjxoG~uZ(0tiD9-alw0X$9zaBZFv${Vz6c8`Opxu9*eQU+v$$8WIuD zQ>B9!HYmv(mitl+w`NP^lwjA+S%>hkVn0^B%A&#)ja;oT-Cc?NISX9Z|=!QpG zT;F+pP-gi@0>{*g3IKz@PBnnkpW1yI%l*7sF*hm~$EK?(e&M{re$;jf;@YW${0-@E zFYA55LVg?x%;_hN=Uul_mv8w02K1GW_;v7I0id7eu-kuik`t>e)HT*udxkaKkrHv> z%z}HT(!unV_`*1SkGbZh3oAZ^6ykASwMtw7wD{Ci8ade5er55zGF`PZQZEF!k)BRb z%oE_<>U@Ryf!5Hq=`80}3p&^OeT7N_TucEo0OxHqHu-VQCkousyQ|ZKz7>YECwDI@ z-|dMCrT91FOfda4lx>VMGDWyRa^=3j7vlg5wi&2{Qe>_M(6#q#ufLsKS`?guSzT&~9BU7Q z{J|UzHDi!VS&qg?_?TgCi~D}!YRqhA&9VxR{_&NVm7wh-f;@119|d7-OSxO5W#(Zg!?eP))`X#Kv!6;*c7bk=@K-x`dOD zj8x_8<_;<65)wT`PaJAE)9ir@7{H(S6ThB(%slOzdG#b6JXClZ9lQItrp>#f)7T7iFwy z@4Mlzuzj)I^+bPt8_U@ z`uIjIJ+=V?w6Ikg*Rbz-2Rg8Y$)Fd+Nu7AZA4 z9Cg1g4<0ZhNh}fYqxTx4u5a6G2x!E;KqP#45P7y{iiVYg_`H6z7^#t?Q z<~?81#V!_pU>DkKSO!W^;@KR;WL2LG_3;ef1{u&*&yA*x1U*W4KWA(tC?u^#&MF*N zL|{{zzC~vIPERpVzg4v{&A&?fxWKndp_J}4UTM$T^xLIUDSZR{=)Q_t*(J})(`%xs zb0alzo*@gM?z_x-y>>ONo9!jQ zvQUO{#&Em4OCSRW5AcW2ii1?~c09%WF%$`dD_w8EPrfESQ!P9ULW$OS9F(+jR z>qrr~`!aFDdX%Bt77lmvdkw%~hq!;rb}Rqovtg!U`C9WH9i?~HgY`hU9$coi{^RzV zK`PS8F_rM4(F3>`s{a(DkZWMmslIg7!GJAxI|1{Lv(mwFUrZj<+~%RRPQ=!f%RAo* zz-?ONs1!4e4^;oGGUyhmJA(nFzR~puscRD>{V$MuCjUPn^+aMnhldvDJ_mTb_V;@H z)8!(gb#^rC_Hj?N44s+sNrwjv#_|nSdkPNBnQYE0fnd zN>aSfWO@vXqF&rcYGj+p=-BV1Zh~ghY@);;PPxuE9JoSlxx zV}=U75>X8b4EN*`Dh9S!Y9E0OGUhk913Md*Bc*}&&};kCUC-jih6BTkEu5!@)mn*F zfET8-x&qE@18imA-fzvOD;Mf36q=`d(lwgkWv{DzK8%}`b{2V(Pi~pUt4R#9?u-<_ z%47E8leu|68Y~?U+DMc*2YgS;?XVjkQp$HcJg+ZKsxw)pNkSc^b3n?cD&>Jpx!vv% z-Z$=XKpw3$hyZqOq$|$lV>V@RF=B1;1q>2cEH-YDwJL02ma-vYFVjRx*VeEIQP zdh-Q(RWVjmi11@%6dS?xslOrge)zA(>jwg&Z66-6{z4crk(De&MRUaN#VQdjvXHVL zZhGX3r5{u*H{`x5m3Pv!7x~IRwTYlmUzU$^3KCihmFO&+@J(I&Pm4B1R)p&QNDElj1iCA32Q&=q;SHMvoQP=q7u z(;WxjB(Hm)jg0ZVSv~PYD_$SkH211;?;$@L72a6~5kn){)O*tQu|NRF=qBI$yxwu; z9~{d!-){Rb&-G-BD6vwqTJ^oQTi|%RZiwdDE5p>Dd%k{KMA`&A8MUGr?YjQhb z?&3LBMugh}bI^q0J*~vq2e}*z^WVDEOxR~9M~6ORQVIaz}M!v(GC;VpeXH36ah2)2d>sUqF`)+=(93QHbs%?@=c?C3|-Oduioimq(nTs zkz?&I&Mf_ zgTl7@DR*U6g2mnG_w+W%ph`1~0ZUufH0xhnYxAwX^^07mbj`OTas734NGbbN?#suh z{Lew{JzLV}Mu)*8MjlQ(h>hU_r6tE8av>XOY_|a6%Al}|ODwbzo!@>yrkBBWEJbyv z=4Q5rVJS%y*~7Ir>g#VA6s5}f8eRUjZIk>vXjOf@?D&182 zyaEC&aPDR?XZ5>t7>CrosCBq896mUQ`}wiek^#s`ryk$Iy&AWssQ}t|dMFEM{-pNuwENi_NY+lApr1n?<1WnUy^wA3weSv=qxLC1 zZ8#+Kihta_F~IW0$?k^tyx8C9n2+reZLlL z7|C%$oHO1rfogkiFh(zWp-5t^HIQe`83NcXcLP6IW^bV_3-?6hvxJ|7u*J&n2`i?p zu@(LZdywO@=gTu1xt@FjF6H2?oi29oJlgcWaF&KkAvP=RumiGkF*5{o@^E5rfAOd{ z-fr;)=lD~}8;r%|@k#Uh^HZVZ_#ym6VM(*CAo79Rsd^5b^i*_HKdWXQp_} zni45w`<_m=+|5f7<7}R*j#-t9dG?NWJ2D8rO8Y>X!!JYOBl>x+?jZH$L_J_4Evo6%0|%|f8lU+hJlJv#bq4w^0ZT4;HkBZG^z#HK$+zhSAZe+jdT zjW%p3U3_paYv4IW=Yy;T(~(Pz$sfIQWWVfzeM{$BkZW;twvKyg!1DtU zvz^n!)^f4NLhx1TdI^D{c5pl$SgGk@e5!AkKQfx~xBM3vrtLTg?=Xnpo`mj;Woj%4BSo*}^uv`5>hR#6!4&BITo-O0e)gH` zw8_W;kBnLP1$r@VzZIB@y8so?8*JAYKp$@f~q!zem^AqUDakK^B2pN1PP$WlNvp@ zS**LB{4y!@?D#hhl~^+t?%3)bBpc?VTgL+*#DrB_NQLzXMNeT0gkTc|e-=TldaR=R zDz&)f|AxV%w|EVlO;+-rO{zYcof^f!6}CAaHyjs(T?JIhPUS`U3%{VGT?Rhcg>Vxa zPUp!(+S%6dy9|{*L1&4-uy7Z@JR{($pEGvc|bCIZSzE1XARVa`f`ITP-PL7yS_r!rGosW0!vyuDVNG;sfu|%SynPBK^bbU^|Ao+J#^S zyY{dvZDW8T%XS>%T-h^B7fE1;W*c-^HoX9aO-UrPO|LQTkdGS{KJ{BO-Qj-0fc-_} z=yw!$d@T^fO6K09a?<9gqHOzSSa}KJmH=os)0#x2qLkRUZn;TYH}*B>JVEO_omwQZ z+(ibv!mFS-Rt@z!+xnLsG=B!=Nhwp2#a#GhIbwh7lR^DXow!i7;Q+q@B~8#`6>V>I z9?c+)4eZ@;kx#vTi8=VtweW7lx-A`QCjTxOsBrLqB|(be@5#Bsfc7MrmVTKg%x-mb z-({3w>iidWhue;pc+2rb@2=nU6h6deuJIIgf3eT$k`_)m&n(DIBxmuwHY~mREcVaw zp;hWOdG_#$P8N{UTSvMA3U<2Wk78U&-*(lgGfWF&RJjzwcps`h<^ak@e3>9wOj2Gj zChB=~H$RWnpWoe{mIB+F-u5qnp<*Rf@ecW@ggvI;321I|nRuH6g2&yr{th_JC<3uB zz(hIglIWdKNUE>aN!So5p{{hlfqQpDXkR-p%%^EVI3m-R*hagq-Kyd-Sf}DO)nvs` zBqAz_f<5p1X-4>raRzc=t(}Zp7`dpdkMwsVw0joWEy$v+;dUKAScv9|0Gvv*S4}3( z_Il}o7l1pJG3P`c{shXcNo2?OSNjUX7i;A^eD_|NzQFLu>6x#vyb|UCyad0{;~1Py z{o5!jH-|4`=c?!A;nF-)L^=Nhx}Q^El2b$t&_sl+LozP?2)5OqdVg|MEzZYF z%uY!z=k(&gY|R~`M7V{^RW1eulv4)^aGl-ID|HI15J}!(ZHXRw_dAozlQRR^CEoP- zxw`|LHeD18NFd7Uod_@%?0Sl#>o98C!o34q|oEx znMwGRZ0y$6#mOero4q zdH%?9T_6=E_Rt2<4;jfPuI{F#RFg-wHd&-^|g^?U?LeD)huhG;>36Ex-yOSV^44sV@ddKnIH zsg!CL`JPezsivcSbenm_Kzo!so$-IrY{q}lY|<(M2xSY>W)5P2cL?v;*mR^ClRyC| zimC8&pUIP`riG#x7@^f!oaCx6cgK}_REX0~XwT?Z?c-eu&E8AAx~MXKjda2f=R58; zElcSGExY!xF@t1>$bRK&=JV5FByk$yarQVpg?G&GdoB2+91#1LU=mCLS(BOqU@>F@ zMmXcoJ&=~ja;71^Jl%7d-+5Rl0maAZ$JHFRni#Yz-iozDp5cVCId@&~coEkIbBX^H z;tT!0>+M3w-K5TZ#-jZgBk&E}utZE4B+!lNpZ14e8#UsEQ#{No@VahGAPYlqMF2Yw z5W?{IM(2{uE063)_P}r8N?x6cSG;Nu5Piph=UwF~Ris@97M9`o2rs`8Lp~;!DVe9o z%1Mx#hyhSQggxnM#{sY}fH>g*hzP8z@F68xzVhODJs&6)TFv>6qw&PaTvaZRTx^&M z?r@Uo<4!#2rcM~a+hj12qoES&?qhWhRFEFM8ArL8DbS#|uO+;^t87ZQh%#9|f$h}0 z2nAOKS&?GCT@1u|c~$rBkVXuK{76#kQF_tXU)yQE1S-xmHKh`Pugf2gWz zx_+1Uh?4flCJ?Dn&20X#N3Hrg)Nvn0Q^UA60L^1etAD96fr!~$RWblZyS`d<8j^UK z^i5yY2mSgCRH$J+x(33`tDf)tdRw)@Gz~o~eQeDl=_C6*Gh&OloZDze$ZW@eGLct~ zV#^Ui)aU_ooyYTa2;zedmn?iU?;XZCLi2c+sd$mZ>|SnNak)B=u|1R%W#Ig9yQmI{ z|NcskVQS=O;|5P0U6uJhJZ~URIh~j1QFM;A*#KcAu$Oy6F;pH+z)|Nb=d)3&R4HV4 z9vgRdWX;we*i4O7s<{h8llEXzdX$Evr!<$YcG*q6opBkNzM@%p3TBNL&lLSRf)E=Y zRpHS$KL1U7G>HvUnX(g}9pqpyt+E@6XNLFK;?1WUo<&D2`PGp+J|7Fyh2E9;8UYpA z5Q^dN11eh=Dj$QrCVq8Z14<>?kF*V*)=T(TC5j1(CtdYTzuiFeF-82i zBWq@unmmHaQJ$Kh-jGU3T*<**@e<@bdBQVcyWM-nWx^#*0sC|59s)XOS@~U}VMEXU z6vxNf^(6|c$OYGpj5~s`-|x&WDh6(PeRiEe?ypQ>Ps6=(d$ILRDCy&Or_hcwc12Mf zU-9OOp3vh2CFj0i1@7$*Z%E-=6`zd3~YJ5m3C2cf$s`hPYp4Ej9+YSJj8}9>*MYHH_3J?lU zPXr~mVxw|a233oi^;DO+TGL!l2Q!(g{@6uRsUAo z>$7yL<#;Bj!0sy%A(=|^#;PrcYbleA=S3SdnBOEw!)L?NGKb;KbB>p6wNb?>VQL2? z?EMWT`;qwDdD2?VcgN~~RaAFA1t6*g$v$BrZIluw0Da!*kCg;v5(q1g=1n*bTbNZo zCZh*VW{(so?>34#JQ&bL%@#zYRx8i{L%r@1=~gbis2Y-~R%E0%27E diff --git a/documentation/img/reload_dependencies.png b/documentation/img/reload_dependencies.png deleted file mode 100644 index e64f7e09ab12389b05ab096a211a1b05171fffab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88799 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 z 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 z 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 Date: Mon, 23 Nov 2020 16:11:53 +0100 Subject: [PATCH 127/169] use ${scala.binary.version} instead of hardcoded version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0949a9c8..aec7f7fa 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,7 @@ SOFTWARE. com.github.apache.bahir-flink - flink-connector-netty_2.11 + flink-connector-netty_${scala.binary.version} master-SNAPSHOT From 5d411e58a95df27450a48b485788402a846b2000 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 26 Nov 2020 11:36:56 +0100 Subject: [PATCH 128/169] Disable CI until local Docker registry is set up --- .gitlab-ci.yml => .gitlab-ci-DISABLED.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .gitlab-ci.yml => .gitlab-ci-DISABLED.yml (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci-DISABLED.yml similarity index 100% rename from .gitlab-ci.yml rename to .gitlab-ci-DISABLED.yml From b11c79adaa1779fd5f2d836c4cd376ca5bd9f495 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 26 Nov 2020 11:41:05 +0100 Subject: [PATCH 129/169] Soft code kafka version --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aec7f7fa..3b4e4b99 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,7 @@ SOFTWARE. 1.7.26 2.13.3 3.11.0 + 2.4.1 2.11 1.8 @@ -252,7 +253,7 @@ SOFTWARE. org.apache.kafka kafka_${scala.binary.version} - 2.4.1 + ${kafka.version} test From 10e6c86bbf310f1b392943746493755fbe5e73e1 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 26 Nov 2020 15:46:04 +0100 Subject: [PATCH 130/169] elable CI again --- .gitlab-ci-DISABLED.yml => .gitlab-ci.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .gitlab-ci-DISABLED.yml => .gitlab-ci.yml (100%) diff --git a/.gitlab-ci-DISABLED.yml b/.gitlab-ci.yml similarity index 100% rename from .gitlab-ci-DISABLED.yml rename to .gitlab-ci.yml From d1f59922bb9719e57300b816df99614b14485f64 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 17 Dec 2020 12:55:30 +0100 Subject: [PATCH 131/169] Remove class parameters for Extractors, since they can be used as singletons. --- .../core/extractors/FunctionMapExtractor.scala | 5 ++--- .../core/extractors/LogicalSourceExtractor.scala | 4 ++-- .../core/extractors/ObjectMapExtractor.scala | 2 +- .../core/extractors/PredicateMapExtractor.scala | 2 +- .../extractors/PredicateObjectMapExtractor.scala | 7 ++----- .../core/extractors/SubjectMapExtractor.scala | 4 ++-- .../core/extractors/TriplesMapExtractor.scala | 11 ++--------- .../extractors/std/StdFunctionMapExtractor.scala | 5 ++--- .../extractors/std/StdObjectMapExtractor.scala | 4 ++-- .../extractors/std/StdPredicateMapExtractor.scala | 4 ++-- .../std/StdPredicateObjectMapExtractor.scala | 13 ++++--------- .../extractors/std/StdSubjectMapExtractor.scala | 4 ++-- .../extractors/std/StdTriplesMapExtractor.scala | 14 +++++--------- 13 files changed, 29 insertions(+), 50 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala index 9fb1d071..c9349066 100644 --- a/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala @@ -45,10 +45,9 @@ trait FunctionMapExtractor extends TermMapExtractor[List[FunctionMap]] { object FunctionMapExtractor { - def apply(logicalSourceExtractor: LogicalSourceExtractor = LogicalSourceExtractor(), - subjectMapExtractor: SubjectMapExtractor = SubjectMapExtractor()):FunctionMapExtractor = { + def apply():FunctionMapExtractor = { - new StdFunctionMapExtractor(subjectMapExtractor, logicalSourceExtractor) + new StdFunctionMapExtractor() } } diff --git a/src/main/scala/io/rml/framework/core/extractors/LogicalSourceExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/LogicalSourceExtractor.scala index 8ce66220..1d86ee73 100644 --- a/src/main/scala/io/rml/framework/core/extractors/LogicalSourceExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/LogicalSourceExtractor.scala @@ -33,9 +33,9 @@ trait LogicalSourceExtractor extends ResourceExtractor[LogicalSource] object LogicalSourceExtractor { - def apply(dataSourceExtractor: DataSourceExtractor = DataSourceExtractor()) + def apply() : LogicalSourceExtractor = { - lazy val extractor = new StdLogicalSourceExtractor(dataSourceExtractor) + lazy val extractor = new StdLogicalSourceExtractor(DataSourceExtractor()) extractor } } diff --git a/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala index 707d8cff..322c2d40 100644 --- a/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/ObjectMapExtractor.scala @@ -30,5 +30,5 @@ import io.rml.framework.core.model.ObjectMap trait ObjectMapExtractor extends TermMapExtractor[List[ObjectMap]] object ObjectMapExtractor { - def apply(): ObjectMapExtractor = new StdObjectMapExtractor(FunctionMapExtractor()) + def apply(): ObjectMapExtractor = new StdObjectMapExtractor() } diff --git a/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala index 0b1cb348..bb4569b9 100644 --- a/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/PredicateMapExtractor.scala @@ -31,7 +31,7 @@ import io.rml.framework.core.model.PredicateMap trait PredicateMapExtractor extends TermMapExtractor[List[PredicateMap]] object PredicateMapExtractor { - def apply(): PredicateMapExtractor = new StdPredicateMapExtractor(FunctionMapExtractor()) + def apply(): PredicateMapExtractor = new StdPredicateMapExtractor() } diff --git a/src/main/scala/io/rml/framework/core/extractors/PredicateObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/PredicateObjectMapExtractor.scala index c0de58a4..22b540d4 100644 --- a/src/main/scala/io/rml/framework/core/extractors/PredicateObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/PredicateObjectMapExtractor.scala @@ -31,11 +31,8 @@ import io.rml.framework.core.model.PredicateObjectMap trait PredicateObjectMapExtractor extends ResourceExtractor[List[PredicateObjectMap]] object PredicateObjectMapExtractor { - def apply(objectMapExtractor: ObjectMapExtractor = ObjectMapExtractor(), - predicateMapExtractor: PredicateMapExtractor = PredicateMapExtractor(), - functionMapExtractor: FunctionMapExtractor = FunctionMapExtractor(), - graphMapExtractor: GraphMapExtractor = GraphMapExtractor()) + def apply() : PredicateObjectMapExtractor = - new StdPredicateObjectMapExtractor(predicateMapExtractor, objectMapExtractor, functionMapExtractor, graphMapExtractor) + new StdPredicateObjectMapExtractor() } diff --git a/src/main/scala/io/rml/framework/core/extractors/SubjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/SubjectMapExtractor.scala index dd108187..291787b1 100644 --- a/src/main/scala/io/rml/framework/core/extractors/SubjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/SubjectMapExtractor.scala @@ -32,8 +32,8 @@ trait SubjectMapExtractor extends TermMapExtractor[SubjectMap] object SubjectMapExtractor { - def apply(graphMapExtractor: GraphMapExtractor = GraphMapExtractor()): SubjectMapExtractor = { - lazy val extractor = new StdSubjectMapExtractor(graphMapExtractor) + def apply(): SubjectMapExtractor = { + lazy val extractor = new StdSubjectMapExtractor() extractor } diff --git a/src/main/scala/io/rml/framework/core/extractors/TriplesMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/TriplesMapExtractor.scala index 4169d6a7..342dafac 100644 --- a/src/main/scala/io/rml/framework/core/extractors/TriplesMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/TriplesMapExtractor.scala @@ -48,18 +48,11 @@ object TriplesMapExtractor { * @param predicateObjectMapExtractor Extractor for predicate object maps. * @return */ - def apply(logicalSourceExtractor: LogicalSourceExtractor = LogicalSourceExtractor(), - subjectMapExtractor: SubjectMapExtractor = SubjectMapExtractor(), - predicateObjectMapExtractor: PredicateObjectMapExtractor = - PredicateObjectMapExtractor(), graphMapExtractor: GraphMapExtractor = GraphMapExtractor()) + def apply() : TriplesMapExtractor = { - lazy val extractor = new StdTriplesMapExtractor( - logicalSourceExtractor, - subjectMapExtractor, - graphMapExtractor, - predicateObjectMapExtractor) + lazy val extractor = new StdTriplesMapExtractor() extractor } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala index e8991cab..4288ed9c 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala @@ -1,12 +1,11 @@ package io.rml.framework.core.extractors.std -import io.rml.framework.core.extractors.{FunctionMapExtractor, LogicalSourceExtractor, PredicateObjectMapExtractor, SubjectMapExtractor} +import io.rml.framework.core.extractors.{FunctionMapExtractor, PredicateObjectMapExtractor} import io.rml.framework.core.model.FunctionMap import io.rml.framework.core.model.rdf.RDFResource import io.rml.framework.core.vocabulary.RMLVoc -class StdFunctionMapExtractor(subjectMapExtractor: SubjectMapExtractor, - logicalSourceExtractor: LogicalSourceExtractor) extends FunctionMapExtractor { +class StdFunctionMapExtractor extends FunctionMapExtractor { /** * Lazy val to prevent circular reference and stack overflow when instantiating the class diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala index 4e530017..9425b428 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala @@ -32,7 +32,7 @@ import io.rml.framework.core.util.Util import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.shared.RMLException -class StdObjectMapExtractor(stdFunctionMapExtractor: FunctionMapExtractor) extends ObjectMapExtractor { +class StdObjectMapExtractor extends ObjectMapExtractor { /** * Extract. * @@ -101,7 +101,7 @@ class StdObjectMapExtractor(stdFunctionMapExtractor: FunctionMapExtractor) exten val joinCondition = extractJoinCondition(resource) val language = extractLanguage(resource) val datatype = extractDatatype(resource) - val functionMap = stdFunctionMapExtractor.extract(resource) + val functionMap = FunctionMapExtractor().extract(resource) ObjectMap(resource.uri.toString, functionMap, constant, reference, template, termType, datatype, language, parentTriplesMap, joinCondition) } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala index cf525a07..d0bff3b5 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateMapExtractor.scala @@ -32,7 +32,7 @@ import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.shared.RMLException -class StdPredicateMapExtractor(functionMapExtractor: FunctionMapExtractor) extends PredicateMapExtractor { +class StdPredicateMapExtractor() extends PredicateMapExtractor { /** * Extract. * @@ -92,7 +92,7 @@ class StdPredicateMapExtractor(functionMapExtractor: FunctionMapExtractor) exten val template = extractTemplate(resource) val constant = extractConstant(resource) val reference = extractReference(resource) - val functionMap = functionMapExtractor.extract(resource) + val functionMap = FunctionMapExtractor().extract(resource) PredicateMap(resource.uri.toString, functionMap, constant, reference, template, termType) } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala index ccc55f91..6be34471 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala @@ -35,12 +35,7 @@ import io.rml.framework.shared.RMLException /** * Extractor for predicate object maps. */ -class StdPredicateObjectMapExtractor(predicateMapExtractor: PredicateMapExtractor, - objectMapExtractor: ObjectMapExtractor, - functionMapExtractor: FunctionMapExtractor, - graphMapExtractor: GraphMapExtractor) - - extends PredicateObjectMapExtractor with Logging { +class StdPredicateObjectMapExtractor extends PredicateObjectMapExtractor with Logging { /** * Extracts predicate object maps from a resource. @@ -74,13 +69,13 @@ class StdPredicateObjectMapExtractor(predicateMapExtractor: PredicateMapExtracto */ private def extractPredicateObjectMap(resource: RDFResource): PredicateObjectMap = { this.logDebug("extractPredicateObjectMap : extracting object maps") - val objectMaps = objectMapExtractor.extract(resource) + val objectMaps = ObjectMapExtractor().extract(resource) this.logDebug("extractPredicateObjectMap : extracting predicate maps") - val predicateMaps = predicateMapExtractor.extract(resource) + val predicateMaps = PredicateMapExtractor().extract(resource) this.logDebug("extractPredicateObjectMap : extracting graph map") - val graphMap = graphMapExtractor.extract(resource) + val graphMap = GraphMapExtractor().extract(resource) this.logDebug("extractPredicateObjectMap : returning resulting PredicateObjectMap") PredicateObjectMap(resource.uri.toString, objectMaps, predicateMaps, graphMap) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdSubjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdSubjectMapExtractor.scala index 58f8f377..e10810ca 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdSubjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdSubjectMapExtractor.scala @@ -35,7 +35,7 @@ import io.rml.framework.shared.RMLException /** * Extractor for extracting Subject Maps from RDFResources. */ -class StdSubjectMapExtractor(graphMapExtractor: GraphMapExtractor) extends SubjectMapExtractor with Logging { +class StdSubjectMapExtractor extends SubjectMapExtractor with Logging { /** * Extracts a SubjectMap from a resource. @@ -81,7 +81,7 @@ class StdSubjectMapExtractor(graphMapExtractor: GraphMapExtractor) extends Subje val constant = extractConstant(resource) val template = extractTemplate(resource) val termType = extractTermType(resource) - val graphMap = graphMapExtractor.extract(resource) + val graphMap = GraphMapExtractor().extract(resource) val functionMap = FunctionMapExtractor().extract(resource) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala index a84fc732..af2d9f1c 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala @@ -35,12 +35,8 @@ import io.rml.framework.shared.RMLException /** * Extractor for extracting triple maps from a graph. */ -class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, - subjectMapExtractor: SubjectMapExtractor, - graphMapExtractor: GraphMapExtractor, - predicateObjectMapExtractor: PredicateObjectMapExtractor) +class StdTriplesMapExtractor extends TriplesMapExtractor with Logging { - extends TriplesMapExtractor with Logging { /** * Helper method for inferring whether the given resource is a TriplesMap. @@ -118,11 +114,11 @@ class StdTriplesMapExtractor(logicalSourceExtractor: LogicalSourceExtractor, try { // create a new triple map by extracting all sub structures - val triplesMap = TriplesMap(predicateObjectMapExtractor.extract(resource), - logicalSourceExtractor.extract(resource), - subjectMapExtractor.extract(resource), + val triplesMap = TriplesMap(PredicateObjectMapExtractor().extract(resource), + LogicalSourceExtractor().extract(resource), + SubjectMapExtractor().extract(resource), resource.uri.toString, - graphMapExtractor.extract(resource) + GraphMapExtractor().extract(resource) ) Some(triplesMap) From 54ae902a5e3baf01ceb10e08f189faccc4e2606d Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Wed, 6 Jan 2021 13:49:20 +0100 Subject: [PATCH 132/169] Fix bug in test framework: extract the expected output format the scala way. This will introduce other bugs though. --- .../io/rml/framework/OutputGenerationTest.scala | 3 --- .../scala/io/rml/framework/util/TestUtil.scala | 14 ++++---------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index baa91dbc..017c8110 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -24,10 +24,7 @@ **/ package io.rml.framework -import java.io.File - import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.FunctionLoader import io.rml.framework.engine.PostProcessor import io.rml.framework.util.TestUtil import io.rml.framework.util.fileprocessing.{ExpectedOutputTestUtil, TripleGeneratorTestUtil} diff --git a/src/test/scala/io/rml/framework/util/TestUtil.scala b/src/test/scala/io/rml/framework/util/TestUtil.scala index 1d24b1be..e69819ed 100644 --- a/src/test/scala/io/rml/framework/util/TestUtil.scala +++ b/src/test/scala/io/rml/framework/util/TestUtil.scala @@ -25,9 +25,6 @@ package io.rml.framework.util -import java.io.File -import java.nio.file.Paths - import io.rml.framework.core.internal.Logging import io.rml.framework.core.util.{Format, JenaUtil, NQuads} import io.rml.framework.engine.{BulkPostProcessor, JsonLDProcessor, NopPostProcessor, PostProcessor} @@ -36,6 +33,9 @@ import io.rml.framework.util.logging.Logger import org.apache.commons.io.FileUtils import org.apache.jena.rdf.model.Model +import java.io.File +import java.nio.file.Paths + object TestProperties { def getTempDir(test: String): File = { val file = Paths.get(System.getProperty("java.io.tmpdir"), "rml-streamer", test).toFile @@ -94,13 +94,7 @@ object TestUtil extends Logging { } private def compareSets(generatedOutput: String, expectedOutput: String, generatedOutputFormat: Format, expectedOutputFormat: Option[Format]): Boolean = { - val expOutForm = expectedOutputFormat match { - case Some(format) => format - case None => { - logWarning("Could not detect the format of the expected output. Assuming N-QUADS") - NQuads - } - } + val expOutForm = expectedOutputFormat.getOrElse(NQuads); val generatedModels: List[(Model, String)] = quadsToModels(generatedOutput, generatedOutputFormat) val expectedModels: List[(Model, String)] = quadsToModels(expectedOutput, expOutForm) if (generatedModels.length != expectedModels.length) { From 209e22482d67bdd1494113e74e8f87bca89741e9 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Wed, 6 Jan 2021 17:22:30 +0100 Subject: [PATCH 133/169] Use a cache with TriplesMaps to avoid duplicate generation of triples maps. This is useful in case of parent triples maps referring to each other. --- src/main/scala/io/rml/framework/Main.scala | 28 +++++------ .../io/rml/framework/api/RMLEnvironment.scala | 17 ++----- .../core/extractors/TriplesMapExtractor.scala | 2 +- .../core/extractors/TriplesMapsCache.scala} | 40 ++++++++-------- .../std/StdObjectMapExtractor.scala | 7 ++- .../std/StdTriplesMapExtractor.scala | 48 +++++++++++-------- .../core/model/JoinedTriplesMap.scala | 4 +- .../rml/framework/core/model/ObjectMap.scala | 4 +- .../rml/framework/core/model/RMLMapping.scala | 5 +- .../core/model/std/StdObjectMap.scala | 2 +- .../statement/ObjectGeneratorAssembler.scala | 3 +- .../statement/StatementsAssembler.scala | 5 +- .../rml/framework/OutputGenerationTest.scala | 3 -- .../scala/io/rml/framework/SandboxTests.scala | 8 +++- .../io/rml/framework/StreamTestSync.scala | 9 ++-- .../engine/StatementEngineTest.scala | 6 ++- .../framework/std/StdMappingReaderTest.scala | 5 ++ .../io/rml/framework/util/CommentFilter.scala | 2 +- .../util/fileprocessing/MappingTestUtil.scala | 7 +-- .../TripleGeneratorTestUtil.scala | 7 +-- .../rml/framework/util/server/TestSink2.scala | 2 +- 21 files changed, 109 insertions(+), 105 deletions(-) rename src/{test/scala/io/rml/framework/Test.scala => main/scala/io/rml/framework/core/extractors/TriplesMapsCache.scala} (51%) diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index caab8a9b..c6aaae57 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -26,11 +26,8 @@ package io.rml.framework **/ -import java.io.FileNotFoundException -import java.net.URLClassLoader -import java.util.Properties - import io.rml.framework.api.{FnOEnvironment, RMLEnvironment} +import io.rml.framework.core.extractors.TriplesMapsCache import io.rml.framework.core.function.flink.{FnOEnvironmentLoader, FnOEnvironmentStreamLoader, RichItemIdentityFunction, RichStreamItemIdentityFunction} import io.rml.framework.core.internal.Logging import io.rml.framework.core.model._ @@ -42,20 +39,16 @@ import io.rml.framework.flink.item.{Item, JoinedItem} import io.rml.framework.flink.source.{EmptyItem, FileDataSet, Source} import io.rml.framework.flink.util.ParameterUtil import io.rml.framework.flink.util.ParameterUtil.{OutputSinkOption, PostProcessorOption} -import org.apache.flink.api.common.functions.RichMapFunction import org.apache.flink.api.common.serialization.SimpleStringSchema import org.apache.flink.api.scala._ -import org.apache.flink.api.scala.typeutils.Types -import org.apache.flink.configuration.Configuration import org.apache.flink.core.fs.FileSystem.WriteMode import org.apache.flink.streaming.api.CheckpointingMode import org.apache.flink.streaming.api.functions.ProcessFunction import org.apache.flink.streaming.api.scala.{DataStream, OutputTag, StreamExecutionEnvironment} import org.apache.flink.util.Collector +import java.util.Properties import scala.collection.{immutable, mutable} -import scala.reflect.io.Path -import scala.util.{Failure, Success, Try} /** * @@ -252,7 +245,7 @@ object Main extends Logging { } - def createMixedPipelineFromFormattedMapping(formattedMapping: FormattedRMLMapping)(implicit env: ExecutionEnvironment, senv: StreamExecutionEnvironment, postProcessor: PostProcessor): DataStream[String] = { + private def createMixedPipelineFromFormattedMapping(formattedMapping: FormattedRMLMapping)(implicit env: ExecutionEnvironment, senv: StreamExecutionEnvironment, postProcessor: PostProcessor): DataStream[String] = { // we assume a streaming child triples map and a static parent triples map require(formattedMapping.containsStreamTriplesMaps() && formattedMapping.containsDatasetTriplesMaps() && formattedMapping.containsParentTriplesMaps) @@ -305,7 +298,7 @@ object Main extends Logging { val joinedStreamTm = triplesMap.asInstanceOf[JoinedTriplesMap] val engine = StatementEngine.fromJoinedTriplesMap(joinedStreamTm) - val parentTmId = joinedStreamTm.parentTriplesMap.identifier + val parentTmId = joinedStreamTm.parentTriplesMap val joinParentSource = joinedStreamTm.joinCondition.get.parent.identifier stream .flatMap(_.iterator) @@ -353,20 +346,20 @@ object Main extends Logging { unionStreams(processedDataStreams) } - def getStaticParentSourceItems(formattedMapping: FormattedRMLMapping)(implicit env: ExecutionEnvironment, senv: StreamExecutionEnvironment, postProcessor: PostProcessor) + private def getStaticParentSourceItems(formattedMapping: FormattedRMLMapping)(implicit env: ExecutionEnvironment, senv: StreamExecutionEnvironment, postProcessor: PostProcessor) : Map[(String, String, String), Item] = { // map: (parent triples map identiefier, name of the variable to join on, the value of it) => generated subject string var parentTriplesMapId2JoinParentSource2JoinParentValue2ParentItem = mutable.HashMap.empty[(String, String, String), Item] formattedMapping.joinedSteamTriplesMaps.foreach(joinedTm => { // identify the parent triples map - val parentTm = joinedTm.parentTriplesMap + val parentTm = TriplesMapsCache.get(joinedTm.parentTriplesMap).get; // find the parent source of the join condition val joinParentSource = joinedTm.joinCondition.get.parent.identifier // get the subjects from the static logical source - val parentDataset = Source(joinedTm.parentTriplesMap.logicalSource).asInstanceOf[FileDataSet].dataset + val parentDataset = Source(parentTm.logicalSource).asInstanceOf[FileDataSet].dataset parentDataset // only keep items where the parent source of the join condition is defined @@ -531,9 +524,10 @@ object Main extends Logging { }) + val parentTriplesMap = TriplesMapsCache.get(tm.parentTriplesMap).get; val parentDataset = // Create a Source from the parents logical source - Source(tm.parentTriplesMap.logicalSource).asInstanceOf[FileDataSet] + Source(parentTriplesMap.logicalSource).asInstanceOf[FileDataSet] .dataset // filter out all items that do not contain the parents join condition @@ -580,7 +574,9 @@ object Main extends Logging { // create a crossed data set val crossed = childDataset.cross(parentDataset) - crossed.map(items => JoinedItem(items._1, items._2)) // create a JoinedItem from the crossed items + crossed.map(items => + JoinedItem(items._1, items._2) + ) // create a JoinedItem from the crossed items .map(new JoinedStaticProcessor(engine)).name("Execute mapping statements on joined items") // process the joined items .flatMap(list => if (list.nonEmpty) Some(list.reduce((a, b) => a + "\n" + b)) else None) // format the triples .name("Convert joined triples to strings") diff --git a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala index fc6afaf3..153114f7 100644 --- a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala +++ b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala @@ -24,16 +24,10 @@ **/ package io.rml.framework.api -import java.io.File - -import io.rml.framework.core.extractors.MappingReader -import io.rml.framework.core.function.FunctionLoader -import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping, Uri} +import io.rml.framework.core.model.Uri import io.rml.framework.flink.item.Item -import scala.collection.mutable -import scala.collection.mutable.{MutableList, Map => MutableMap} -import scala.reflect.io.Path +import scala.collection.mutable.{Map => MutableMap} object RMLEnvironment { @@ -57,12 +51,7 @@ object RMLEnvironment { def getMappingFileBaseIRI(): Option[String] = { mappingFileBaseIRI } - - def loadMappingFromFile(path: String): RMLMapping = { - val file = new File(path) - FormattedRMLMapping.fromRMLMapping(MappingReader().read(file).asInstanceOf[RMLMapping]) - } - + def executeMapping(): Unit = ??? def executeTriplesMap(): Unit = ??? diff --git a/src/main/scala/io/rml/framework/core/extractors/TriplesMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/TriplesMapExtractor.scala index 342dafac..462f9d90 100644 --- a/src/main/scala/io/rml/framework/core/extractors/TriplesMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/TriplesMapExtractor.scala @@ -52,7 +52,7 @@ object TriplesMapExtractor { : TriplesMapExtractor = { - lazy val extractor = new StdTriplesMapExtractor() + lazy val extractor = StdTriplesMapExtractor extractor } diff --git a/src/test/scala/io/rml/framework/Test.scala b/src/main/scala/io/rml/framework/core/extractors/TriplesMapsCache.scala similarity index 51% rename from src/test/scala/io/rml/framework/Test.scala rename to src/main/scala/io/rml/framework/core/extractors/TriplesMapsCache.scala index 661da3af..8d6c3028 100644 --- a/src/test/scala/io/rml/framework/Test.scala +++ b/src/main/scala/io/rml/framework/core/extractors/TriplesMapsCache.scala @@ -1,3 +1,7 @@ +package io.rml.framework.core.extractors + +import io.rml.framework.core.model.TriplesMap + /** * MIT License * @@ -21,29 +25,23 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * - **/ -package io.rml.framework - -import java.io.File + * */ +object TriplesMapsCache { + private val triplesMaps = scala.collection.mutable.Map[String, TriplesMap](); -import io.rml.framework.core.extractors.MappingReader -import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping} -import io.rml.framework.engine.NopPostProcessor -import io.rml.framework.util.logging.Logger -import org.apache.flink.api.scala.ExecutionEnvironment -import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment + def put(resource: String, triplesMap: TriplesMap): Unit = { + triplesMaps.put(resource, triplesMap); + } -object Test extends App { + def get(resource: String): Option[TriplesMap] = { + triplesMaps.get(resource) + } - implicit val env = ExecutionEnvironment.getExecutionEnvironment - implicit val senv = StreamExecutionEnvironment.getExecutionEnvironment - implicit val postProcessor = new NopPostProcessor() - val classLoader = getClass.getClassLoader - val file = new File(classLoader.getResource("rml-testcases/RMLTC0007d-CSV/mapping.ttl").getFile) - val mapping = MappingReader().read(file) + def contains(resource: String): Boolean = { + triplesMaps.contains(resource) + } - val formattedMapping = FormattedRMLMapping.fromRMLMapping(mapping.asInstanceOf[RMLMapping]) - Logger.logInfo("" + formattedMapping.standardStaticTriplesMaps.size) - val result = Main.createDataSetFromFormattedMapping(formattedMapping).collect().reduce((a, b) => a + "\n" + b) - System.out.println(result) + def clear(): Unit = { + triplesMaps.clear(); + } } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala index 9425b428..d5416075 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala @@ -25,7 +25,7 @@ package io.rml.framework.core.extractors.std -import io.rml.framework.core.extractors.{FunctionMapExtractor, JoinConditionExtractor, ObjectMapExtractor, TriplesMapExtractor} +import io.rml.framework.core.extractors.{FunctionMapExtractor, JoinConditionExtractor, ObjectMapExtractor} import io.rml.framework.core.model._ import io.rml.framework.core.model.rdf.{RDFLiteral, RDFResource} import io.rml.framework.core.util.Util @@ -172,7 +172,7 @@ class StdObjectMapExtractor extends ObjectMapExtractor { languageLiteral } - private def extractParentTriplesMap(resource: RDFResource): Option[TriplesMap] = { + private def extractParentTriplesMap(resource: RDFResource): Option[String] = { val property = RMLVoc.Property.PARENTTRIPLESMAP val properties = resource.listProperties(property) @@ -182,8 +182,7 @@ class StdObjectMapExtractor extends ObjectMapExtractor { if (properties.isEmpty) return None properties.head match { - case resource: RDFResource => TriplesMapExtractor().extractTriplesMapProperties(resource) - .flatMap(tm => Some(ParentTriplesMap(tm))) // transform to PTM + case resource: RDFResource => Some(resource.toString) case literal: Literal => throw new RMLException(literal.toString + ": invalid parent triple map.") } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala index af2d9f1c..298fce3c 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdTriplesMapExtractor.scala @@ -25,7 +25,7 @@ package io.rml.framework.core.extractors.std -import io.rml.framework.core.extractors._ +import io.rml.framework.core.extractors.{TriplesMapsCache, _} import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.rdf.{RDFGraph, RDFResource} import io.rml.framework.core.model.{TriplesMap, Uri} @@ -35,7 +35,7 @@ import io.rml.framework.shared.RMLException /** * Extractor for extracting triple maps from a graph. */ -class StdTriplesMapExtractor extends TriplesMapExtractor with Logging { +object StdTriplesMapExtractor extends TriplesMapExtractor with Logging { /** @@ -56,7 +56,7 @@ class StdTriplesMapExtractor extends TriplesMapExtractor with Logging { val subjectConstantProperty = RMLVoc.Property.SUBJECT // trivial case - val isTriplesMap = resource.getType == Some(Uri(RMLVoc.Class.TRIPLESMAP)) + val isTriplesMap = resource.getType.equals(Some(Uri(RMLVoc.Class.TRIPLESMAP))) // property requirements for a triplesmap val hasExactlyOneLogicalSource = resource.listProperties(logicalSourceProperty).length==1 @@ -110,25 +110,31 @@ class StdTriplesMapExtractor extends TriplesMapExtractor with Logging { * @return */ def extractTriplesMapProperties(resource: RDFResource): Option[TriplesMap] = { + val resourceStr = resource.toString; // errors can occur during extraction of sub structures - try { - - // create a new triple map by extracting all sub structures - val triplesMap = TriplesMap(PredicateObjectMapExtractor().extract(resource), - LogicalSourceExtractor().extract(resource), - SubjectMapExtractor().extract(resource), - resource.uri.toString, - GraphMapExtractor().extract(resource) - ) - Some(triplesMap) - - } catch { - // in case of an error, skip this triple map and log warnings - case e: RMLException => - e.printStackTrace() - logWarning(e.getMessage) - logWarning(resource.uri + ": Skipping triple map.") - throw e + if (TriplesMapsCache.contains(resourceStr)) { + TriplesMapsCache.get(resourceStr) + } else { + try { + + // create a new triple map by extracting all sub structures + val triplesMap = TriplesMap(PredicateObjectMapExtractor().extract(resource), + LogicalSourceExtractor().extract(resource), + SubjectMapExtractor().extract(resource), + resource.uri.toString, + GraphMapExtractor().extract(resource) + ) + val t = TriplesMapsCache.put(resourceStr, triplesMap); + Some(triplesMap) + + } catch { + // in case of an error, skip this triple map and log warnings + case e: RMLException => + e.printStackTrace() + logWarning(e.getMessage) + logWarning(resource.uri + ": Skipping triple map.") + throw e + } } } diff --git a/src/main/scala/io/rml/framework/core/model/JoinedTriplesMap.scala b/src/main/scala/io/rml/framework/core/model/JoinedTriplesMap.scala index a9f66ba9..e8c21544 100644 --- a/src/main/scala/io/rml/framework/core/model/JoinedTriplesMap.scala +++ b/src/main/scala/io/rml/framework/core/model/JoinedTriplesMap.scala @@ -29,7 +29,7 @@ import io.rml.framework.shared.RMLException abstract class JoinedTriplesMap(triplesMap: TriplesMap) extends TriplesMap { - private val parentTriplesMaps: List[TriplesMap] = triplesMap.predicateObjectMaps.flatMap(pom => { + private val parentTriplesMaps: List[String] = triplesMap.predicateObjectMaps.flatMap(pom => { pom.objectMaps.flatMap(om => { om.parentTriplesMap }) @@ -50,7 +50,7 @@ abstract class JoinedTriplesMap(triplesMap: TriplesMap) extends TriplesMap { if (joinConditions.exists(_ != joinConditions.head)) throw new RMLException(triplesMap.identifier + ": Can only create JoinedTripleMap from triple map with one general join condition.") - val parentTriplesMap: TriplesMap = parentTriplesMaps.head + val parentTriplesMap: String = parentTriplesMaps.head val joinCondition: Option[JoinCondition] = joinConditions.headOption } diff --git a/src/main/scala/io/rml/framework/core/model/ObjectMap.scala b/src/main/scala/io/rml/framework/core/model/ObjectMap.scala index 6bc5726f..a98b9d2b 100644 --- a/src/main/scala/io/rml/framework/core/model/ObjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/ObjectMap.scala @@ -38,7 +38,7 @@ trait ObjectMap extends TermMap { def joinCondition: Option[JoinCondition] - def parentTriplesMap: Option[TriplesMap] + def parentTriplesMap: Option[String] } @@ -53,7 +53,7 @@ object ObjectMap { termType: Option[Uri] = None, datatype: Option[Uri] = None, language: Option[Literal] = None, - parentTriplesMap: Option[TriplesMap] = None, + parentTriplesMap: Option[String] = None, joinCondition: Option[JoinCondition] = None): ObjectMap = StdObjectMap(identifier, diff --git a/src/main/scala/io/rml/framework/core/model/RMLMapping.scala b/src/main/scala/io/rml/framework/core/model/RMLMapping.scala index 4d09f3ad..1c7858ab 100644 --- a/src/main/scala/io/rml/framework/core/model/RMLMapping.scala +++ b/src/main/scala/io/rml/framework/core/model/RMLMapping.scala @@ -24,6 +24,7 @@ **/ package io.rml.framework.core.model +import io.rml.framework.core.extractors.TriplesMapsCache import io.rml.framework.core.model.std.StdRMLMapping /** @@ -62,7 +63,9 @@ object RMLMapping { val parentTriplesMaps = tmWithParentTriplesMaps.flatMap(tm => tm.predicateObjectMaps.flatMap(pm => pm.objectMaps.flatMap(om => om.parentTriplesMap))) - val transformedPTM = parentTriplesMaps.map(ParentTriplesMap(_)) + val transformedPTM = parentTriplesMaps.map( + resource => ParentTriplesMap(TriplesMapsCache.get(resource).get) + ) // filter out all triple maps that are not parent triple maps themselves val nonPTMTriplesMaps = triplesMaps.filter(tm => !transformedPTM.contains(ParentTriplesMap(tm))) diff --git a/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala b/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala index ac27b4ca..7ca6fd4a 100644 --- a/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala +++ b/src/main/scala/io/rml/framework/core/model/std/StdObjectMap.scala @@ -34,5 +34,5 @@ case class StdObjectMap(identifier: String, termType: Option[Uri], override val datatype: Option[Uri], override val language: Option[Literal], - parentTriplesMap: Option[TriplesMap], + parentTriplesMap: Option[String], joinCondition: Option[JoinCondition]) extends ObjectMap diff --git a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala index 437d360a..e5751940 100644 --- a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala @@ -25,6 +25,7 @@ package io.rml.framework.engine.statement +import io.rml.framework.core.extractors.TriplesMapsCache import io.rml.framework.core.model.{Entity, Literal, ObjectMap, Uri} import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item @@ -35,7 +36,7 @@ class ObjectGeneratorAssembler extends TermMapGeneratorAssembler { // check if it has a parent triple map if (objectMap.parentTriplesMap.isDefined) { - super.assemble(objectMap.parentTriplesMap.get.subjectMap) + super.assemble(TriplesMapsCache.get(objectMap.parentTriplesMap.get).get.subjectMap) } else if (objectMap.hasFunctionMap) { val assembledFunction = FunctionMapGeneratorAssembler().assemble(objectMap.functionMap.head) val termTypeString = objectMap.termType.map(_.toString).getOrElse("") diff --git a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala index 0bb86252..33568837 100644 --- a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala @@ -25,10 +25,11 @@ package io.rml.framework.engine.statement +import io.rml.framework.core.extractors.TriplesMapsCache +import io.rml.framework.core.internal.Logging import io.rml.framework.core.model._ import io.rml.framework.core.vocabulary.RDFVoc import io.rml.framework.flink.item.{Item, JoinedItem} -import io.rml.framework.core.internal.Logging /** * Creates statements from triple maps. */ @@ -96,7 +97,7 @@ object StatementsAssembler { def assembleParentStatements(joinedTriplesMap: JoinedTriplesMap): List[Statement[JoinedItem]] = { val triples = new StatementsAssembler() - .assembleStatements(joinedTriplesMap.parentTriplesMap) + .assembleStatements(TriplesMapsCache.get(joinedTriplesMap.parentTriplesMap).get) triples.map(triple => ParentStatement(triple._1, triple._2, triple._3, triple._4)) } diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index baa91dbc..017c8110 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -24,10 +24,7 @@ **/ package io.rml.framework -import java.io.File - import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.FunctionLoader import io.rml.framework.engine.PostProcessor import io.rml.framework.util.TestUtil import io.rml.framework.util.fileprocessing.{ExpectedOutputTestUtil, TripleGeneratorTestUtil} diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index e254de47..1207039a 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -24,9 +24,8 @@ **/ package io.rml.framework -import java.io.File - import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.extractors.TriplesMapsCache import io.rml.framework.core.util.Util import io.rml.framework.engine.NopPostProcessor import io.rml.framework.util.TestUtil @@ -35,11 +34,14 @@ import org.apache.flink.api.scala.ExecutionEnvironment import org.apache.flink.streaming.api.scala._ import org.scalatest.{FunSuite, Matchers} +import java.io.File + class SandboxTests extends FunSuite with Matchers with FunctionMappingTest { private def executeTest(mappingFile: String): Unit = { + TriplesMapsCache.clear(); RMLEnvironment.setGeneratorBaseIRI(Some("http://example.org/base/")) implicit val env = ExecutionEnvironment.getExecutionEnvironment implicit val senv = StreamExecutionEnvironment.getExecutionEnvironment @@ -58,7 +60,9 @@ class SandboxTests extends FunSuite with Matchers with FunctionMappingTest { //val testDir = new File(mappingFile).getParentFile.getAbsoluteFile val (expectedOutput, expectedOutputFormat) = TestUtil.getExpectedOutputs(testDir) + val testOutcome = TestUtil.compareResults(s"StatementEngineTest: ${testDir}", result, expectedOutput, postProcessor.outputFormat, expectedOutputFormat) + testOutcome match { case Left(e) => { Logger.logError(e) diff --git a/src/test/scala/io/rml/framework/StreamTestSync.scala b/src/test/scala/io/rml/framework/StreamTestSync.scala index 4bfc12e5..23bc5e19 100644 --- a/src/test/scala/io/rml/framework/StreamTestSync.scala +++ b/src/test/scala/io/rml/framework/StreamTestSync.scala @@ -24,11 +24,8 @@ **/ package io.rml.framework -import java.io.File -import java.nio.file.{Path, Paths} -import java.util.concurrent.Executors - import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.extractors.TriplesMapsCache import io.rml.framework.core.internal.Logging import io.rml.framework.core.util.{StreamerConfig, Util} import io.rml.framework.engine.PostProcessor @@ -43,6 +40,9 @@ import org.apache.flink.runtime.jobgraph.JobGraph import org.apache.flink.runtime.minicluster.{MiniCluster, MiniClusterConfiguration} import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment} +import java.io.File +import java.nio.file.{Path, Paths} +import java.util.concurrent.Executors import scala.concurrent.{ExecutionContext, ExecutionContextExecutor} import scala.reflect.io.Directory @@ -104,6 +104,7 @@ abstract class StreamTestSync extends StaticTestSpec with ReadMappingBehaviour w // run the test cases for ((folderPath, postProcessorName) <- testCases) { + TriplesMapsCache.clear(); //it should s"produce triples equal to the expected triples for ${folderPath.getFileName}" in { Logger.lineBreak(50) diff --git a/src/test/scala/io/rml/framework/engine/StatementEngineTest.scala b/src/test/scala/io/rml/framework/engine/StatementEngineTest.scala index 6aa89c4c..c005cad8 100644 --- a/src/test/scala/io/rml/framework/engine/StatementEngineTest.scala +++ b/src/test/scala/io/rml/framework/engine/StatementEngineTest.scala @@ -24,10 +24,9 @@ **/ package io.rml.framework.engine -import java.io.File - import io.rml.framework.Main import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.extractors.TriplesMapsCache import io.rml.framework.core.util.Util import io.rml.framework.util.TestUtil import io.rml.framework.util.logging.Logger @@ -35,9 +34,12 @@ import org.apache.flink.api.scala.ExecutionEnvironment import org.apache.flink.streaming.api.scala._ import org.scalatest.{FunSuite, Matchers} +import java.io.File + class StatementEngineTest extends FunSuite with Matchers { private def executeTest(mappingFile: String): Unit = { + TriplesMapsCache.clear(); RMLEnvironment.setGeneratorBaseIRI(Some("http://example.org/base/")) implicit val env = ExecutionEnvironment.getExecutionEnvironment implicit val senv = StreamExecutionEnvironment.getExecutionEnvironment diff --git a/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala b/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala index 241182ab..15d98f5c 100644 --- a/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala +++ b/src/test/scala/io/rml/framework/std/StdMappingReaderTest.scala @@ -26,6 +26,7 @@ package io.rml.framework.std import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.extractors.TriplesMapsCache import io.rml.framework.core.internal.Logging import io.rml.framework.core.util.Util import org.scalatest.{BeforeAndAfter, FunSuite, Matchers} @@ -36,6 +37,7 @@ class StdMappingReaderTest extends FunSuite with Matchers with BeforeAndAfter with Logging { + // TODO: There are no assetions in the tests?? after { // clean up @@ -49,6 +51,7 @@ class StdMappingReaderTest extends FunSuite with Matchers * │   └── student.csv */ test("relative paths: scenario01"){ + TriplesMapsCache.clear(); val mappingFile = "relative_paths/scenario01/RMLTC0001a-CSV/mapping.ttl" // determine the base IRI of the mapping file RMLEnvironment.setMappingFileBaseIRI(Some((mappingFile))) @@ -64,6 +67,7 @@ class StdMappingReaderTest extends FunSuite with Matchers * │   └── student.csv */ test("relative paths: scenario02"){ + TriplesMapsCache.clear(); val mappingFile = "relative_paths/scenario02/RMLTC0001a-CSV/mapping.ttl" // determine the base IRI of the mapping file RMLEnvironment.setMappingFileBaseIRI(Some((mappingFile))) @@ -79,6 +83,7 @@ class StdMappingReaderTest extends FunSuite with Matchers * └── output.ttl */ test("relative paths: scenario03"){ + TriplesMapsCache.clear(); val mappingFile = "relative_paths/scenario03/RMLTC0001a-CSV/mapping.ttl" // determine the base IRI of the mapping file RMLEnvironment.setMappingFileBaseIRI(Some((mappingFile))) diff --git a/src/test/scala/io/rml/framework/util/CommentFilter.scala b/src/test/scala/io/rml/framework/util/CommentFilter.scala index 5871043c..212d5e0a 100644 --- a/src/test/scala/io/rml/framework/util/CommentFilter.scala +++ b/src/test/scala/io/rml/framework/util/CommentFilter.scala @@ -28,6 +28,6 @@ class CommentFilter extends Filter[String] { val filterChars = Set('#') override def check(line: String): Boolean = { - line.trim.length > 0 && !filterChars.contains(line.trim.charAt(0)) + line.trim.nonEmpty && !filterChars.contains(line.trim.charAt(0)) } } diff --git a/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala b/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala index 5accc5cf..75033fa4 100644 --- a/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala +++ b/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala @@ -24,11 +24,11 @@ **/ package io.rml.framework.util.fileprocessing -import java.io.File - -import io.rml.framework.core.extractors.MappingReader +import io.rml.framework.core.extractors.{MappingReader, TriplesMapsCache} import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping} +import java.io.File + /** * Test helper to read the mapping file and generate a FormattedRMLMapping */ @@ -37,6 +37,7 @@ object MappingTestUtil extends FileProcessingUtil[FormattedRMLMapping] { override def processFile(file: File): FormattedRMLMapping = { + TriplesMapsCache.clear(); val mapping = MappingReader().read(file) FormattedRMLMapping.fromRMLMapping(mapping.asInstanceOf[RMLMapping]) } diff --git a/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala b/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala index 05104c51..1dd6b993 100644 --- a/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala +++ b/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala @@ -24,10 +24,8 @@ **/ package io.rml.framework.util.fileprocessing -import java.io.File - import io.rml.framework.Main -import io.rml.framework.core.extractors.MappingReader +import io.rml.framework.core.extractors.{MappingReader, TriplesMapsCache} import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping} import io.rml.framework.core.util.{Format, NQuads} import io.rml.framework.engine.{NopPostProcessor, PostProcessor} @@ -35,6 +33,8 @@ import io.rml.framework.util.logging.Logger import org.apache.flink.api.scala.ExecutionEnvironment import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment +import java.io.File + /** * Test helper to get generated triples after processing the mapping file * containing triple maps. @@ -66,6 +66,7 @@ object TripleGeneratorTestUtil extends TestFilesUtil[(List[String], Format)] { */ def processFile(file: File): (List[String], Format) = { try { + TriplesMapsCache.clear(); val mapping = MappingReader().read(file) val formattedMapping = FormattedRMLMapping.fromRMLMapping(mapping.asInstanceOf[RMLMapping]) diff --git a/src/test/scala/io/rml/framework/util/server/TestSink2.scala b/src/test/scala/io/rml/framework/util/server/TestSink2.scala index 59dcc1d3..191f4165 100644 --- a/src/test/scala/io/rml/framework/util/server/TestSink2.scala +++ b/src/test/scala/io/rml/framework/util/server/TestSink2.scala @@ -49,7 +49,7 @@ class TestSink2 extends SinkFunction[String] { override def invoke(value: String, context: SinkFunction.Context[_]): Unit = { Logger.logInfo(s"TestSink2: got value [${value}]") - if (!value.trim.isEmpty) { + if (value.trim.nonEmpty) { triples = value :: triples } } From 3d1744f80a4a0255a84f38068ced2127d7843e37 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Wed, 6 Jan 2021 19:13:33 +0100 Subject: [PATCH 134/169] All triples maps should be applied. Fixes #108 and fixes https://github.com/RMLio/RMLStreamer/issues/19 . --- src/main/resources/log4j.properties | 9 ++++++++- .../io/rml/framework/core/model/RMLMapping.scala | 15 +-------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties index 20495214..dace706e 100644 --- a/src/main/resources/log4j.properties +++ b/src/main/resources/log4j.properties @@ -1,5 +1,12 @@ -log4j.rootLogger=INFO, console +log4j.rootLogger=WARN, console +log4j.logger.io.rml=DEBUG +log4j.logger.org.apache.flink=WARN +log4j.logger.kafka=ERROR +log4j.logger.org.I0Itec.zkclient=ERROR +log4j.logger.org.apache.kafka=ERROR +log4j.logger.org.apache.zookeeper=ERROR +log4j.logger.org.apache.curator=ERROR log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout diff --git a/src/main/scala/io/rml/framework/core/model/RMLMapping.scala b/src/main/scala/io/rml/framework/core/model/RMLMapping.scala index 1c7858ab..6cea5c68 100644 --- a/src/main/scala/io/rml/framework/core/model/RMLMapping.scala +++ b/src/main/scala/io/rml/framework/core/model/RMLMapping.scala @@ -24,7 +24,6 @@ **/ package io.rml.framework.core.model -import io.rml.framework.core.extractors.TriplesMapsCache import io.rml.framework.core.model.std.StdRMLMapping /** @@ -58,19 +57,7 @@ object RMLMapping { * @return */ def apply(triplesMaps: List[TriplesMap], identifier: String): RMLMapping = { - // separating triple maps that contain parent triple maps - val tmWithParentTriplesMaps = triplesMaps.filter(tm => tm.containsParentTriplesMap) - val parentTriplesMaps = tmWithParentTriplesMaps.flatMap(tm => - tm.predicateObjectMaps.flatMap(pm => - pm.objectMaps.flatMap(om => om.parentTriplesMap))) - val transformedPTM = parentTriplesMaps.map( - resource => ParentTriplesMap(TriplesMapsCache.get(resource).get) - ) - - // filter out all triple maps that are not parent triple maps themselves - val nonPTMTriplesMaps = triplesMaps.filter(tm => !transformedPTM.contains(ParentTriplesMap(tm))) - - StdRMLMapping(nonPTMTriplesMaps, identifier) + StdRMLMapping(triplesMaps, identifier) } } From ae8a9f4a3d6d28bf1b56ff2d78aa62f27dae6fde Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Wed, 6 Jan 2021 19:15:09 +0100 Subject: [PATCH 135/169] All triples maps should be applied. Fixes #108 and fixes https://github.com/RMLio/RMLStreamer/issues/19 . --- .../head.csv | 3 + .../mapping.ttl | 119 ++++++++++++++++++ .../output.ttl | 58 +++++++++ 3 files changed, 180 insertions(+) create mode 100644 src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/head.csv create mode 100644 src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/mapping.ttl create mode 100644 src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/output.ttl diff --git a/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/head.csv b/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/head.csv new file mode 100644 index 00000000..8ba04cce --- /dev/null +++ b/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/head.csv @@ -0,0 +1,3 @@ +fragment_id_mam,mediaobject_id_mam,cp,cp_id,sp_id,sp_name,pid,dc_description,dc_format,dc_publisher,dc_source,dc_terms,dc_title,dcterms_abstract,dcterms_created,dcterms_issued +f_id_mam_1,m_id_mam_1,cp1,cp_id1,sp_id1,sp_name1,pid1,dc_description1,dc_format1,dc_publisher1,dc_source1,dc_terms1,dc_title1,dcterms_abstract1,dcterms_created1,dcterms_issued1 +f_id_mam_2,m_id_mam_2,cp2,cp_id2,sp_id2,sp_name2,pid2,dc_description2,dc_format2,dc_publisher2,dc_source2,dc_terms2,dc_title2,dcterms_abstract2,dcterms_created2,dcterms_issued2 diff --git a/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/mapping.ttl b/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/mapping.ttl new file mode 100644 index 00000000..eb2a26f0 --- /dev/null +++ b/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/mapping.ttl @@ -0,0 +1,119 @@ +@prefix map: . +@prefix rml: . + @prefix ql: . +@prefix rr: . +@prefix vcard: . +@prefix rdfs: . +@prefix skos: . +@prefix dcterms: . +@prefix dc: . +@prefix conf: . +@prefix foaf: . +@prefix rdf: . +@prefix xsd: . + +@prefix edtf: . +@prefix meemoo: . + +map:FragmentMetadata rml:source "bugs/108_stackoverflow_when_reading_mapping_github_19/head.csv"; + rml:referenceFormulation ql:CSV. + +map:Fragment a rr:TriplesMap; + rml:logicalSource map:FragmentMetadata; + rr:subjectMap [ + rr:template "http://data.meemoo.be/fm/{fragment_id_mam}"; + rr:class meemoo:Fragment; + ]; + rr:predicateObjectMap [ + rr:predicate meemoo:hasContentpartner; + rr:objectMap [ rr:parentTriplesMap map:Contentpartner ]; + ]; + rr:predicateObjectMap [ + rr:predicate meemoo:hasServiceprovider; + rr:objectMap [ rr:parentTriplesMap map:Serviceprovider ]; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:isPartOf; + rr:objectMap [ rr:parentTriplesMap map:MediaObject ]; + ]. + +map:MediaObject a rr:TriplesMap; + rml:logicalSource map:FragmentMetadata; + rr:subjectMap [ + rr:template "http://data.meemoo.be/mo/{mediaobject_id_mam}"; + rr:class meemoo:MediaObject; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:hasPart; + rr:objectMap [ rr:parentTriplesMap map:Fragment ]; + ]. + +map:Contentpartner a rr:TriplesMap; + rml:logicalSource map:FragmentMetadata; + rr:subjectMap [ + rr:template "http://data.meemoo.be/cp/{cp_id}"; + rr:class meemoo:Contentpartner; + ]; + rr:predicateObjectMap [ + rr:predicate rdfs:label; + rr:objectMap [ rml:reference "cp" ]; + ]; + rr:predicateObjectMap [ + rr:predicate dc:identifier; + rr:objectMap [ rml:reference "cp_id" ]; + ]. + + +map:Serviceprovider a rr:TriplesMap; + rml:logicalSource map:FragmentMetadata; + rr:subjectMap [ + rr:template "http://data.meemoo.be/sp/{sp_id}"; + rr:class meemoo:Serviceprovider; + ]; + rr:predicateObjectMap [ + rr:predicate rdfs:label; + rr:objectMap [ rml:reference "sp_name" ]; + ]; + rr:predicateObjectMap [ + rr:predicate dc:identifier; + rr:objectMap [ rml:reference "sp_id" ]; + ]. + +map:IntellectualEntity a rr:TriplesMap; + rml:logicalSource map:FragmentMetadata; + rr:subjectMap [ + rr:template "http://data.meemoo.be/ie/{pid}"; + rr:class meemoo:IntellectualEntity; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:title; + rr:objectMap [ rml:reference "dc_title" ]; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:abstract; + rr:objectMap [ rml:reference "dcterms_abstract" ]; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:created; + rr:objectMap [ rml:reference "dcterms_created" ]; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:issued; + rr:objectMap [ rml:reference "dcterms_issued" ]; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:description; + rr:objectMap [ rml:reference "dc_description" ]; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:publisher; + rr:objectMap [ rml:reference "dc_publisher" ]; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:source; + rr:objectMap [ rml:reference "dc_source" ]; + ]; + rr:predicateObjectMap [ + rr:predicate dcterms:date; + rr:objectMap [ rml:reference "dc_terms"; rr:datatype edtf:EDTF ]; + ]. diff --git a/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/output.ttl b/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/output.ttl new file mode 100644 index 00000000..5dfa51cf --- /dev/null +++ b/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/output.ttl @@ -0,0 +1,58 @@ +@prefix dc: . +@prefix dcterms: . +@prefix meemoo: . +@prefix rdf: . +@prefix rdfs: . +@prefix xsd: . + + a meemoo:Contentpartner; + dc:identifier "cp_id1"; + rdfs:label "cp1" . + + a meemoo:Contentpartner; + dc:identifier "cp_id2"; + rdfs:label "cp2" . + + a meemoo:Fragment; + meemoo:hasContentpartner , ; + meemoo:hasServiceprovider , ; + dcterms:isPartOf , . + + a meemoo:Fragment; + meemoo:hasContentpartner , ; + meemoo:hasServiceprovider , ; + dcterms:isPartOf , . + + a meemoo:IntellectualEntity; + dcterms:abstract "dcterms_abstract1"; + dcterms:created "dcterms_created1"; + dcterms:date "dc_terms1"^^; + dcterms:description "dc_description1"; + dcterms:issued "dcterms_issued1"; + dcterms:publisher "dc_publisher1"; + dcterms:source "dc_source1"; + dcterms:title "dc_title1" . + + a meemoo:IntellectualEntity; + dcterms:abstract "dcterms_abstract2"; + dcterms:created "dcterms_created2"; + dcterms:date "dc_terms2"^^; + dcterms:description "dc_description2"; + dcterms:issued "dcterms_issued2"; + dcterms:publisher "dc_publisher2"; + dcterms:source "dc_source2"; + dcterms:title "dc_title2" . + + a meemoo:MediaObject; + dcterms:hasPart , . + + a meemoo:MediaObject; + dcterms:hasPart , . + + a meemoo:Serviceprovider; + dc:identifier "sp_id1"; + rdfs:label "sp_name1" . + + a meemoo:Serviceprovider; + dc:identifier "sp_id2"; + rdfs:label "sp_name2" . From 1468d517e0e8f252fef2121eeeb8032764039fe7 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 7 Jan 2021 09:20:07 +0100 Subject: [PATCH 136/169] Simplified TriplesMapsCache --- .../core/extractors/TriplesMapsCache.scala | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/extractors/TriplesMapsCache.scala b/src/main/scala/io/rml/framework/core/extractors/TriplesMapsCache.scala index 8d6c3028..362cb292 100644 --- a/src/main/scala/io/rml/framework/core/extractors/TriplesMapsCache.scala +++ b/src/main/scala/io/rml/framework/core/extractors/TriplesMapsCache.scala @@ -26,22 +26,4 @@ import io.rml.framework.core.model.TriplesMap * THE SOFTWARE. * * */ -object TriplesMapsCache { - private val triplesMaps = scala.collection.mutable.Map[String, TriplesMap](); - - def put(resource: String, triplesMap: TriplesMap): Unit = { - triplesMaps.put(resource, triplesMap); - } - - def get(resource: String): Option[TriplesMap] = { - triplesMaps.get(resource) - } - - def contains(resource: String): Boolean = { - triplesMaps.contains(resource) - } - - def clear(): Unit = { - triplesMaps.clear(); - } -} +object TriplesMapsCache extends scala.collection.mutable.HashMap[String, TriplesMap] From 0c9fb80dc20711835fc883f8119fdb205b156113 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 7 Jan 2021 09:40:47 +0100 Subject: [PATCH 137/169] Updated the CHANGELOG --- CHANGELOG.md | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7416e732..99404363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,22 +9,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Function mapping. * Joins of data streams -* Updated Flink from version 1.10.1 to 1.11.2 -* Updated Kafka from version 2.2.2 to 2.4.2 - +## [2.0.1] - ### Changed -* Updated Flink from version 1.10.0 to 1.10.1 +* Updated Flink from version 1.10.0 to 1.11.2 +* Updated Kafka version from version 2.2.2 to 2.4.1 (more versions supported using the universal connector) ### Fixed -* Escape characters were not escaped in generated literals (Internal [issue #81](https://gitlab.ilabt.imec.be/rml/proc/rml-streamer/issues/81)). -* Curly brackets were not escaped correctly (Internal [issue #65](https://gitlab.ilabt.imec.be/rml/proc/rml-streamer/-/issues/65)). - -## [1.2.3] - 2020-03-16 - -### Changed -* Updated documentation +* Cyclic reference of parent triples maps leads to a stack overflow error (GitHub [issue #19](https://github.com/RMLio/RMLStreamer/issues/19), Internal [issue #108](https://gitlab.ilabt.imec.be/rml/proc/rml-streamer/-/issues/108)) +* In some cases not all triples maps were applied when joins (static-static and static-streams) are involved (fixed together with issue above). ## [2.0.0] - 2020-06-08 From 10d7099e3c6f5d79fe0421fdd3f47aa989d9455c Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 7 Jan 2021 10:00:01 +0100 Subject: [PATCH 138/169] Remove unused code --- .../io/rml/framework/api/RMLEnvironment.scala | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala index 153114f7..dc19a5b6 100644 --- a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala +++ b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala @@ -24,15 +24,7 @@ **/ package io.rml.framework.api -import io.rml.framework.core.model.Uri -import io.rml.framework.flink.item.Item - -import scala.collection.mutable.{Map => MutableMap} - object RMLEnvironment { - - - private val sources: MutableMap[Uri, Iterable[Item]] = MutableMap() private var generatorBaseIRI: Option[String] = None private var mappingFileBaseIRI: Option[String] = None @@ -51,24 +43,4 @@ object RMLEnvironment { def getMappingFileBaseIRI(): Option[String] = { mappingFileBaseIRI } - - def executeMapping(): Unit = ??? - - def executeTriplesMap(): Unit = ??? - - - def registerSource(uri: Uri, iterable: Iterable[Item]): Unit = { - require(sources.isEmpty, "Processing of only one source supported in API mode.") - sources.put(uri, iterable) - } - - - def getSource(uri: Uri): Option[Iterable[Item]] = { - sources.get(uri) - } - - def reset(): Unit = { - sources.clear() - } - } From d4d3a69978971f215b9021bc721baa4aa83c35cf Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Tue, 12 Jan 2021 12:38:36 +0100 Subject: [PATCH 139/169] * Only support Java 11, not 8 anymore; * Disable TCP PUSH code until stable alternative; --- .gitlab-ci.yml | 13 +----- CHANGELOG.md | 4 ++ pom.xml | 44 +++++++++---------- .../framework/flink/source/StreamUtil.scala | 4 +- 4 files changed, 30 insertions(+), 35 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1bae6359..79017429 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,22 +42,13 @@ cache: script: - 'mvn $MAVEN_CLI_OPTS test' -# Build merge requests using JDK8 -build:jdk8: - <<: *build - image: maven:3-jdk-8 - -# Test merge requests using JDK8 -test:jdk8: - <<: *test - image: maven:3-jdk-8 # Build merge requests using JDK12 build:jdk12: <<: *build - image: maven:3-jdk-12 + image: maven:3-jdk-11 # Test merge requests using JDK12 test:jdk12: <<: *test - image: maven:3-jdk-12 + image: maven:3-jdk-11 diff --git a/CHANGELOG.md b/CHANGELOG.md index 99404363..66cba4f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Updated Flink from version 1.10.0 to 1.11.2 * Updated Kafka version from version 2.2.2 to 2.4.1 (more versions supported using the universal connector) +### Removed +* Drop support for Java 8, only Java 11 supported. +* TCP PUSH support disabled: this code relies on development version of Apache Bahir. + ### Fixed * Cyclic reference of parent triples maps leads to a stack overflow error (GitHub [issue #19](https://github.com/RMLio/RMLStreamer/issues/19), Internal [issue #108](https://gitlab.ilabt.imec.be/rml/proc/rml-streamer/-/issues/108)) * In some cases not all triples maps were applied when joins (static-static and static-streams) are involved (fixed together with issue above). diff --git a/pom.xml b/pom.xml index 3b4e4b99..58ffd4f0 100644 --- a/pom.xml +++ b/pom.xml @@ -52,12 +52,12 @@ SOFTWARE. mit - + - - org.apache.commons - commons-lang3 - - - + + + + + + + + + + + + + + + + + + + + com.ximpleware diff --git a/src/main/scala/io/rml/framework/flink/source/StreamUtil.scala b/src/main/scala/io/rml/framework/flink/source/StreamUtil.scala index 78c56012..990945ed 100644 --- a/src/main/scala/io/rml/framework/flink/source/StreamUtil.scala +++ b/src/main/scala/io/rml/framework/flink/source/StreamUtil.scala @@ -29,7 +29,7 @@ import io.rml.framework.core.model.TCPSocketStream import io.rml.framework.core.util.StreamerConfig import org.apache.flink.api.scala._ import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment} -import org.apache.flink.streaming.connectors.netty.example.TcpReceiverSource +//import org.apache.flink.streaming.connectors.netty.example.TcpReceiverSource object StreamUtil { @@ -45,7 +45,7 @@ object StreamUtil { case TCPSocketStream.TYPE.PULL => new DataStream[String](env.getJavaEnv.socketTextStream(tCPSocketStream.hostName, tCPSocketStream.port, delimiter)) - case TCPSocketStream.TYPE.PUSH => env.addSource(new TcpReceiverSource(tCPSocketStream.port)).setParallelism(1) // to avoid library to setup multiple instances + //case TCPSocketStream.TYPE.PUSH => env.addSource(new TcpReceiverSource(tCPSocketStream.port)).setParallelism(1) // to avoid library to setup multiple instances } } From 7c8db235472f9ef41fd0c3ac0b4aef7d443c4531 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Tue, 12 Jan 2021 12:41:19 +0100 Subject: [PATCH 140/169] Typo --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 79017429..f07556b3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,11 +44,11 @@ cache: # Build merge requests using JDK12 -build:jdk12: +build:jdk11: <<: *build image: maven:3-jdk-11 # Test merge requests using JDK12 -test:jdk12: +test:jdk11: <<: *test image: maven:3-jdk-11 From da547d7e7f9453471e648a7c096c1522884fcd64 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Sat, 23 Jan 2021 23:23:15 +0100 Subject: [PATCH 141/169] Update Flink to 1.11.3. Closes #119 --- CHANGELOG.md | 2 +- README.md | 4 ++-- docker/docker-compose.yml | 4 ++-- pom.xml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66cba4f5..2d1acd20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [2.0.1] - ### Changed -* Updated Flink from version 1.10.0 to 1.11.2 +* Updated Flink from version 1.10.0 to 1.11.3 * Updated Kafka version from version 2.2.2 to 2.4.1 (more versions supported using the universal connector) ### Removed diff --git a/README.md b/README.md index f92b05b9..5efdd362 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ If you want to deploy it yourself, read on. ### Installing Flink RMLStreamer runs its jobs on Flink clusters. -More information on how to install Flink and getting started can be found [here](https://ci.apache.org/projects/flink/flink-docs-release-1.10/getting-started/tutorials/local_setup.html). +More information on how to install Flink and getting started can be found [here](https://ci.apache.org/projects/flink/flink-docs-release-1.11/try-flink/local_installation.html). At least a local cluster must be running in order to start executing RML Mappings with RMLStreamer. -Please note that this version works with Flink 1.11.2 with Scala 2.11 support, which can be downloaded [here](https://www.apache.org/dyn/closer.lua/flink/flink-1.11.2/flink-1.11.2-bin-scala_2.11.tgz). +Please note that this version works with Flink 1.11.3 with Scala 2.11 support, which can be downloaded [here](https://archive.apache.org/dist/flink/flink-1.11.3/flink-1.11.3-bin-scala_2.11.tgz). ### Building RMLStreamer diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 7eae11e4..fb61a26c 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: jobmanager: - image: flink:1.11.2-scala_2.11 + image: flink:1.11.3-scala_2.11 expose: - "6123" ports: @@ -14,7 +14,7 @@ services: - data:/mnt/data taskmanager: - image: flink:1.11.2-scala_2.11 + image: flink:1.11.3-scala_2.11 expose: - "6121" - "6122" diff --git a/pom.xml b/pom.xml index 58ffd4f0..820dce51 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ SOFTWARE. UTF-8 - 1.11.2 + 1.11.3 1.7.26 2.13.3 3.11.0 From 84128c559e0fb78759817a2c400286f93bde5274 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Tue, 2 Feb 2021 16:18:12 +0100 Subject: [PATCH 142/169] One step closer to fixing issue #105 : now functions are just ignored if the ttl and jar files are not in place. --- ...{functions.ttl => __________functions.ttl} | 0 .../io/rml/framework/api/FnOEnvironment.scala | 20 +++++++++--- .../core/function/FunctionLoader.scala | 16 ++++------ .../io/rml/framework/core/util/Util.scala | 17 +++++----- .../FunctionMapGeneratorAssembler.scala | 31 ++++++++++--------- 5 files changed, 46 insertions(+), 38 deletions(-) rename src/main/resources/{functions.ttl => __________functions.ttl} (100%) diff --git a/src/main/resources/functions.ttl b/src/main/resources/__________functions.ttl similarity index 100% rename from src/main/resources/functions.ttl rename to src/main/resources/__________functions.ttl diff --git a/src/main/scala/io/rml/framework/api/FnOEnvironment.scala b/src/main/scala/io/rml/framework/api/FnOEnvironment.scala index 34b00cab..26409ac7 100644 --- a/src/main/scala/io/rml/framework/api/FnOEnvironment.scala +++ b/src/main/scala/io/rml/framework/api/FnOEnvironment.scala @@ -28,7 +28,7 @@ object FnOEnvironment extends Logging{ } def intializeFunctionLoader() = { - this.functionLoader = Some(FunctionLoader.apply(getFunctionDescriptionFilePaths(), getFunctionMappingFilePaths())) + this.functionLoader = FunctionLoader.apply(getFunctionDescriptionFilePaths(), getFunctionMappingFilePaths()) this.functionLoader } def getFunctionLoader: Option[FunctionLoader] = { @@ -63,8 +63,13 @@ object FnOEnvironment extends Logging{ defaultFunctionDescriptionFilePaths.foreach(strPath=> { try { - val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) - FnOEnvironment.addFunctionDescriptionFilePath(p) + val file = Util.getFile(strPath); + if (file.exists()) { + val p = Path.string2path(file.getAbsolutePath) + FnOEnvironment.addFunctionDescriptionFilePath(p) + } else { + logWarning(s"Can't add function description file to RMLEnvironment ( $strPath ). This will result in errors when using functions!"); + } } catch { case e : Exception => logWarning(s"Can't add function description file to RMLEnvironment ( $strPath ). This will result in errors when using functions! Exception: ${e.getMessage}") @@ -74,8 +79,13 @@ object FnOEnvironment extends Logging{ // adding default function description file paths to the RMLEnvironment defaultFunctionMappingFilePaths.foreach(strPath=> { try { - val p = Path.string2path(Util.getFile(strPath).getAbsolutePath) - FnOEnvironment.addFunctionMappingFilePaths(p) + val file = Util.getFile(strPath); + if (file.exists()) { + val p = Path.string2path(file.getAbsolutePath) + FnOEnvironment.addFunctionMappingFilePaths(p) + } else { + logWarning(s"Can't add function mapping file to RMLEnvironment ( $strPath ). This will result in errors when using functions!"); + } }catch { case e : Exception => logWarning(s"Can't add function mapping file to RMLEnvironment ( $strPath ). This will result in errors when using functions! Exception: ${e.getMessage}") } diff --git a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index 601a9a64..af4f4eaf 100644 --- a/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -1,7 +1,5 @@ package io.rml.framework.core.function -import java.io.{File, IOException} - import io.rml.framework.api.{FnOEnvironment, RMLEnvironment} import io.rml.framework.core.function.model.{Function, FunctionMetaData, Parameter} import io.rml.framework.core.function.std.StdFunctionLoader @@ -10,6 +8,7 @@ import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode} import io.rml.framework.core.util.Turtle +import java.io.{File, IOException} import scala.collection.mutable.{Map => MutableMap} import scala.reflect.io.Path @@ -101,7 +100,7 @@ object FunctionLoader extends Logging{ */ def apply(functionDescriptionPaths : List[Path] = FnOEnvironment.getFunctionDescriptionFilePaths(), functionMappingPaths : List[Path] = FnOEnvironment.getFunctionMappingFilePaths() - ): FunctionLoader = { + ): Option[FunctionLoader] = { if(singletonFunctionLoader.isEmpty) { // The functionDescriptionsGraph is populated by iterating over the filepaths of the function description files. @@ -127,16 +126,13 @@ object FunctionLoader extends Logging{ // now parse the mappings functionMappingPaths.foreach(fmp=>singletonFunctionLoader.get.parseFunctionMapping(new File(fmp.path))) + } else { + logWarning("No function graph found. Continuing without loading functions.") + None } - else - throw new Exception("Function description graph is none...") } - singletonFunctionLoader.get + singletonFunctionLoader } - - - - } diff --git a/src/main/scala/io/rml/framework/core/util/Util.scala b/src/main/scala/io/rml/framework/core/util/Util.scala index 6dd8c09f..bfbc6337 100644 --- a/src/main/scala/io/rml/framework/core/util/Util.scala +++ b/src/main/scala/io/rml/framework/core/util/Util.scala @@ -24,17 +24,16 @@ **/ package io.rml.framework.core.util -import java.io.{ByteArrayInputStream, File, FileInputStream, FileNotFoundException, InputStream} -import java.net.URI -import java.nio.charset.StandardCharsets -import java.nio.file.{Files, Paths} -import java.util.regex.Pattern - import io.rml.framework.core.extractors.MappingReader +import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.{FormattedRMLMapping, Literal, Node, RMLMapping} import io.rml.framework.shared.ReadException -import io.rml.framework.core.internal.Logging +import java.io._ +import java.net.URI +import java.nio.charset.StandardCharsets +import java.nio.file.{Files, Paths} +import java.util.regex.Pattern import scala.collection.mutable.ListBuffer import scala.io.Source import scala.util.{Failure, Success, Try} @@ -223,12 +222,12 @@ object Util extends Logging{ val out = Try(getFileUsingClassLoader(path)) match { case Success(file) => Some(file) case Failure(exception) => { - logError("can't find file use class loader") + logWarning(s"can't find file $path using class loader") // Try to find the file relative to the user directory Try(getFileRelativeToUserDir(path)) match { case Success(file) => Some(file) case Failure(exception) => { - logError(s"can't find file relative to user dir") + logWarning(s"can't find file $path relative to user dir") None } } diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index cd19579f..af021dc5 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -24,15 +24,12 @@ **/ package io.rml.framework.engine.statement -import java.io.File - -import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.{FunctionLoader, ReflectionUtils} -import io.rml.framework.core.function.model.{DynamicFunction, Function} +import io.rml.framework.core.function.FunctionLoader +import io.rml.framework.core.function.model.Function import io.rml.framework.core.model._ import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item -import io.rml.framework.flink.sink.{FlinkRDFNode, FlinkRDFQuad} +import io.rml.framework.flink.sink.FlinkRDFQuad import io.rml.framework.flink.source.EmptyItem import io.rml.framework.shared.RMLException @@ -57,7 +54,7 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { } private def parseFunction(assembledPom: - List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Function = { + List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Option[Function] = { this.logDebug("parseFunction (assembledPom)") val placeHolder: List[FlinkRDFQuad] = generateFunctionTriples(new EmptyItem(), assembledPom) @@ -74,10 +71,13 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { .value .toString) - val loadedFunctionOption = FunctionLoader().createFunction(functionName) - loadedFunctionOption.getOrElse{ - // complain about function that isn't present - throw new RMLException("Can't load function..") + + val functionLoaderOption = FunctionLoader(); + + if (functionLoaderOption.isDefined) { + functionLoaderOption.get.createFunction(functionName); + } else { + None } } @@ -88,14 +88,17 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { * @param assembledPom List of predicate object generator functions * @return anon function taking in [[Item]] and returns entities using the function */ - private def createAssemblerFunction(function: Function, assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Item => Option[Iterable[Entity]] = { + private def createAssemblerFunction(function: Option[Function], assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Item => Option[Iterable[Entity]] = { (item: Item) => { val triples: List[FlinkRDFQuad] = generateFunctionTriples(item, assembledPom) val paramTriples = triples.filter(triple => triple.predicate.uri != Uri(RMLVoc.Property.EXECUTES)) - - function.execute(paramTriples) + if (function.isDefined) { + function.get.execute(paramTriples) + } else { + None + } } } From b9309989cc0e3f0d3b527fe6ce8af58eb1421a83 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 25 Feb 2021 07:15:42 +0100 Subject: [PATCH 143/169] WIP: use paths relative to mapping file. To do: fix negative test cases. --- src/main/scala/io/rml/framework/Main.scala | 3 - .../io/rml/framework/core/util/Util.scala | 20 +++-- .../mapping.ttl | 2 +- src/test/resources/bugs/36/mapping.ttl | 2 +- .../bugs/58_no_triples_when_no_id/mapping.ttl | 14 ++-- src/test/resources/example1/example.rml.ttl | 4 +- src/test/resources/example10/mapping.rml.ttl | 2 +- .../resources/example2-bn/example.rml.ttl | 4 +- .../resources/example2-lang/example.rml.ttl | 4 +- .../resources/example2-object/example.rml.ttl | 4 +- src/test/resources/example2/example.rml.ttl | 4 +- src/test/resources/example2pm/example.rml.ttl | 4 +- src/test/resources/example3/example3.rml.ttl | 10 +-- .../resources/example4/example4_Venue.rml.ttl | 2 +- .../example4b/example4_Venue.rml.ttl | 2 +- src/test/resources/example6/example.rml.ttl | 4 +- src/test/resources/example8/simergy.rml.ttl | 2 +- .../RMLFNOTC0000-CSV/mapping.ttl | 2 +- .../RMLFNOTC0011-CSV/mapping.ttl | 2 +- .../RMLFNOTC0012-CSV/mapping.ttl | 2 +- .../RMLFNOTC0014-CSV/mapping.ttl | 2 +- .../RMLFNOTC0015-CSV/mapping.ttl | 2 +- .../RMLFNOTC0016-CSV/mapping.ttl | 2 +- .../RMLFNOTC0022-CSV/mapping.ttl | 2 +- .../RMLFNOTC0023-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0009b-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0009b-JSON/mapping.ttl | 4 +- .../rml-testcases/RMLTC0009b-XML/mapping.ttl | 4 +- .../rml-testcases/RMLTC0010c-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0010c-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0010c-XML/mapping.ttl | 2 +- .../RMLFNOTC0001-CSV/mapping.ttl | 2 +- .../RMLFNOTC0002-CSV/mapping.ttl | 2 +- .../RMLFNOTC0003-CSV/mapping.ttl | 2 +- .../RMLFNOTC0004-CSV/mapping.ttl | 2 +- .../RMLFNOTC0005-CSV/mapping.ttl | 2 +- .../RMLFNOTC0006-CSV/mapping.ttl | 2 +- .../RMLFNOTC0007-CSV/mapping.ttl | 2 +- .../RMLFNOTC0008-CSV/mapping.ttl | 2 +- .../RMLFNOTC0013-CSV/mapping.ttl | 2 +- .../RMLFNOTC0018-CSV/mapping.ttl | 2 +- .../fno-testcases/RMLFNOTCA004/mapping.ttl | 2 +- .../fno-testcases/RMLFNOTCA004/student.csv | 2 - .../fno-testcases/RMLFNOTCA004b/mapping.ttl | 2 +- .../fno-testcases/RMLFNOTCA004b/student.csv | 2 - .../mapping.ttl.bak | 33 -------- .../RMLTC0012a-CSV-STREAM/mapping.ttl.bak | 33 -------- .../mapping.ttl.bak | 34 -------- .../RMLTC0012a-JSON-STREAM/mapping.ttl.bak | 34 -------- .../mapping.ttl.bak | 34 -------- .../RMLTC0012a-XML-STREAM/mapping.ttl.bak | 34 -------- .../mapping.ttl.bak | 33 -------- .../tcp/RMLTC0012a-CSV-STREAM/mapping.ttl.bak | 33 -------- .../mapping.ttl.bak | 34 -------- .../RMLTC0012a-JSON-STREAM/mapping.ttl.bak | 34 -------- .../mapping.ttl.bak | 34 -------- .../tcp/RMLTC0012a-XML-STREAM/mapping.ttl.bak | 34 -------- .../RMLTC0002e-CSV/mapping.ttl | 24 ------ .../RMLTC0002e-CSV/mapping.ttl.bak | 24 ------ .../RMLTC0002e-JSON/mapping.ttl | 25 ------ .../RMLTC0002e-JSON/mapping.ttl.bak | 25 ------ .../RMLTC0002e-XML/mapping.ttl | 25 ------ .../RMLTC0002e-XML/mapping.ttl.bak | 25 ------ .../RMLTC0002g-JSON/mapping.ttl.bak | 23 ------ .../RMLTC0002g-XML/mapping.ttl.bak | 23 ------ .../RMLTC0004b-CSV/mapping.ttl.bak | 30 ------- .../RMLTC0004b-JSON/mapping.ttl.bak | 31 ------- .../RMLTC0004b-XML/mapping.ttl.bak | 31 ------- .../RMLTC0012c-CSV/mapping.rml.ttl.bak | 31 ------- .../RMLTC0012c-JSON/mapping.rml.ttl.bak | 32 -------- .../RMLTC0012c-XML/mapping.rml.ttl.bak | 32 -------- .../RMLTC0012d-CSV/mapping.rml.ttl | 36 -------- .../RMLTC0012d-JSON/mapping.rml.ttl.bak | 36 -------- .../RMLTC0012d-XML/mapping.rml.ttl.bak | 36 -------- .../RMLTC0004b-CSV/mapping.ttl | 2 +- .../RMLTC0004b-CSV/output.ttl | 0 .../RMLTC0004b-CSV/student.csv | 0 .../RMLTC0004b-JSON/mapping.ttl | 2 +- .../RMLTC0004b-JSON/output.ttl | 0 .../RMLTC0004b-JSON/student.json | 0 .../RMLTC0004b-XML/mapping.ttl | 2 +- .../RMLTC0004b-XML/output.ttl | 0 .../RMLTC0004b-XML/student.xml | 0 .../RMLTC0012c-CSV/mapping.rml.ttl | 2 +- .../RMLTC0012c-CSV/persons.csv | 0 .../RMLTC0012c-JSON/mapping.rml.ttl | 2 +- .../RMLTC0012c-JSON/persons.json | 0 .../RMLTC0012c-XML/mapping.rml.ttl | 2 +- .../RMLTC0012c-XML/persons.xml | 0 .../RMLTC0012d-CSV/mapping.rml.ttl} | 3 +- .../RMLTC0012d-CSV/persons.csv | 0 .../RMLTC0012d-JSON/mapping.rml.ttl | 2 +- .../RMLTC0012d-JSON/persons.json | 0 .../RMLTC0012d-XML/mapping.rml.ttl | 2 +- .../RMLTC0012d-XML/persons.xml | 0 .../RMLTC0015b-CSV/country_en.csv | 0 .../RMLTC0015b-CSV/country_es.csv | 0 .../RMLTC0015b-CSV/mapping.ttl | 4 +- .../RMLTC0015b-JSON/country_en.json | 0 .../RMLTC0015b-JSON/country_es.json | 0 .../RMLTC0015b-JSON/mapping.ttl | 4 +- .../RMLTC0015b-XML/country_en.xml | 0 .../RMLTC0015b-XML/country_es.xml | 0 .../RMLTC0015b-XML/mapping.ttl | 4 +- .../RMLTC0002e-CSV/mapping.ttl} | 2 +- .../RMLTC0002e-CSV/output.ttl | 0 .../RMLTC0002e-CSV/student.csv | 0 .../RMLTC0002e-JSON/mapping.ttl} | 2 +- .../RMLTC0002e-JSON/output.ttl | 0 .../RMLTC0002e-JSON/student.json | 0 .../RMLTC0002e-XML/mapping.ttl} | 2 +- .../RMLTC0002e-XML/output.ttl | 0 .../RMLTC0002e-XML/student.xml | 0 .../RMLTC0002g-JSON/mapping.ttl | 2 +- .../RMLTC0002g-JSON/output.ttl | 0 .../RMLTC0002g-JSON/student.json | 0 .../RMLTC0002g-XML/mapping.ttl | 2 +- .../RMLTC0002g-XML/output.ttl | 0 .../RMLTC0002g-XML/student.xml | 0 .../rml-testcases/RMLTC0000-CSV/mapping.ttl | 2 +- .../RMLTC0000-CSV/mapping.ttl.bak | 27 ------ .../rml-testcases/RMLTC0000-JSON/mapping.ttl | 2 +- .../RMLTC0000-JSON/mapping.ttl.bak | 28 ------- .../rml-testcases/RMLTC0000-XML/mapping.ttl | 2 +- .../RMLTC0000-XML/mapping.ttl.bak | 28 ------- .../rml-testcases/RMLTC0001a-CSV/mapping.ttl | 2 +- .../RMLTC0001a-CSV/mapping.ttl.bak | 29 ------- .../rml-testcases/RMLTC0001a-JSON/mapping.ttl | 2 +- .../RMLTC0001a-JSON/mapping.ttl.bak | 30 ------- .../rml-testcases/RMLTC0001a-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0001b-CSV/mapping.ttl | 2 +- .../RMLTC0001b-CSV/mapping.ttl.bak | 28 ------- .../rml-testcases/RMLTC0001b-JSON/mapping.ttl | 2 +- .../RMLTC0001b-JSON/mapping.ttl.bak | 29 ------- .../rml-testcases/RMLTC0001b-XML/mapping.ttl | 2 +- .../RMLTC0001b-XML/mapping.ttl.bak | 29 ------- .../rml-testcases/RMLTC0002a-CSV/mapping.ttl | 2 +- .../RMLTC0002a-CSV/mapping.ttl.bak | 29 ------- .../rml-testcases/RMLTC0002a-JSON/mapping.ttl | 2 +- .../RMLTC0002a-JSON/mapping.ttl.bak | 30 ------- .../rml-testcases/RMLTC0002a-XML/mapping.ttl | 2 +- .../RMLTC0002a-XML/mapping.ttl.bak | 30 ------- .../rml-testcases/RMLTC0002b-CSV/mapping.ttl | 2 +- .../RMLTC0002b-CSV/mapping.ttl.bak | 25 ------ .../rml-testcases/RMLTC0002b-JSON/mapping.ttl | 2 +- .../RMLTC0002b-JSON/mapping.ttl.bak | 26 ------ .../rml-testcases/RMLTC0002b-XML/mapping.ttl | 2 +- .../RMLTC0002b-XML/mapping.ttl.bak | 26 ------ .../rml-testcases/RMLTC0002c-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0002c-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0002c-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0003c-CSV/mapping.ttl | 2 +- .../RMLTC0003c-CSV/mapping.ttl.bak | 27 ------ .../rml-testcases/RMLTC0003c-JSON/mapping.ttl | 2 +- .../RMLTC0003c-JSON/mapping.ttl.bak | 28 ------- .../rml-testcases/RMLTC0003c-XML/mapping.ttl | 2 +- .../RMLTC0003c-XML/mapping.ttl.bak | 28 ------- .../rml-testcases/RMLTC0004a-CSV/mapping.ttl | 4 +- .../rml-testcases/RMLTC0004a-JSON/mapping.ttl | 4 +- .../RMLTC0004a-JSON/mapping.ttl.bak | 47 ----------- .../rml-testcases/RMLTC0004a-XML/mapping.ttl | 4 +- .../rml-testcases/RMLTC0005a-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0005a-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0005a-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0006a-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0006a-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0006a-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007a-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007a-JSON/mapping.ttl | 2 +- .../RMLTC0007a-JSON/mapping.ttl.bak | 26 ------ .../rml-testcases/RMLTC0007a-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007b-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007b-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007b-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007c-CSV/mapping.ttl | 2 +- .../RMLTC0007c-CSV/mapping.ttl.bak | 25 ------ .../rml-testcases/RMLTC0007c-JSON/mapping.ttl | 2 +- .../RMLTC0007c-JSON/mapping.ttl.bak | 28 ------- .../rml-testcases/RMLTC0007c-XML/mapping.ttl | 2 +- .../RMLTC0007c-XML/mapping.ttl.bak | 26 ------ .../rml-testcases/RMLTC0007d-CSV/mapping.ttl | 2 +- .../RMLTC0007d-CSV/mapping.ttl.bak | 35 -------- .../rml-testcases/RMLTC0007d-JSON/mapping.ttl | 2 +- .../RMLTC0007d-JSON/mapping.ttl.bak | 37 --------- .../rml-testcases/RMLTC0007d-XML/mapping.ttl | 2 +- .../RMLTC0007d-XML/mapping.ttl.bak | 37 --------- .../rml-testcases/RMLTC0007e-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007e-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007e-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007f-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007f-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007f-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0007g-CSV/mapping.ttl | 2 +- .../RMLTC0007g-CSV/mapping.ttl.bak | 26 ------ .../rml-testcases/RMLTC0007g-JSON/mapping.ttl | 2 +- .../RMLTC0007g-JSON/mapping.ttl.bak | 30 ------- .../rml-testcases/RMLTC0007g-XML/mapping.ttl | 2 +- .../RMLTC0007g-XML/mapping.ttl.bak | 27 ------ .../rml-testcases/RMLTC0007h-CSV/mapping.ttl | 2 +- .../RMLTC0007h-CSV/mapping.ttl.bak | 26 ------ .../rml-testcases/RMLTC0007h-JSON/mapping.ttl | 2 +- .../RMLTC0007h-JSON/mapping.ttl.bak | 30 ------- .../rml-testcases/RMLTC0007h-XML/mapping.ttl | 2 +- .../RMLTC0007h-XML/mapping.ttl.bak | 27 ------ .../rml-testcases/RMLTC0008a-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0008a-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0008a-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0008b-CSV/mapping.ttl | 4 +- .../RMLTC0008b-CSV/mapping.ttl.bak | 60 -------------- .../rml-testcases/RMLTC0008b-JSON/mapping.ttl | 4 +- .../RMLTC0008b-JSON/mapping.ttl.bak | 62 -------------- .../rml-testcases/RMLTC0008b-XML/mapping.ttl | 4 +- .../RMLTC0008b-XML/mapping.ttl.bak | 61 -------------- .../rml-testcases/RMLTC0008c-CSV/mapping.ttl | 2 +- .../RMLTC0008c-CSV/mapping.ttl.bak | 24 ------ .../rml-testcases/RMLTC0008c-JSON/mapping.ttl | 2 +- .../RMLTC0008c-JSON/mapping.ttl.bak | 25 ------ .../rml-testcases/RMLTC0008c-XML/mapping.ttl | 2 +- .../RMLTC0008c-XML/mapping.ttl.bak | 25 ------ .../rml-testcases/RMLTC0009a-CSV/mapping.ttl | 4 +- .../RMLTC0009a-CSV/mapping.ttl.bak | 52 ------------ .../rml-testcases/RMLTC0009a-JSON/mapping.ttl | 4 +- .../RMLTC0009a-JSON/mapping.ttl.bak | 54 ------------ .../rml-testcases/RMLTC0009a-XML/mapping.ttl | 4 +- .../RMLTC0009a-XML/mapping.ttl.bak | 54 ------------ .../rml-testcases/RMLTC0010a-CSV/mapping.ttl | 2 +- .../RMLTC0010a-CSV/mapping.ttl.bak | 23 ------ .../rml-testcases/RMLTC0010a-JSON/mapping.ttl | 2 +- .../RMLTC0010a-JSON/mapping.ttl.bak | 24 ------ .../rml-testcases/RMLTC0010b-CSV/mapping.ttl | 2 +- .../RMLTC0010b-CSV/mapping.ttl.bak | 23 ------ .../rml-testcases/RMLTC0010b-JSON/mapping.ttl | 2 +- .../RMLTC0010b-JSON/mapping.ttl.bak | 24 ------ .../rml-testcases/RMLTC0010b-XML/mapping.ttl | 2 +- .../RMLTC0010b-XML/mapping.ttl.bak | 24 ------ .../rml-testcases/RMLTC0010c-CSV/mapping.ttl | 2 +- .../RMLTC0010c-CSV/mapping.ttl.bak | 23 ------ .../rml-testcases/RMLTC0010c-JSON/mapping.ttl | 2 +- .../RMLTC0010c-JSON/mapping.ttl.bak | 24 ------ .../rml-testcases/RMLTC0010c-XML/mapping.ttl | 2 +- .../RMLTC0010c-XML/mapping.ttl.bak | 24 ------ .../rml-testcases/RMLTC0011b-CSV/mapping.ttl | 6 +- .../RMLTC0011b-CSV/mapping.ttl.bak | 79 ------------------ .../rml-testcases/RMLTC0011b-JSON/mapping.ttl | 6 +- .../RMLTC0011b-JSON/mapping.ttl.bak | 82 ------------------- .../rml-testcases/RMLTC0011b-XML/mapping.ttl | 6 +- .../RMLTC0011b-XML/mapping.ttl.bak | 82 ------------------- .../rml-testcases/RMLTC0012a-CSV/mapping.ttl | 2 +- .../RMLTC0012a-CSV/mapping.ttl.bak | 33 -------- .../rml-testcases/RMLTC0012a-JSON/mapping.ttl | 2 +- .../RMLTC0012a-JSON/mapping.ttl.bak | 34 -------- .../rml-testcases/RMLTC0012a-XML/mapping.ttl | 2 +- .../RMLTC0012a-XML/mapping.ttl.bak | 34 -------- .../rml-testcases/RMLTC0012b-CSV/mapping.ttl | 4 +- .../RMLTC0012b-CSV/mapping.ttl.bak | 52 ------------ .../rml-testcases/RMLTC0012b-JSON/mapping.ttl | 4 +- .../RMLTC0012b-JSON/mapping.ttl.bak | 54 ------------ .../rml-testcases/RMLTC0012b-XML/mapping.ttl | 4 +- .../RMLTC0012b-XML/mapping.ttl.bak | 54 ------------ .../rml-testcases/RMLTC0013a-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0015a-CSV/mapping.ttl | 4 +- .../rml-testcases/RMLTC0015a-JSON/mapping.ttl | 4 +- .../rml-testcases/RMLTC0015a-XML/mapping.ttl | 4 +- .../rml-testcases/RMLTC0019a-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0019a-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0019a-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0019b-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0019b-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0019b-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0020a-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0020a-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0020a-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC0020b-CSV/mapping.ttl | 2 +- .../rml-testcases/RMLTC0020b-JSON/mapping.ttl | 2 +- .../rml-testcases/RMLTC0020b-XML/mapping.ttl | 2 +- .../rml-testcases/RMLTC1001-JSON/mapping.ttl | 2 +- .../RMLTC1001-JSON/mapping.ttl.bak | 27 ------ .../rml-testcases/RMLTC1001-XML/mapping.ttl | 2 +- .../RMLTC1001-XML/mapping.ttl.bak | 27 ------ .../condition-function-on-po/mapping.ttl | 2 +- .../condition-function-on-po/mapping.yarrrml | 2 +- .../mapping.ttl | 2 +- .../condition-on-po/mapping.rml.ttl | 2 +- .../function_related/contains/mapping.ttl | 2 +- .../controls_if_contains/mapping.ttl | 2 +- .../mapping.ttl | 2 +- .../controls_if_false/mapping.ttl | 2 +- .../controls_if_true/mapping.ttl | 2 +- .../function_related/equal/mapping.ttl | 2 +- .../function_related/notEqual/mapping.ttl | 2 +- .../mapping.ttl | 2 +- .../using_trueCondition_and_equal/mapping.ttl | 2 +- .../rml/framework/OutputGenerationTest.scala | 3 +- .../scala/io/rml/framework/SandboxTests.scala | 2 +- .../util/fileprocessing/MappingTestUtil.scala | 10 ++- .../TripleGeneratorTestUtil.scala | 8 +- 296 files changed, 240 insertions(+), 3202 deletions(-) delete mode 100644 src/test/resources/fno-testcases/RMLFNOTCA004/student.csv delete mode 100644 src/test/resources/fno-testcases/RMLFNOTCA004b/student.csv delete mode 100644 src/test/resources/json-ld/stream/kafka/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/kafka/RMLTC0012a-CSV-STREAM/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/kafka/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/kafka/RMLTC0012a-JSON-STREAM/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/kafka/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/kafka/RMLTC0012a-XML-STREAM/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl.bak delete mode 100644 src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM/mapping.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0002e-CSV/mapping.ttl delete mode 100644 src/test/resources/negative_test_cases/RMLTC0002e-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0002e-JSON/mapping.ttl delete mode 100644 src/test/resources/negative_test_cases/RMLTC0002e-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0002e-XML/mapping.ttl delete mode 100644 src/test/resources/negative_test_cases/RMLTC0002e-XML/mapping.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0002g-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0002g-XML/mapping.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0004b-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0004b-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0004b-XML/mapping.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0012c-CSV/mapping.rml.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0012c-JSON/mapping.rml.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0012c-XML/mapping.rml.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0012d-CSV/mapping.rml.ttl delete mode 100644 src/test/resources/negative_test_cases/RMLTC0012d-JSON/mapping.rml.ttl.bak delete mode 100644 src/test/resources/negative_test_cases/RMLTC0012d-XML/mapping.rml.ttl.bak rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0004b-CSV/mapping.ttl (90%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0004b-CSV/output.ttl (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0004b-CSV/student.csv (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0004b-JSON/mapping.ttl (90%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0004b-JSON/output.ttl (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0004b-JSON/student.json (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0004b-XML/mapping.ttl (91%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0004b-XML/output.ttl (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0004b-XML/student.xml (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012c-CSV/mapping.rml.ttl (91%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012c-CSV/persons.csv (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012c-JSON/mapping.rml.ttl (91%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012c-JSON/persons.json (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012c-XML/mapping.rml.ttl (91%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012c-XML/persons.xml (100%) rename src/test/resources/{negative_test_cases/RMLTC0012d-CSV/mapping.rml.ttl.bak => rml-testcases-invalid-mapping-file/RMLTC0012d-CSV/mapping.rml.ttl} (93%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012d-CSV/persons.csv (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012d-JSON/mapping.rml.ttl (93%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012d-JSON/persons.json (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012d-XML/mapping.rml.ttl (93%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0012d-XML/persons.xml (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0015b-CSV/country_en.csv (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0015b-CSV/country_es.csv (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0015b-CSV/mapping.ttl (87%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0015b-JSON/country_en.json (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0015b-JSON/country_es.json (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0015b-JSON/mapping.ttl (88%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0015b-XML/country_en.xml (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0015b-XML/country_es.xml (100%) rename src/test/resources/{negative_test_cases => rml-testcases-invalid-mapping-file}/RMLTC0015b-XML/mapping.ttl (88%) rename src/test/resources/{rml-testcases/RMLTC0002c-CSV/mapping.ttl.bak => rml-testcases-negative/RMLTC0002e-CSV/mapping.ttl} (90%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002e-CSV/output.ttl (100%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002e-CSV/student.csv (100%) rename src/test/resources/{rml-testcases/RMLTC0002c-JSON/mapping.ttl.bak => rml-testcases-negative/RMLTC0002e-JSON/mapping.ttl} (91%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002e-JSON/output.ttl (100%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002e-JSON/student.json (100%) rename src/test/resources/{rml-testcases/RMLTC0002c-XML/mapping.ttl.bak => rml-testcases-negative/RMLTC0002e-XML/mapping.ttl} (91%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002e-XML/output.ttl (100%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002e-XML/student.xml (100%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002g-JSON/mapping.ttl (90%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002g-JSON/output.ttl (100%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002g-JSON/student.json (100%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002g-XML/mapping.ttl (90%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002g-XML/output.ttl (100%) rename src/test/resources/{negative_test_cases => rml-testcases-negative}/RMLTC0002g-XML/student.xml (100%) delete mode 100644 src/test/resources/rml-testcases/RMLTC0000-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0000-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0000-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0001a-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0001a-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0001b-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0001b-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0001b-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0002a-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0002a-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0002a-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0002b-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0002b-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0002b-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0003c-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0003c-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0003c-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0004a-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007a-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007c-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007c-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007c-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007d-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007d-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007d-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007g-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007g-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007g-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007h-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007h-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0007h-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0008b-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0008b-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0008b-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0008c-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0008c-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0008c-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0009a-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0009a-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0009a-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0010a-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0010a-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0010b-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0010b-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0010b-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0012a-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0012a-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0012a-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0012b-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0012b-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC0012b-XML/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC1001-JSON/mapping.ttl.bak delete mode 100644 src/test/resources/rml-testcases/RMLTC1001-XML/mapping.ttl.bak diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index c6aaae57..8562dbf7 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -83,9 +83,6 @@ object Main extends Logging { // determine the base IRI of the RDF to generate RMLEnvironment.setGeneratorBaseIRI(config.baseIRI) - // determine the base IRI of the mapping file - RMLEnvironment.setMappingFileBaseIRI(Some((config.mappingFilePath))) - // Read mapping file and format these, a formatted mapping is a rml mapping that is reorganized optimally. // Triple maps are also organized in categories (does it contain streams, does it contain joins, ... ) val formattedMapping = Util.readMappingFile(config.mappingFilePath) diff --git a/src/main/scala/io/rml/framework/core/util/Util.scala b/src/main/scala/io/rml/framework/core/util/Util.scala index bfbc6337..7fda10e7 100644 --- a/src/main/scala/io/rml/framework/core/util/Util.scala +++ b/src/main/scala/io/rml/framework/core/util/Util.scala @@ -24,6 +24,7 @@ **/ package io.rml.framework.core.util +import io.rml.framework.api.RMLEnvironment import io.rml.framework.core.extractors.MappingReader import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.{FormattedRMLMapping, Literal, Node, RMLMapping} @@ -190,9 +191,9 @@ object Util extends Logging{ * @return */ def readMappingFile(path: String): FormattedRMLMapping = { - val mappingFile = getFile(path) - - val mapping = MappingReader().read(mappingFile).asInstanceOf[RMLMapping] + val mappingFile = getFile(path); + RMLEnvironment.setMappingFileBaseIRI(Some(mappingFile.getCanonicalPath)) + val mapping = MappingReader().read(mappingFile).asInstanceOf[RMLMapping]; FormattedRMLMapping.fromRMLMapping(mapping) } @@ -227,7 +228,7 @@ object Util extends Logging{ Try(getFileRelativeToUserDir(path)) match { case Success(file) => Some(file) case Failure(exception) => { - logWarning(s"can't find file $path relative to user dir") + logWarning(s"can't find file $path relative to working dir") None } } @@ -245,10 +246,13 @@ object Util extends Logging{ def resolveFileRelativeToSourceFileParent(sourcePathString: String, other : String) = { val sourcePath = Paths.get(sourcePathString) - sourcePath - .getParent - .resolve(other) - .toFile + val resolved = if (sourcePath.toFile.isDirectory) { + sourcePath.resolve(other) + } else { + sourcePath.resolveSibling(other) + }; + + resolved.toFile .getCanonicalFile } diff --git a/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/mapping.ttl b/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/mapping.ttl index eb2a26f0..6799b86d 100644 --- a/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/mapping.ttl +++ b/src/test/resources/bugs/108_stackoverflow_when_reading_mapping_github_19/mapping.ttl @@ -15,7 +15,7 @@ @prefix edtf: . @prefix meemoo: . -map:FragmentMetadata rml:source "bugs/108_stackoverflow_when_reading_mapping_github_19/head.csv"; +map:FragmentMetadata rml:source "head.csv"; rml:referenceFormulation ql:CSV. map:Fragment a rr:TriplesMap; diff --git a/src/test/resources/bugs/36/mapping.ttl b/src/test/resources/bugs/36/mapping.ttl index 83dc8d61..0d0b30df 100644 --- a/src/test/resources/bugs/36/mapping.ttl +++ b/src/test/resources/bugs/36/mapping.ttl @@ -7,7 +7,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "bugs/36/input.json"; + rml:source "input.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.people[*]" ]; diff --git a/src/test/resources/bugs/58_no_triples_when_no_id/mapping.ttl b/src/test/resources/bugs/58_no_triples_when_no_id/mapping.ttl index ee94b033..d7a6dd3d 100644 --- a/src/test/resources/bugs/58_no_triples_when_no_id/mapping.ttl +++ b/src/test/resources/bugs/58_no_triples_when_no_id/mapping.ttl @@ -18,7 +18,7 @@ :map_anomaly_0 rml:logicalSource :source_0. :source_0 a rml:LogicalSource; - rml:source "bugs/58_no_triples_when_no_id/input.json"; + rml:source "input.json"; rml:iterator "$"; rml:referenceFormulation ql:JSONPath. :map_anomaly_0 a rr:TriplesMap; @@ -110,7 +110,7 @@ rr:termType rr:IRI. :map_stimulus_0 rml:logicalSource :source_1. :source_1 a rml:LogicalSource; - rml:source "bugs/58_no_triples_when_no_id/input.json"; + rml:source "input.json"; rml:iterator "$.anomaly.parts[*]"; rml:referenceFormulation ql:JSONPath. :map_stimulus_0 a rr:TriplesMap; @@ -156,7 +156,7 @@ rr:termType rr:IRI. :map_observation_from_0 rml:logicalSource :source_2. :source_2 a rml:LogicalSource; - rml:source "bugs/58_no_triples_when_no_id/input.json"; + rml:source "input.json"; rml:iterator "$.anomaly.parts[*]"; rml:referenceFormulation ql:JSONPath. :map_observation_from_0 a rr:TriplesMap; @@ -176,7 +176,7 @@ rr:datatype . :map_observation_to_0 rml:logicalSource :source_3. :source_3 a rml:LogicalSource; - rml:source "bugs/58_no_triples_when_no_id/input.json"; + rml:source "input.json"; rml:iterator "$.anomaly.parts[*]"; rml:referenceFormulation ql:JSONPath. :map_observation_to_0 a rr:TriplesMap; @@ -196,7 +196,7 @@ rr:datatype . :map_procedure_0 rml:logicalSource :source_4. :source_4 a rml:LogicalSource; - rml:source "bugs/58_no_triples_when_no_id/input.json"; + rml:source "input.json"; rml:iterator "$"; rml:referenceFormulation ql:JSONPath. :map_procedure_0 a rr:TriplesMap; @@ -224,7 +224,7 @@ rr:termType rr:IRI. :map_procedure_bn_0 rml:logicalSource :source_5. :source_5 a rml:LogicalSource; - rml:source "bugs/58_no_triples_when_no_id/input.json"; + rml:source "input.json"; rml:iterator "$"; rml:referenceFormulation ql:JSONPath. :map_procedure_bn_0 a rr:TriplesMap; @@ -243,7 +243,7 @@ rr:termType rr:Literal. :map_sensor_property_0 rml:logicalSource :source_6. :source_6 a rml:LogicalSource; - rml:source "bugs/58_no_triples_when_no_id/input.json"; + rml:source "input.json"; rml:iterator "$.anomaly.parts[*]"; rml:referenceFormulation ql:JSONPath. :map_sensor_property_0 a rr:TriplesMap; diff --git a/src/test/resources/example1/example.rml.ttl b/src/test/resources/example1/example.rml.ttl index 2d6e7623..446bdcfa 100755 --- a/src/test/resources/example1/example.rml.ttl +++ b/src/test/resources/example1/example.rml.ttl @@ -8,7 +8,7 @@ <#FromToMaps> a rr:TriplesMap; rml:logicalSource [ - rml:source "example1/example1.xml"; + rml:source "example1.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/notes/note"; ]; @@ -47,7 +47,7 @@ rr:subjectMap [ <#DateTime> rml:logicalSource [ - rml:source "example1/example1.xml"; + rml:source "example1.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; diff --git a/src/test/resources/example10/mapping.rml.ttl b/src/test/resources/example10/mapping.rml.ttl index 7b6b937a..807728e3 100644 --- a/src/test/resources/example10/mapping.rml.ttl +++ b/src/test/resources/example10/mapping.rml.ttl @@ -10,7 +10,7 @@ <#PersonMapping> rml:logicalSource [ - rml:source "example10/persons.json"; + rml:source "persons.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/example2-bn/example.rml.ttl b/src/test/resources/example2-bn/example.rml.ttl index a1de1d97..f5c9c5ba 100644 --- a/src/test/resources/example2-bn/example.rml.ttl +++ b/src/test/resources/example2-bn/example.rml.ttl @@ -8,7 +8,7 @@ <#FromToMaps> rml:logicalSource [ - rml:source "example2-bn/example2.xml"; + rml:source "example2.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; @@ -47,7 +47,7 @@ <#DateTime> rml:logicalSource [ - rml:source "example2-bn/example2.xml"; + rml:source "example2.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; diff --git a/src/test/resources/example2-lang/example.rml.ttl b/src/test/resources/example2-lang/example.rml.ttl index ea2305c6..8ddca0eb 100644 --- a/src/test/resources/example2-lang/example.rml.ttl +++ b/src/test/resources/example2-lang/example.rml.ttl @@ -8,7 +8,7 @@ <#FromToMaps> rml:logicalSource [ - rml:source "example2/example2.xml"; + rml:source "example2.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; @@ -47,7 +47,7 @@ <#DateTime> rml:logicalSource [ - rml:source "example2/example2.xml"; + rml:source "example2.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; diff --git a/src/test/resources/example2-object/example.rml.ttl b/src/test/resources/example2-object/example.rml.ttl index 52aa5052..4d0946f3 100644 --- a/src/test/resources/example2-object/example.rml.ttl +++ b/src/test/resources/example2-object/example.rml.ttl @@ -8,7 +8,7 @@ <#FromToMaps> rml:logicalSource [ - rml:source "example2/example2.xml"; + rml:source "example2.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; @@ -47,7 +47,7 @@ <#DateTime> rml:logicalSource [ - rml:source "example2/example2.xml"; + rml:source "example2.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; diff --git a/src/test/resources/example2/example.rml.ttl b/src/test/resources/example2/example.rml.ttl index 09b8f307..63b0f196 100755 --- a/src/test/resources/example2/example.rml.ttl +++ b/src/test/resources/example2/example.rml.ttl @@ -8,7 +8,7 @@ <#FromToMaps> a rr:TriplesMap; rml:logicalSource [ - rml:source "example2/example2.xml"; + rml:source "example2.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; @@ -45,7 +45,7 @@ <#DateTime> rml:logicalSource [ - rml:source "example2/example2.xml" ; + rml:source "example2.xml" ; rml:iterator "/notes/note" ; rml:referenceFormulation ql:XPath ; ]; diff --git a/src/test/resources/example2pm/example.rml.ttl b/src/test/resources/example2pm/example.rml.ttl index ef3fc1c1..72c4867c 100644 --- a/src/test/resources/example2pm/example.rml.ttl +++ b/src/test/resources/example2pm/example.rml.ttl @@ -8,7 +8,7 @@ <#FromToMaps> rml:logicalSource [ - rml:source "example2/example2.xml"; + rml:source "example2.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; @@ -47,7 +47,7 @@ <#DateTime> rml:logicalSource [ - rml:source "example2/example2.xml"; + rml:source "example2.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; diff --git a/src/test/resources/example3/example3.rml.ttl b/src/test/resources/example3/example3.rml.ttl index 8f06bcdc..c19111db 100755 --- a/src/test/resources/example3/example3.rml.ttl +++ b/src/test/resources/example3/example3.rml.ttl @@ -24,7 +24,7 @@ <#AirportMapping> rml:logicalSource [ - rml:source "example3/Airport.csv"; + rml:source "Airport.csv"; rml:referenceFormulation ql:CSV ]; rr:subjectMap [ @@ -56,7 +56,7 @@ <#BusMapping> rml:logicalSource[ - rml:source "example3/Transport.xml"; + rml:source "Transport.xml"; rml:iterator "/transport/bus"; rml:referenceFormulation ql:XPath; ]; @@ -75,7 +75,7 @@ <#BusStopMapping> rml:logicalSource [ - rml:source "example3/Transport.xml"; + rml:source "Transport.xml"; rml:iterator "/transport/bus/route/stop"; rml:referenceFormulation ql:XPath; ]; @@ -93,7 +93,7 @@ <#VenueMapping> rml:logicalSource [ - rml:source "example3/Venue.json"; + rml:source "Venue.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$" ]; @@ -124,7 +124,7 @@ <#LocationMapping> rml:logicalSource [ - rml:source "example3/Venue.json"; + rml:source "Venue.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$" ]; diff --git a/src/test/resources/example4/example4_Venue.rml.ttl b/src/test/resources/example4/example4_Venue.rml.ttl index 6b99ecde..fdcec129 100755 --- a/src/test/resources/example4/example4_Venue.rml.ttl +++ b/src/test/resources/example4/example4_Venue.rml.ttl @@ -17,7 +17,7 @@ <#VenueMapping> rml:logicalSource [ - rml:source "example4/Venue4.json"; + rml:source "Venue4.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$[*]"; ]; diff --git a/src/test/resources/example4b/example4_Venue.rml.ttl b/src/test/resources/example4b/example4_Venue.rml.ttl index 06e234e9..fdcec129 100644 --- a/src/test/resources/example4b/example4_Venue.rml.ttl +++ b/src/test/resources/example4b/example4_Venue.rml.ttl @@ -17,7 +17,7 @@ <#VenueMapping> rml:logicalSource [ - rml:source "example4b/Venue4.json"; + rml:source "Venue4.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$[*]"; ]; diff --git a/src/test/resources/example6/example.rml.ttl b/src/test/resources/example6/example.rml.ttl index 44d908e0..30c7cee9 100755 --- a/src/test/resources/example6/example.rml.ttl +++ b/src/test/resources/example6/example.rml.ttl @@ -8,7 +8,7 @@ <#FromToMaps> rml:logicalSource [ - rml:source "example6/example6.xml"; + rml:source "example6.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/notes/note"; ]; @@ -48,7 +48,7 @@ <#DateTime> rml:logicalSource [ - rml:source "example6/example6.xml"; + rml:source "example6.xml"; rml:iterator "/notes/note"; rml:referenceFormulation ql:XPath; ]; diff --git a/src/test/resources/example8/simergy.rml.ttl b/src/test/resources/example8/simergy.rml.ttl index d726a1db..bafd3faa 100755 --- a/src/test/resources/example8/simergy.rml.ttl +++ b/src/test/resources/example8/simergy.rml.ttl @@ -10,7 +10,7 @@ <#SimModelMapping> rml:logicalSource [ - rml:source "example8/simergy.xml" ; + rml:source "simergy.xml" ; rml:iterator "/SimModel/simmodel:SimAppLibraryDefault_AppLibraryDefault_GlobalLibrary"; rml:referenceFormulation ql:XPath ; ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl index 0c188516..f5044d2c 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl index d6a18f37..f42c5c72 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl index 03a48120..3f04a6a1 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl index 8e805fa2..502a7a3a 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl index 0c9872aa..91a6e11e 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl index 142874f1..6e3a5b71 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/mapping.ttl index 682712dc..a3500a44 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/RMLFNOTC0022-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl index 987a170e..b462643e 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl @@ -19,7 +19,7 @@ map:map_person_0 map:source_0 a rml:LogicalSource ; - rml:source "failing/fno-testcases/RMLFNOTC0023-CSV/student.csv" ; + rml:source "student.csv" ; rml:referenceFormulation ql:CSV . map:s_0 diff --git a/src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/mapping.ttl index 289a00bb..1aa09736 100644 --- a/src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/mapping.ttl +++ b/src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009b-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/mapping.ttl index 47e890f1..381463cf 100644 --- a/src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/mapping.ttl +++ b/src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009b-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; @@ -45,7 +45,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009b-JSON/sport.json"; + rml:source "sport.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.sports[*]" ]; diff --git a/src/test/resources/failing/rml-testcases/RMLTC0009b-XML/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0009b-XML/mapping.ttl index 17d7f0c5..9b528fa9 100644 --- a/src/test/resources/failing/rml-testcases/RMLTC0009b-XML/mapping.ttl +++ b/src/test/resources/failing/rml-testcases/RMLTC0009b-XML/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009b-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; @@ -47,7 +47,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009b-XML/sport.xml"; + rml:source "sport.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/sports/sport" ]; diff --git a/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl index 250a85dd..c62096a8 100644 --- a/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl +++ b/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-CSV/country info.csv"; + rml:source "country info.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl index 04fa74dd..3cd7bd9d 100644 --- a/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl +++ b/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-JSON/country info.json"; + rml:source "country info.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" ]; diff --git a/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl index 157c218f..37c8aab2 100644 --- a/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl +++ b/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-XML/country info.xml"; + rml:source "country info.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/countries/country" ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl index beba67cc..a4c816cc 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl index e530250b..4b0a4b90 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl index a973198a..eda134cd 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl index b8a44fc5..fd98a596 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl index 242b17c9..a7fbf469 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/RMLFNOTC0005-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl index dc5d9a35..bce4d84c 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl index 3e51b5f2..2f1105d3 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl index 7cef47eb..a9ba63f7 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl index 391dfe0d..02a792dd 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl index daaa7860..5a30cdaa 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/RMLFNOTC0018-CSV/data.csv"; + rml:source "data.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTCA004/mapping.ttl index 9bb5550c..377b7240 100644 --- a/src/test/resources/fno-testcases/RMLFNOTCA004/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTCA004/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004/student.csv b/src/test/resources/fno-testcases/RMLFNOTCA004/student.csv deleted file mode 100644 index 052b9915..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTCA004/student.csv +++ /dev/null @@ -1,2 +0,0 @@ -Id,Name,Comment,Class -1,Venus,A&B,A diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004b/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTCA004b/mapping.ttl index 7d22945c..79125db8 100644 --- a/src/test/resources/fno-testcases/RMLFNOTCA004b/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTCA004b/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/fno-testcases/RMLFNOTCA004b/student.csv b/src/test/resources/fno-testcases/RMLFNOTCA004b/student.csv deleted file mode 100644 index 052b9915..00000000 --- a/src/test/resources/fno-testcases/RMLFNOTCA004b/student.csv +++ /dev/null @@ -1,2 +0,0 @@ -Id,Name,Comment,Class -1,Venus,A&B,A diff --git a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl.bak b/src/test/resources/json-ld/stream/kafka/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl.bak deleted file mode 100644 index b875af25..00000000 --- a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl.bak +++ /dev/null @@ -1,33 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-CSV/persons.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-CSV-STREAM/mapping.ttl.bak b/src/test/resources/json-ld/stream/kafka/RMLTC0012a-CSV-STREAM/mapping.ttl.bak deleted file mode 100644 index b875af25..00000000 --- a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-CSV-STREAM/mapping.ttl.bak +++ /dev/null @@ -1,33 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-CSV/persons.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl.bak b/src/test/resources/json-ld/stream/kafka/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl.bak deleted file mode 100644 index 1acdb04b..00000000 --- a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.persons[*]" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-JSON-STREAM/mapping.ttl.bak b/src/test/resources/json-ld/stream/kafka/RMLTC0012a-JSON-STREAM/mapping.ttl.bak deleted file mode 100644 index 09638b19..00000000 --- a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-JSON-STREAM/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-JSON/persons.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.persons[*]" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl.bak b/src/test/resources/json-ld/stream/kafka/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl.bak deleted file mode 100644 index 76f1d43d..00000000 --- a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; - rml:referenceFormulation ql:XPath; - rml:iterator "/Persons/Person" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-XML-STREAM/mapping.ttl.bak b/src/test/resources/json-ld/stream/kafka/RMLTC0012a-XML-STREAM/mapping.ttl.bak deleted file mode 100644 index 9e55c5d8..00000000 --- a/src/test/resources/json-ld/stream/kafka/RMLTC0012a-XML-STREAM/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-XML/persons.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/Persons/Person" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl.bak b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl.bak deleted file mode 100644 index b875af25..00000000 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl.bak +++ /dev/null @@ -1,33 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-CSV/persons.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM/mapping.ttl.bak b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM/mapping.ttl.bak deleted file mode 100644 index b875af25..00000000 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM/mapping.ttl.bak +++ /dev/null @@ -1,33 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-CSV/persons.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl.bak b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl.bak deleted file mode 100644 index 1acdb04b..00000000 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.persons[*]" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM/mapping.ttl.bak b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM/mapping.ttl.bak deleted file mode 100644 index 09638b19..00000000 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-JSON/persons.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.persons[*]" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl.bak b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl.bak deleted file mode 100644 index 76f1d43d..00000000 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; - rml:referenceFormulation ql:XPath; - rml:iterator "/Persons/Person" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM/mapping.ttl.bak b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM/mapping.ttl.bak deleted file mode 100644 index 9e55c5d8..00000000 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-XML/persons.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/Persons/Person" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-CSV/mapping.ttl b/src/test/resources/negative_test_cases/RMLTC0002e-CSV/mapping.ttl deleted file mode 100644 index 3e1e0deb..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0002e-CSV/mapping.ttl +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002e-CSV/student2.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "IDs" ] - ]. - diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-CSV/mapping.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0002e-CSV/mapping.ttl.bak deleted file mode 100644 index 41476180..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0002e-CSV/mapping.ttl.bak +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002e-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "IDs" ] - ]. - diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-JSON/mapping.ttl b/src/test/resources/negative_test_cases/RMLTC0002e-JSON/mapping.ttl deleted file mode 100644 index 2df0f1a8..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0002e-JSON/mapping.ttl +++ /dev/null @@ -1,25 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002e-JSON/student2.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "IDs" ] - ]. - diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-JSON/mapping.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0002e-JSON/mapping.ttl.bak deleted file mode 100644 index 170caafe..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0002e-JSON/mapping.ttl.bak +++ /dev/null @@ -1,25 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002e-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "IDs" ] - ]. - diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-XML/mapping.ttl b/src/test/resources/negative_test_cases/RMLTC0002e-XML/mapping.ttl deleted file mode 100644 index 267c50ef..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0002e-XML/mapping.ttl +++ /dev/null @@ -1,25 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002e-XML/student2.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "IDs" ] - ]. - diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-XML/mapping.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0002e-XML/mapping.ttl.bak deleted file mode 100644 index 4289256e..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0002e-XML/mapping.ttl.bak +++ /dev/null @@ -1,25 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002e-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "IDs" ] - ]. - diff --git a/src/test/resources/negative_test_cases/RMLTC0002g-JSON/mapping.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0002g-JSON/mapping.ttl.bak deleted file mode 100644 index 41f6a2a0..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0002g-JSON/mapping.ttl.bak +++ /dev/null @@ -1,23 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002g-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "IDs" ] - ]. - diff --git a/src/test/resources/negative_test_cases/RMLTC0002g-XML/mapping.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0002g-XML/mapping.ttl.bak deleted file mode 100644 index 4237f611..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0002g-XML/mapping.ttl.bak +++ /dev/null @@ -1,23 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002g-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "$" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "IDs" ] - ]. - diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-CSV/mapping.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0004b-CSV/mapping.ttl.bak deleted file mode 100644 index af1f39a6..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0004b-CSV/mapping.ttl.bak +++ /dev/null @@ -1,30 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0004b-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}"; - rr:termType rr:Literal - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. - - diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-JSON/mapping.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0004b-JSON/mapping.ttl.bak deleted file mode 100644 index dc592ce2..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0004b-JSON/mapping.ttl.bak +++ /dev/null @@ -1,31 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0004b-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}"; - rr:termType rr:Literal - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. - - diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-XML/mapping.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0004b-XML/mapping.ttl.bak deleted file mode 100644 index fda50028..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0004b-XML/mapping.ttl.bak +++ /dev/null @@ -1,31 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0004b-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}"; - rr:termType rr:Literal - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. - - diff --git a/src/test/resources/negative_test_cases/RMLTC0012c-CSV/mapping.rml.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0012c-CSV/mapping.rml.ttl.bak deleted file mode 100644 index 6327da79..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0012c-CSV/mapping.rml.ttl.bak +++ /dev/null @@ -1,31 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012c-CSV/persons.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/negative_test_cases/RMLTC0012c-JSON/mapping.rml.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0012c-JSON/mapping.rml.ttl.bak deleted file mode 100644 index f7cb6100..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0012c-JSON/mapping.rml.ttl.bak +++ /dev/null @@ -1,32 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012c-JSON/persons.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.persons[*]" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/negative_test_cases/RMLTC0012c-XML/mapping.rml.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0012c-XML/mapping.rml.ttl.bak deleted file mode 100644 index bc6b936e..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0012c-XML/mapping.rml.ttl.bak +++ /dev/null @@ -1,32 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: .qsdfqsdf -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012c-XML/persons.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/Persons/Person" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/negative_test_cases/RMLTC0012d-CSV/mapping.rml.ttl b/src/test/resources/negative_test_cases/RMLTC0012d-CSV/mapping.rml.ttl deleted file mode 100644 index 5aea6805..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0012d-CSV/mapping.rml.ttl +++ /dev/null @@ -1,36 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012d-CSV/persons.csv"; - rml:referenceFormulation ql:CSV - ]; - - - rr:subjectMap [ rr:template "{fname}_{lname}_{amount}"; rr:termType rr:BlankNode; ]; - - rr:subjectMap [ rr:template "{amount}_{fname}_{lname}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/negative_test_cases/RMLTC0012d-JSON/mapping.rml.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0012d-JSON/mapping.rml.ttl.bak deleted file mode 100644 index 2441221d..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0012d-JSON/mapping.rml.ttl.bak +++ /dev/null @@ -1,36 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012d-JSON/persons.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.persons[*]" - ]; - - rr:subjectMap [ rr:template "{fname}_{lname}_{amount}"; rr:termType rr:BlankNode; ]; - - rr:subjectMap [ rr:template "{amount}_{fname}_{lname}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/negative_test_cases/RMLTC0012d-XML/mapping.rml.ttl.bak b/src/test/resources/negative_test_cases/RMLTC0012d-XML/mapping.rml.ttl.bak deleted file mode 100644 index 38e6f34e..00000000 --- a/src/test/resources/negative_test_cases/RMLTC0012d-XML/mapping.rml.ttl.bak +++ /dev/null @@ -1,36 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012d-XML/persons.json"; - rml:referenceFormulation ql:XPath; - rml:iterator "/Persons/Person" - ]; - - rr:subjectMap [ rr:template "{fname}_{lname}_{amount}"; rr:termType rr:BlankNode; ]; - - rr:subjectMap [ rr:template "{amount}_{fname}_{lname}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-CSV/mapping.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-CSV/mapping.ttl similarity index 90% rename from src/test/resources/negative_test_cases/RMLTC0004b-CSV/mapping.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-CSV/mapping.ttl index af1f39a6..bbf9d957 100644 --- a/src/test/resources/negative_test_cases/RMLTC0004b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0004b-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-CSV/output.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-CSV/output.ttl similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0004b-CSV/output.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-CSV/output.ttl diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-CSV/student.csv b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-CSV/student.csv similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0004b-CSV/student.csv rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-CSV/student.csv diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-JSON/mapping.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-JSON/mapping.ttl similarity index 90% rename from src/test/resources/negative_test_cases/RMLTC0004b-JSON/mapping.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-JSON/mapping.ttl index dc592ce2..a0b87505 100644 --- a/src/test/resources/negative_test_cases/RMLTC0004b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0004b-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-JSON/output.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-JSON/output.ttl similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0004b-JSON/output.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-JSON/output.ttl diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-JSON/student.json b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-JSON/student.json similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0004b-JSON/student.json rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-JSON/student.json diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-XML/mapping.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-XML/mapping.ttl similarity index 91% rename from src/test/resources/negative_test_cases/RMLTC0004b-XML/mapping.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-XML/mapping.ttl index fda50028..1c9301df 100644 --- a/src/test/resources/negative_test_cases/RMLTC0004b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0004b-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-XML/output.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-XML/output.ttl similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0004b-XML/output.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-XML/output.ttl diff --git a/src/test/resources/negative_test_cases/RMLTC0004b-XML/student.xml b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-XML/student.xml similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0004b-XML/student.xml rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0004b-XML/student.xml diff --git a/src/test/resources/negative_test_cases/RMLTC0012c-CSV/mapping.rml.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-CSV/mapping.rml.ttl similarity index 91% rename from src/test/resources/negative_test_cases/RMLTC0012c-CSV/mapping.rml.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-CSV/mapping.rml.ttl index ffee4af0..5147b0f1 100644 --- a/src/test/resources/negative_test_cases/RMLTC0012c-CSV/mapping.rml.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-CSV/mapping.rml.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012c-CSV/persons.csv"; + rml:source "persons.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0012c-CSV/persons.csv b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-CSV/persons.csv similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0012c-CSV/persons.csv rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-CSV/persons.csv diff --git a/src/test/resources/negative_test_cases/RMLTC0012c-JSON/mapping.rml.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-JSON/mapping.rml.ttl similarity index 91% rename from src/test/resources/negative_test_cases/RMLTC0012c-JSON/mapping.rml.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-JSON/mapping.rml.ttl index 5f85446f..3a84fbae 100644 --- a/src/test/resources/negative_test_cases/RMLTC0012c-JSON/mapping.rml.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-JSON/mapping.rml.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012c-JSON/persons.json"; + rml:source "persons.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0012c-JSON/persons.json b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-JSON/persons.json similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0012c-JSON/persons.json rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-JSON/persons.json diff --git a/src/test/resources/negative_test_cases/RMLTC0012c-XML/mapping.rml.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-XML/mapping.rml.ttl similarity index 91% rename from src/test/resources/negative_test_cases/RMLTC0012c-XML/mapping.rml.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-XML/mapping.rml.ttl index cc3ec3b8..79733745 100644 --- a/src/test/resources/negative_test_cases/RMLTC0012c-XML/mapping.rml.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-XML/mapping.rml.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012c-XML/persons.xml"; + rml:source "persons.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/Persons/Person" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0012c-XML/persons.xml b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-XML/persons.xml similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0012c-XML/persons.xml rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012c-XML/persons.xml diff --git a/src/test/resources/negative_test_cases/RMLTC0012d-CSV/mapping.rml.ttl.bak b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-CSV/mapping.rml.ttl similarity index 93% rename from src/test/resources/negative_test_cases/RMLTC0012d-CSV/mapping.rml.ttl.bak rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-CSV/mapping.rml.ttl index 8f465fbe..6499b34f 100644 --- a/src/test/resources/negative_test_cases/RMLTC0012d-CSV/mapping.rml.ttl.bak +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-CSV/mapping.rml.ttl @@ -11,10 +11,11 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012d-CSV/persons.csv"; + rml:source "persons.csv"; rml:referenceFormulation ql:CSV ]; + rr:subjectMap [ rr:template "{fname}_{lname}_{amount}"; rr:termType rr:BlankNode; ]; rr:subjectMap [ rr:template "{amount}_{fname}_{lname}"; rr:termType rr:BlankNode; ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0012d-CSV/persons.csv b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-CSV/persons.csv similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0012d-CSV/persons.csv rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-CSV/persons.csv diff --git a/src/test/resources/negative_test_cases/RMLTC0012d-JSON/mapping.rml.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-JSON/mapping.rml.ttl similarity index 93% rename from src/test/resources/negative_test_cases/RMLTC0012d-JSON/mapping.rml.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-JSON/mapping.rml.ttl index 5a34c70a..51958c84 100644 --- a/src/test/resources/negative_test_cases/RMLTC0012d-JSON/mapping.rml.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-JSON/mapping.rml.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012d-JSON/persons.json"; + rml:source "persons.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0012d-JSON/persons.json b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-JSON/persons.json similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0012d-JSON/persons.json rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-JSON/persons.json diff --git a/src/test/resources/negative_test_cases/RMLTC0012d-XML/mapping.rml.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-XML/mapping.rml.ttl similarity index 93% rename from src/test/resources/negative_test_cases/RMLTC0012d-XML/mapping.rml.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-XML/mapping.rml.ttl index dd84f533..5a0afd86 100644 --- a/src/test/resources/negative_test_cases/RMLTC0012d-XML/mapping.rml.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-XML/mapping.rml.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0012d-XML/persons.xml"; + rml:source "persons.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/Persons/Person" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0012d-XML/persons.xml b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-XML/persons.xml similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0012d-XML/persons.xml rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0012d-XML/persons.xml diff --git a/src/test/resources/negative_test_cases/RMLTC0015b-CSV/country_en.csv b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-CSV/country_en.csv similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0015b-CSV/country_en.csv rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-CSV/country_en.csv diff --git a/src/test/resources/negative_test_cases/RMLTC0015b-CSV/country_es.csv b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-CSV/country_es.csv similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0015b-CSV/country_es.csv rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-CSV/country_es.csv diff --git a/src/test/resources/negative_test_cases/RMLTC0015b-CSV/mapping.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-CSV/mapping.ttl similarity index 87% rename from src/test/resources/negative_test_cases/RMLTC0015b-CSV/mapping.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-CSV/mapping.ttl index b53c1739..417a388c 100644 --- a/src/test/resources/negative_test_cases/RMLTC0015b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-CSV/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0015b-CSV/country_en.csv"; + rml:source "country_en.csv"; rml:referenceFormulation ql:CSV ]; @@ -30,7 +30,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0015b-CSV/country_es.csv"; + rml:source "country_es.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0015b-JSON/country_en.json b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-JSON/country_en.json similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0015b-JSON/country_en.json rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-JSON/country_en.json diff --git a/src/test/resources/negative_test_cases/RMLTC0015b-JSON/country_es.json b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-JSON/country_es.json similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0015b-JSON/country_es.json rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-JSON/country_es.json diff --git a/src/test/resources/negative_test_cases/RMLTC0015b-JSON/mapping.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-JSON/mapping.ttl similarity index 88% rename from src/test/resources/negative_test_cases/RMLTC0015b-JSON/mapping.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-JSON/mapping.ttl index edd8662b..3279f3e8 100644 --- a/src/test/resources/negative_test_cases/RMLTC0015b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-JSON/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0015b-JSON/country_en.json"; + rml:source "country_en.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" ]; @@ -31,7 +31,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0015b-JSON/country_en.json"; + rml:source "country_en.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0015b-XML/country_en.xml b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-XML/country_en.xml similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0015b-XML/country_en.xml rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-XML/country_en.xml diff --git a/src/test/resources/negative_test_cases/RMLTC0015b-XML/country_es.xml b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-XML/country_es.xml similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0015b-XML/country_es.xml rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-XML/country_es.xml diff --git a/src/test/resources/negative_test_cases/RMLTC0015b-XML/mapping.ttl b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-XML/mapping.ttl similarity index 88% rename from src/test/resources/negative_test_cases/RMLTC0015b-XML/mapping.ttl rename to src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-XML/mapping.ttl index dc057655..c1bf7a64 100644 --- a/src/test/resources/negative_test_cases/RMLTC0015b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases-invalid-mapping-file/RMLTC0015b-XML/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0015b-XML/country_en.xml"; + rml:source "country_en.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/countries/country" ]; @@ -31,7 +31,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0015b-XML/country_es.xml"; + rml:source "country_es.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/countries/country" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0002c-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases-negative/RMLTC0002e-CSV/mapping.ttl similarity index 90% rename from src/test/resources/rml-testcases/RMLTC0002c-CSV/mapping.ttl.bak rename to src/test/resources/rml-testcases-negative/RMLTC0002e-CSV/mapping.ttl index 01e6a608..b189d5c1 100644 --- a/src/test/resources/rml-testcases/RMLTC0002c-CSV/mapping.ttl.bak +++ b/src/test/resources/rml-testcases-negative/RMLTC0002e-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002c-CSV/student.csv"; + rml:source "student2.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-CSV/output.ttl b/src/test/resources/rml-testcases-negative/RMLTC0002e-CSV/output.ttl similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002e-CSV/output.ttl rename to src/test/resources/rml-testcases-negative/RMLTC0002e-CSV/output.ttl diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-CSV/student.csv b/src/test/resources/rml-testcases-negative/RMLTC0002e-CSV/student.csv similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002e-CSV/student.csv rename to src/test/resources/rml-testcases-negative/RMLTC0002e-CSV/student.csv diff --git a/src/test/resources/rml-testcases/RMLTC0002c-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases-negative/RMLTC0002e-JSON/mapping.ttl similarity index 91% rename from src/test/resources/rml-testcases/RMLTC0002c-JSON/mapping.ttl.bak rename to src/test/resources/rml-testcases-negative/RMLTC0002e-JSON/mapping.ttl index 54cf185e..1c156053 100644 --- a/src/test/resources/rml-testcases/RMLTC0002c-JSON/mapping.ttl.bak +++ b/src/test/resources/rml-testcases-negative/RMLTC0002e-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002c-JSON/student.json"; + rml:source "student2.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-JSON/output.ttl b/src/test/resources/rml-testcases-negative/RMLTC0002e-JSON/output.ttl similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002e-JSON/output.ttl rename to src/test/resources/rml-testcases-negative/RMLTC0002e-JSON/output.ttl diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-JSON/student.json b/src/test/resources/rml-testcases-negative/RMLTC0002e-JSON/student.json similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002e-JSON/student.json rename to src/test/resources/rml-testcases-negative/RMLTC0002e-JSON/student.json diff --git a/src/test/resources/rml-testcases/RMLTC0002c-XML/mapping.ttl.bak b/src/test/resources/rml-testcases-negative/RMLTC0002e-XML/mapping.ttl similarity index 91% rename from src/test/resources/rml-testcases/RMLTC0002c-XML/mapping.ttl.bak rename to src/test/resources/rml-testcases-negative/RMLTC0002e-XML/mapping.ttl index 1df25bae..abfdd229 100644 --- a/src/test/resources/rml-testcases/RMLTC0002c-XML/mapping.ttl.bak +++ b/src/test/resources/rml-testcases-negative/RMLTC0002e-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002c-XML/student.xml"; + rml:source "student2.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-XML/output.ttl b/src/test/resources/rml-testcases-negative/RMLTC0002e-XML/output.ttl similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002e-XML/output.ttl rename to src/test/resources/rml-testcases-negative/RMLTC0002e-XML/output.ttl diff --git a/src/test/resources/negative_test_cases/RMLTC0002e-XML/student.xml b/src/test/resources/rml-testcases-negative/RMLTC0002e-XML/student.xml similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002e-XML/student.xml rename to src/test/resources/rml-testcases-negative/RMLTC0002e-XML/student.xml diff --git a/src/test/resources/negative_test_cases/RMLTC0002g-JSON/mapping.ttl b/src/test/resources/rml-testcases-negative/RMLTC0002g-JSON/mapping.ttl similarity index 90% rename from src/test/resources/negative_test_cases/RMLTC0002g-JSON/mapping.ttl rename to src/test/resources/rml-testcases-negative/RMLTC0002g-JSON/mapping.ttl index 4dbf04b8..d561e70c 100644 --- a/src/test/resources/negative_test_cases/RMLTC0002g-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases-negative/RMLTC0002g-JSON/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002g-JSON/student2.json"; + rml:source "student2.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]]" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0002g-JSON/output.ttl b/src/test/resources/rml-testcases-negative/RMLTC0002g-JSON/output.ttl similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002g-JSON/output.ttl rename to src/test/resources/rml-testcases-negative/RMLTC0002g-JSON/output.ttl diff --git a/src/test/resources/negative_test_cases/RMLTC0002g-JSON/student.json b/src/test/resources/rml-testcases-negative/RMLTC0002g-JSON/student.json similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002g-JSON/student.json rename to src/test/resources/rml-testcases-negative/RMLTC0002g-JSON/student.json diff --git a/src/test/resources/negative_test_cases/RMLTC0002g-XML/mapping.ttl b/src/test/resources/rml-testcases-negative/RMLTC0002g-XML/mapping.ttl similarity index 90% rename from src/test/resources/negative_test_cases/RMLTC0002g-XML/mapping.ttl rename to src/test/resources/rml-testcases-negative/RMLTC0002g-XML/mapping.ttl index ee58a19f..548d5d59 100644 --- a/src/test/resources/negative_test_cases/RMLTC0002g-XML/mapping.ttl +++ b/src/test/resources/rml-testcases-negative/RMLTC0002g-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "negative_test_cases/RMLTC0002g-XML/student2.xml"; + rml:source "student2.xml"; rml:referenceFormulation ql:XPath; rml:iterator "$" ]; diff --git a/src/test/resources/negative_test_cases/RMLTC0002g-XML/output.ttl b/src/test/resources/rml-testcases-negative/RMLTC0002g-XML/output.ttl similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002g-XML/output.ttl rename to src/test/resources/rml-testcases-negative/RMLTC0002g-XML/output.ttl diff --git a/src/test/resources/negative_test_cases/RMLTC0002g-XML/student.xml b/src/test/resources/rml-testcases-negative/RMLTC0002g-XML/student.xml similarity index 100% rename from src/test/resources/negative_test_cases/RMLTC0002g-XML/student.xml rename to src/test/resources/rml-testcases-negative/RMLTC0002g-XML/student.xml diff --git a/src/test/resources/rml-testcases/RMLTC0000-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0000-CSV/mapping.ttl index 33da1736..ad67a5f4 100644 --- a/src/test/resources/rml-testcases/RMLTC0000-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0000-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0000-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ] ; diff --git a/src/test/resources/rml-testcases/RMLTC0000-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0000-CSV/mapping.ttl.bak deleted file mode 100644 index 33da1736..00000000 --- a/src/test/resources/rml-testcases/RMLTC0000-CSV/mapping.ttl.bak +++ /dev/null @@ -1,27 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0000-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ] ; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rml:reference "Name" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0000-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0000-JSON/mapping.ttl index b36ad519..2c58780c 100644 --- a/src/test/resources/rml-testcases/RMLTC0000-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0000-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0000-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ] ; diff --git a/src/test/resources/rml-testcases/RMLTC0000-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0000-JSON/mapping.ttl.bak deleted file mode 100644 index b36ad519..00000000 --- a/src/test/resources/rml-testcases/RMLTC0000-JSON/mapping.ttl.bak +++ /dev/null @@ -1,28 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0000-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ] ; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rml:reference "Name" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0000-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0000-XML/mapping.ttl index 7220092b..d9278416 100644 --- a/src/test/resources/rml-testcases/RMLTC0000-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0000-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0000-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ] ; diff --git a/src/test/resources/rml-testcases/RMLTC0000-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0000-XML/mapping.ttl.bak deleted file mode 100644 index 7220092b..00000000 --- a/src/test/resources/rml-testcases/RMLTC0000-XML/mapping.ttl.bak +++ /dev/null @@ -1,28 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0000-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ] ; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rml:reference "Name" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0001a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0001a-CSV/mapping.ttl index 251574db..330858ba 100644 --- a/src/test/resources/rml-testcases/RMLTC0001a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0001a-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0001a-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0001a-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0001a-CSV/mapping.ttl.bak deleted file mode 100644 index 251574db..00000000 --- a/src/test/resources/rml-testcases/RMLTC0001a-CSV/mapping.ttl.bak +++ /dev/null @@ -1,29 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0001a-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. - - diff --git a/src/test/resources/rml-testcases/RMLTC0001a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0001a-JSON/mapping.ttl index 2f62685a..5c950c64 100644 --- a/src/test/resources/rml-testcases/RMLTC0001a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0001a-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0001a-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0001a-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0001a-JSON/mapping.ttl.bak deleted file mode 100644 index 2f62685a..00000000 --- a/src/test/resources/rml-testcases/RMLTC0001a-JSON/mapping.ttl.bak +++ /dev/null @@ -1,30 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0001a-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Name}" - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. - - diff --git a/src/test/resources/rml-testcases/RMLTC0001a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0001a-XML/mapping.ttl index a765b8d8..937f71fc 100644 --- a/src/test/resources/rml-testcases/RMLTC0001a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0001a-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0001a-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0001b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0001b-CSV/mapping.ttl index 9cc33471..33133e60 100644 --- a/src/test/resources/rml-testcases/RMLTC0001b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0001b-CSV/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0001b-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0001b-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0001b-CSV/mapping.ttl.bak deleted file mode 100644 index 9cc33471..00000000 --- a/src/test/resources/rml-testcases/RMLTC0001b-CSV/mapping.ttl.bak +++ /dev/null @@ -1,28 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0001b-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "{Name}"; - rr:termType rr:BlankNode - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0001b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0001b-JSON/mapping.ttl index 516e6b36..55cb59c9 100644 --- a/src/test/resources/rml-testcases/RMLTC0001b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0001b-JSON/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0001b-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0001b-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0001b-JSON/mapping.ttl.bak deleted file mode 100644 index 516e6b36..00000000 --- a/src/test/resources/rml-testcases/RMLTC0001b-JSON/mapping.ttl.bak +++ /dev/null @@ -1,29 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0001b-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "{Name}"; - rr:termType rr:BlankNode - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0001b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0001b-XML/mapping.ttl index e79f0c20..97418149 100644 --- a/src/test/resources/rml-testcases/RMLTC0001b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0001b-XML/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0001b-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0001b-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0001b-XML/mapping.ttl.bak deleted file mode 100644 index e79f0c20..00000000 --- a/src/test/resources/rml-testcases/RMLTC0001b-XML/mapping.ttl.bak +++ /dev/null @@ -1,29 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0001b-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "{Name}"; - rr:termType rr:BlankNode - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0002a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0002a-CSV/mapping.ttl index 7e569f17..c21aa51f 100644 --- a/src/test/resources/rml-testcases/RMLTC0002a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0002a-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002a-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0002a-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0002a-CSV/mapping.ttl.bak deleted file mode 100644 index 7e569f17..00000000 --- a/src/test/resources/rml-testcases/RMLTC0002a-CSV/mapping.ttl.bak +++ /dev/null @@ -1,29 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002a-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - rr:class foaf:Person - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "ID" ] - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ rml:reference "Name" ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0002a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0002a-JSON/mapping.ttl index d5406e67..31f8da3f 100644 --- a/src/test/resources/rml-testcases/RMLTC0002a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0002a-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002a-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0002a-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0002a-JSON/mapping.ttl.bak deleted file mode 100644 index d5406e67..00000000 --- a/src/test/resources/rml-testcases/RMLTC0002a-JSON/mapping.ttl.bak +++ /dev/null @@ -1,30 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002a-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - rr:class foaf:Person - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "ID" ] - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ rml:reference "Name" ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0002a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0002a-XML/mapping.ttl index e773d068..1db40ec7 100644 --- a/src/test/resources/rml-testcases/RMLTC0002a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0002a-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002a-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0002a-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0002a-XML/mapping.ttl.bak deleted file mode 100644 index e773d068..00000000 --- a/src/test/resources/rml-testcases/RMLTC0002a-XML/mapping.ttl.bak +++ /dev/null @@ -1,30 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002a-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{ID}/{Name}"; - rr:class foaf:Person - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "ID" ] - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ rml:reference "Name" ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0002b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0002b-CSV/mapping.ttl index 937c9bef..e8181fde 100644 --- a/src/test/resources/rml-testcases/RMLTC0002b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0002b-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0002b-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0002b-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0002b-CSV/mapping.ttl.bak deleted file mode 100644 index 937c9bef..00000000 --- a/src/test/resources/rml-testcases/RMLTC0002b-CSV/mapping.ttl.bak +++ /dev/null @@ -1,25 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0002b-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "students{ID}"; - rr:termType rr:BlankNode - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "Name" ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0002b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0002b-JSON/mapping.ttl index 7353cc34..bd512278 100644 --- a/src/test/resources/rml-testcases/RMLTC0002b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0002b-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0002b-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0002b-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0002b-JSON/mapping.ttl.bak deleted file mode 100644 index 7353cc34..00000000 --- a/src/test/resources/rml-testcases/RMLTC0002b-JSON/mapping.ttl.bak +++ /dev/null @@ -1,26 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0002b-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "students{ID}"; - rr:termType rr:BlankNode - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "Name" ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0002b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0002b-XML/mapping.ttl index ef23759b..9ef0c3c0 100644 --- a/src/test/resources/rml-testcases/RMLTC0002b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0002b-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0002b-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0002b-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0002b-XML/mapping.ttl.bak deleted file mode 100644 index ef23759b..00000000 --- a/src/test/resources/rml-testcases/RMLTC0002b-XML/mapping.ttl.bak +++ /dev/null @@ -1,26 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0002b-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "students{ID}"; - rr:termType rr:BlankNode - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "Name" ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0002c-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0002c-CSV/mapping.ttl index 01e6a608..144f3850 100644 --- a/src/test/resources/rml-testcases/RMLTC0002c-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0002c-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002c-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0002c-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0002c-JSON/mapping.ttl index 54cf185e..921cd4c6 100644 --- a/src/test/resources/rml-testcases/RMLTC0002c-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0002c-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002c-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0002c-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0002c-XML/mapping.ttl index 1df25bae..e0dda06e 100644 --- a/src/test/resources/rml-testcases/RMLTC0002c-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0002c-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0002c-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0003c-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0003c-CSV/mapping.ttl index 0108342a..764573ee 100644 --- a/src/test/resources/rml-testcases/RMLTC0003c-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0003c-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0003c-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0003c-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0003c-CSV/mapping.ttl.bak deleted file mode 100644 index 0108342a..00000000 --- a/src/test/resources/rml-testcases/RMLTC0003c-CSV/mapping.ttl.bak +++ /dev/null @@ -1,27 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0003c-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{FirstName} {LastName}"; - rr:termType rr:Literal; - ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0003c-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0003c-JSON/mapping.ttl index d96358b6..36727fd0 100644 --- a/src/test/resources/rml-testcases/RMLTC0003c-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0003c-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0003c-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0003c-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0003c-JSON/mapping.ttl.bak deleted file mode 100644 index d96358b6..00000000 --- a/src/test/resources/rml-testcases/RMLTC0003c-JSON/mapping.ttl.bak +++ /dev/null @@ -1,28 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0003c-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{FirstName} {LastName}"; - rr:termType rr:Literal; - ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0003c-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0003c-XML/mapping.ttl index f3bb3b0b..0201038f 100644 --- a/src/test/resources/rml-testcases/RMLTC0003c-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0003c-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0003c-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0003c-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0003c-XML/mapping.ttl.bak deleted file mode 100644 index f3bb3b0b..00000000 --- a/src/test/resources/rml-testcases/RMLTC0003c-XML/mapping.ttl.bak +++ /dev/null @@ -1,28 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0003c-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rr:template "{FirstName} {LastName}"; - rr:termType rr:Literal; - ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0004a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0004a-CSV/mapping.ttl index c5b12075..1d26bf00 100644 --- a/src/test/resources/rml-testcases/RMLTC0004a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0004a-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0004a-CSV/student_sport.csv"; + rml:source "student_sport.csv"; rml:referenceFormulation ql:CSV ]; @@ -28,7 +28,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0004a-CSV/student_sport.csv"; + rml:source "student_sport.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0004a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0004a-JSON/mapping.ttl index e36b6e3d..56dbc7d8 100644 --- a/src/test/resources/rml-testcases/RMLTC0004a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0004a-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0004a-JSON/student_sport.json"; + rml:source "student_sport.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; @@ -29,7 +29,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0004a-JSON/student_sport.json"; + rml:source "student_sport.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0004a-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0004a-JSON/mapping.ttl.bak deleted file mode 100644 index e36b6e3d..00000000 --- a/src/test/resources/rml-testcases/RMLTC0004a-JSON/mapping.ttl.bak +++ /dev/null @@ -1,47 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0004a-JSON/student_sport.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Student}"; - rr:class ex:Student - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rml:reference "Student" - ] - ]. - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0004a-JSON/student_sport.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/{Sport}"; - rr:class ex:Sport - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rml:reference "Sport" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0004a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0004a-XML/mapping.ttl index a88d547e..96553a92 100644 --- a/src/test/resources/rml-testcases/RMLTC0004a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0004a-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0004a-XML/student_sport.xml"; + rml:source "student_sport.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; @@ -29,7 +29,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0004a-XML/student_sport.xml"; + rml:source "student_sport.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0005a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0005a-CSV/mapping.ttl index f4b223f7..8474bfbb 100644 --- a/src/test/resources/rml-testcases/RMLTC0005a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0005a-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0005a-CSV/ious.csv"; + rml:source "ious.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0005a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0005a-JSON/mapping.ttl index 758a8f26..afa6f260 100644 --- a/src/test/resources/rml-testcases/RMLTC0005a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0005a-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0005a-JSON/ious.json"; + rml:source "ious.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0005a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0005a-XML/mapping.ttl index 5e500039..1d9c4083 100644 --- a/src/test/resources/rml-testcases/RMLTC0005a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0005a-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0005a-XML/ious.xml"; + rml:source "ious.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/persons/person" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0006a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0006a-CSV/mapping.ttl index 455befc8..7e6be247 100644 --- a/src/test/resources/rml-testcases/RMLTC0006a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0006a-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0006a-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0006a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0006a-JSON/mapping.ttl index 303da93b..9a95665a 100644 --- a/src/test/resources/rml-testcases/RMLTC0006a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0006a-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0006a-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0006a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0006a-XML/mapping.ttl index fa217e49..f89ee47d 100644 --- a/src/test/resources/rml-testcases/RMLTC0006a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0006a-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0006a-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007a-CSV/mapping.ttl index ab7b8cd6..9845b799 100644 --- a/src/test/resources/rml-testcases/RMLTC0007a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007a-CSV/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007a-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007a-JSON/mapping.ttl index 203cbee6..a64e94e8 100644 --- a/src/test/resources/rml-testcases/RMLTC0007a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007a-JSON/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007a-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007a-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007a-JSON/mapping.ttl.bak deleted file mode 100644 index e257e69d..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007a-JSON/mapping.ttl.bak +++ /dev/null @@ -1,26 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007a-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}" - ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type; - rr:object foaf:Person; - ]. - - diff --git a/src/test/resources/rml-testcases/RMLTC0007a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007a-XML/mapping.ttl index 944aa0ca..64163067 100644 --- a/src/test/resources/rml-testcases/RMLTC0007a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007a-XML/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007a-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007b-CSV/mapping.ttl index 2e499f1c..04eaba04 100644 --- a/src/test/resources/rml-testcases/RMLTC0007b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007b-CSV/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007b-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007b-JSON/mapping.ttl index 7c0f9306..9c327a13 100644 --- a/src/test/resources/rml-testcases/RMLTC0007b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007b-JSON/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007b-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007b-XML/mapping.ttl index 033c2164..7d7cd660 100644 --- a/src/test/resources/rml-testcases/RMLTC0007b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007b-XML/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007b-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007c-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007c-CSV/mapping.ttl index 5040ba47..1ba21210 100644 --- a/src/test/resources/rml-testcases/RMLTC0007c-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007c-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007c-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007c-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007c-CSV/mapping.ttl.bak deleted file mode 100644 index 5040ba47..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007c-CSV/mapping.ttl.bak +++ /dev/null @@ -1,25 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007c-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}"; - rr:class foaf:Person, ex:Student - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "FirstName" ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0007c-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007c-JSON/mapping.ttl index 75d09ad2..14b2b998 100644 --- a/src/test/resources/rml-testcases/RMLTC0007c-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007c-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007c-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007c-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007c-JSON/mapping.ttl.bak deleted file mode 100644 index 75d09ad2..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007c-JSON/mapping.ttl.bak +++ /dev/null @@ -1,28 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007c-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}"; - rr:class foaf:Person, ex:Student - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "FirstName" ] - ]. - - - diff --git a/src/test/resources/rml-testcases/RMLTC0007c-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007c-XML/mapping.ttl index 88bab61b..dd326a68 100644 --- a/src/test/resources/rml-testcases/RMLTC0007c-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007c-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007c-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007c-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007c-XML/mapping.ttl.bak deleted file mode 100644 index 88bab61b..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007c-XML/mapping.ttl.bak +++ /dev/null @@ -1,26 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007c-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}"; - rr:class foaf:Person, ex:Student - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "FirstName" ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0007d-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007d-CSV/mapping.ttl index 953fd3e4..faa83b7d 100644 --- a/src/test/resources/rml-testcases/RMLTC0007d-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007d-CSV/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007d-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007d-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007d-CSV/mapping.ttl.bak deleted file mode 100644 index 953fd3e4..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007d-CSV/mapping.ttl.bak +++ /dev/null @@ -1,35 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix rdf: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007d-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}" - ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type; - rr:object foaf:Person; - ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type; - rr:object ex:Student; - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "FirstName" ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0007d-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007d-JSON/mapping.ttl index 064ed5ab..7738c623 100644 --- a/src/test/resources/rml-testcases/RMLTC0007d-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007d-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007d-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007d-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007d-JSON/mapping.ttl.bak deleted file mode 100644 index 93adffe1..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007d-JSON/mapping.ttl.bak +++ /dev/null @@ -1,37 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007d-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}" - ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type; - rr:object foaf:Person; - ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type; - rr:object ex:Student; - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "FirstName" ] - ]. - - - diff --git a/src/test/resources/rml-testcases/RMLTC0007d-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007d-XML/mapping.ttl index d6299195..06156b45 100644 --- a/src/test/resources/rml-testcases/RMLTC0007d-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007d-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007d-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007d-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007d-XML/mapping.ttl.bak deleted file mode 100644 index d6299195..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007d-XML/mapping.ttl.bak +++ /dev/null @@ -1,37 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix rdf: . - -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007d-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}" - ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type; - rr:object foaf:Person; - ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type; - rr:object ex:Student; - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ rml:reference "FirstName" ] - ]. - diff --git a/src/test/resources/rml-testcases/RMLTC0007e-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007e-CSV/mapping.ttl index e6c72c49..d234713e 100644 --- a/src/test/resources/rml-testcases/RMLTC0007e-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007e-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007e-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007e-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007e-JSON/mapping.ttl index 708cd38b..e1c0b6e7 100644 --- a/src/test/resources/rml-testcases/RMLTC0007e-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007e-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007e-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007e-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007e-XML/mapping.ttl index 03f581ee..2b10803a 100644 --- a/src/test/resources/rml-testcases/RMLTC0007e-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007e-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007e-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007f-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007f-CSV/mapping.ttl index ce9a4b1d..eebc0bbf 100644 --- a/src/test/resources/rml-testcases/RMLTC0007f-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007f-CSV/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007f-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007f-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007f-JSON/mapping.ttl index 19ca129b..f3d786a1 100644 --- a/src/test/resources/rml-testcases/RMLTC0007f-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007f-JSON/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007f-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007f-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007f-XML/mapping.ttl index f6055b97..690f779d 100644 --- a/src/test/resources/rml-testcases/RMLTC0007f-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007f-XML/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007f-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007g-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007g-CSV/mapping.ttl index 012ab7d7..96e9ec1c 100644 --- a/src/test/resources/rml-testcases/RMLTC0007g-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007g-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007g-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007g-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007g-CSV/mapping.ttl.bak deleted file mode 100644 index 012ab7d7..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007g-CSV/mapping.ttl.bak +++ /dev/null @@ -1,26 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007g-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}"; - rr:graph rr:defaultGraph - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "FirstName" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0007g-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007g-JSON/mapping.ttl index 9d513cf4..64ab7461 100644 --- a/src/test/resources/rml-testcases/RMLTC0007g-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007g-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007g-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007g-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007g-JSON/mapping.ttl.bak deleted file mode 100644 index 9d513cf4..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007g-JSON/mapping.ttl.bak +++ /dev/null @@ -1,30 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007g-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}"; - rr:graph rr:defaultGraph - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "FirstName" - ] - ]. - - - diff --git a/src/test/resources/rml-testcases/RMLTC0007g-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007g-XML/mapping.ttl index 759cdd24..10d22c01 100644 --- a/src/test/resources/rml-testcases/RMLTC0007g-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007g-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007g-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007g-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007g-XML/mapping.ttl.bak deleted file mode 100644 index 759cdd24..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007g-XML/mapping.ttl.bak +++ /dev/null @@ -1,27 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007g-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}"; - rr:graph rr:defaultGraph - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "FirstName" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0007h-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007h-CSV/mapping.ttl index 165e84af..b1727bf0 100644 --- a/src/test/resources/rml-testcases/RMLTC0007h-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007h-CSV/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007h-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007h-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007h-CSV/mapping.ttl.bak deleted file mode 100644 index 165e84af..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007h-CSV/mapping.ttl.bak +++ /dev/null @@ -1,26 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007h-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}"; - rr:graph [ rml:reference "Name"; rr:termType rr:Literal; ] - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0007h-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007h-JSON/mapping.ttl index a1e0d1da..de6d4799 100644 --- a/src/test/resources/rml-testcases/RMLTC0007h-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007h-JSON/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007h-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007h-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007h-JSON/mapping.ttl.bak deleted file mode 100644 index a1e0d1da..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007h-JSON/mapping.ttl.bak +++ /dev/null @@ -1,30 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007h-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}"; - rr:graph [ rml:reference "Name"; rr:termType rr:Literal; ] - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. - - - diff --git a/src/test/resources/rml-testcases/RMLTC0007h-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0007h-XML/mapping.ttl index 1bf378c5..be342627 100644 --- a/src/test/resources/rml-testcases/RMLTC0007h-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0007h-XML/mapping.ttl @@ -9,7 +9,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007h-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0007h-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0007h-XML/mapping.ttl.bak deleted file mode 100644 index 1bf378c5..00000000 --- a/src/test/resources/rml-testcases/RMLTC0007h-XML/mapping.ttl.bak +++ /dev/null @@ -1,27 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0007h-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}/{FirstName}"; - rr:graph [ rml:reference "Name"; rr:termType rr:Literal; ] - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name; - rr:objectMap [ - rml:reference "Name" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0008a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0008a-CSV/mapping.ttl index 48e4dd8b..18ff6c45 100644 --- a/src/test/resources/rml-testcases/RMLTC0008a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0008a-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008a-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0008a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0008a-JSON/mapping.ttl index 2a948d96..cd63e51f 100644 --- a/src/test/resources/rml-testcases/RMLTC0008a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0008a-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008a-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0008a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0008a-XML/mapping.ttl index 6baa5a98..7f729ea7 100644 --- a/src/test/resources/rml-testcases/RMLTC0008a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0008a-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008a-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0008b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0008b-CSV/mapping.ttl index b2cee72b..0dcf7ff3 100644 --- a/src/test/resources/rml-testcases/RMLTC0008b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0008b-CSV/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; @@ -27,7 +27,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0008b-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0008b-CSV/mapping.ttl.bak deleted file mode 100644 index b2cee72b..00000000 --- a/src/test/resources/rml-testcases/RMLTC0008b-CSV/mapping.ttl.bak +++ /dev/null @@ -1,60 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix rdf: . - -@prefix activity: . -@base . - - - a rr:TriplesMap; - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "http://example.com/{Sport}" ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type ; - rr:object activity:Sport ; - ] . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "http://example.com/Student/{ID}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type ; - rr:object foaf:Person ; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "ID"; ] - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ rml:reference "Name" ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:Sport ; - rr:objectMap - ] . - - - - a rr:RefObjectMap; - rr:parentTriplesMap . - diff --git a/src/test/resources/rml-testcases/RMLTC0008b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0008b-JSON/mapping.ttl index 68daa599..bcb7c792 100644 --- a/src/test/resources/rml-testcases/RMLTC0008b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0008b-JSON/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; @@ -28,7 +28,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0008b-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0008b-JSON/mapping.ttl.bak deleted file mode 100644 index 68daa599..00000000 --- a/src/test/resources/rml-testcases/RMLTC0008b-JSON/mapping.ttl.bak +++ /dev/null @@ -1,62 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@prefix rdf: . - -@base . - - - a rr:TriplesMap; - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ rr:template "http://example.com/{Sport}" ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type ; - rr:object activity:Sport ; - ] . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ rr:template "http://example.com/Student/{ID}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type ; - rr:object foaf:Person ; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "ID"; ] - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ rml:reference "Name" ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:Sport ; - rr:objectMap - ] . - - - - a rr:RefObjectMap; - rr:parentTriplesMap . - diff --git a/src/test/resources/rml-testcases/RMLTC0008b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0008b-XML/mapping.ttl index 0ffff561..6e0d62e1 100644 --- a/src/test/resources/rml-testcases/RMLTC0008b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0008b-XML/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; @@ -28,7 +28,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0008b-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0008b-XML/mapping.ttl.bak deleted file mode 100644 index 0ffff561..00000000 --- a/src/test/resources/rml-testcases/RMLTC0008b-XML/mapping.ttl.bak +++ /dev/null @@ -1,61 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@prefix rdf: . - -@base . - - - a rr:TriplesMap; - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ rr:template "http://example.com/{Sport}" ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type ; - rr:object activity:Sport ; - ] . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008b-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ rr:template "http://example.com/Student/{ID}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate rdf:type ; - rr:object foaf:Person ; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id ; - rr:objectMap [ rml:reference "ID"; ] - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ rml:reference "Name" ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:Sport ; - rr:objectMap - ] . - - - - a rr:RefObjectMap; - rr:parentTriplesMap . diff --git a/src/test/resources/rml-testcases/RMLTC0008c-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0008c-CSV/mapping.ttl index 11ebc207..43dc9a5b 100644 --- a/src/test/resources/rml-testcases/RMLTC0008c-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0008c-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008c-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0008c-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0008c-CSV/mapping.ttl.bak deleted file mode 100644 index 11ebc207..00000000 --- a/src/test/resources/rml-testcases/RMLTC0008c-CSV/mapping.ttl.bak +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008c-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "http://example.com/Student/{ID}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:predicate ex:name ; - rr:objectMap [ rml:reference "Name" ] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0008c-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0008c-JSON/mapping.ttl index 9b9274c1..b642a14b 100644 --- a/src/test/resources/rml-testcases/RMLTC0008c-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0008c-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008c-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0008c-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0008c-JSON/mapping.ttl.bak deleted file mode 100644 index 9b9274c1..00000000 --- a/src/test/resources/rml-testcases/RMLTC0008c-JSON/mapping.ttl.bak +++ /dev/null @@ -1,25 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008c-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ rr:template "http://example.com/Student/{ID}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:predicate ex:name ; - rr:objectMap [ rml:reference "Name" ] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0008c-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0008c-XML/mapping.ttl index 51ad3ddd..1971d275 100644 --- a/src/test/resources/rml-testcases/RMLTC0008c-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0008c-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008c-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0008c-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0008c-XML/mapping.ttl.bak deleted file mode 100644 index 51ad3ddd..00000000 --- a/src/test/resources/rml-testcases/RMLTC0008c-XML/mapping.ttl.bak +++ /dev/null @@ -1,25 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0008c-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ rr:template "http://example.com/Student/{ID}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:predicate ex:name ; - rr:objectMap [ rml:reference "Name" ] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0009a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0009a-CSV/mapping.ttl index 2d394ede..2d38c327 100644 --- a/src/test/resources/rml-testcases/RMLTC0009a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0009a-CSV/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; @@ -40,7 +40,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-CSV/sport.csv"; + rml:source "sport.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0009a-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0009a-CSV/mapping.ttl.bak deleted file mode 100644 index 2d394ede..00000000 --- a/src/test/resources/rml-testcases/RMLTC0009a-CSV/mapping.ttl.bak +++ /dev/null @@ -1,52 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@prefix rdfs: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "http://example.com/resource/student_{ID}" ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ rml:reference "Name" ] - ] ; - - rr:predicateObjectMap [ - rr:predicate ; - rr:objectMap [ - a rr:RefObjectMap ; - rr:parentTriplesMap ; - rr:joinCondition [ - rr:child "Sport" ; - rr:parent "ID" ; - ] - ] - ] . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-CSV/sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "http://example.com/resource/sport_{ID}" ]; - - rr:predicateObjectMap [ - rr:predicate rdfs:label ; - rr:objectMap [ rml:reference "Name" ]; - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0009a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0009a-JSON/mapping.ttl index e0b45c01..247540c4 100644 --- a/src/test/resources/rml-testcases/RMLTC0009a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0009a-JSON/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; @@ -41,7 +41,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-JSON/sport.json"; + rml:source "sport.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.sports[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0009a-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0009a-JSON/mapping.ttl.bak deleted file mode 100644 index e0b45c01..00000000 --- a/src/test/resources/rml-testcases/RMLTC0009a-JSON/mapping.ttl.bak +++ /dev/null @@ -1,54 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@prefix rdfs: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ rr:template "http://example.com/resource/student_{ID}" ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ rml:reference "Name" ] - ] ; - - rr:predicateObjectMap [ - rr:predicate ; - rr:objectMap [ - a rr:RefObjectMap ; - rr:parentTriplesMap ; - rr:joinCondition [ - rr:child "Sport" ; - rr:parent "ID" ; - ] - ] - ] . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-JSON/sport.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.sports[*]" - ]; - - rr:subjectMap [ rr:template "http://example.com/resource/sport_{ID}" ]; - - rr:predicateObjectMap [ - rr:predicate rdfs:label ; - rr:objectMap [ rml:reference "Name" ]; - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0009a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0009a-XML/mapping.ttl index 041eae6e..e231a415 100644 --- a/src/test/resources/rml-testcases/RMLTC0009a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0009a-XML/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; @@ -41,7 +41,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-XML/sport.xml"; + rml:source "sport.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/sports/sport" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0009a-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0009a-XML/mapping.ttl.bak deleted file mode 100644 index 041eae6e..00000000 --- a/src/test/resources/rml-testcases/RMLTC0009a-XML/mapping.ttl.bak +++ /dev/null @@ -1,54 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@prefix rdfs: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ rr:template "http://example.com/resource/student_{ID}" ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ rml:reference "Name" ] - ] ; - - rr:predicateObjectMap [ - rr:predicate ; - rr:objectMap [ - a rr:RefObjectMap ; - rr:parentTriplesMap ; - rr:joinCondition [ - rr:child "Sport" ; - rr:parent "ID" ; - ] - ] - ] . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0009a-XML/sport.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/sports/sport" - ]; - - rr:subjectMap [ rr:template "http://example.com/resource/sport_{ID}" ]; - - rr:predicateObjectMap [ - rr:predicate rdfs:label ; - rr:objectMap [ rml:reference "Name" ]; - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0010a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0010a-CSV/mapping.ttl index 80440362..2967178a 100644 --- a/src/test/resources/rml-testcases/RMLTC0010a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0010a-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010a-CSV/country info.csv"; + rml:source "country info.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0010a-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0010a-CSV/mapping.ttl.bak deleted file mode 100644 index 80440362..00000000 --- a/src/test/resources/rml-testcases/RMLTC0010a-CSV/mapping.ttl.bak +++ /dev/null @@ -1,23 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010a-CSV/country info.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "http://example.com/{Country Code}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:name ; - rr:objectMap [ rml:reference "Name" ] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0010a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0010a-JSON/mapping.ttl index 6c4d267c..b7b84993 100644 --- a/src/test/resources/rml-testcases/RMLTC0010a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0010a-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010a-JSON/country info.json"; + rml:source "country info.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0010a-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0010a-JSON/mapping.ttl.bak deleted file mode 100644 index 6c4d267c..00000000 --- a/src/test/resources/rml-testcases/RMLTC0010a-JSON/mapping.ttl.bak +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010a-JSON/country info.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.countries[*]" - ]; - - rr:subjectMap [ rr:template "http://example.com/{Country Code}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:name ; - rr:objectMap [ rml:reference "Name" ] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0010b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0010b-CSV/mapping.ttl index 6e4dbe4e..d1161091 100644 --- a/src/test/resources/rml-testcases/RMLTC0010b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0010b-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010b-CSV/country info.csv"; + rml:source "country info.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0010b-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0010b-CSV/mapping.ttl.bak deleted file mode 100644 index 6e4dbe4e..00000000 --- a/src/test/resources/rml-testcases/RMLTC0010b-CSV/mapping.ttl.bak +++ /dev/null @@ -1,23 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010b-CSV/country info.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "http://example.com/{Country Code}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:name ; - rr:objectMap [ rml:reference "Name" ] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0010b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0010b-JSON/mapping.ttl index 5780b3fc..a9f9e1c5 100644 --- a/src/test/resources/rml-testcases/RMLTC0010b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0010b-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010b-JSON/country info.json"; + rml:source "country info.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" diff --git a/src/test/resources/rml-testcases/RMLTC0010b-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0010b-JSON/mapping.ttl.bak deleted file mode 100644 index fed1de22..00000000 --- a/src/test/resources/rml-testcases/RMLTC0010b-JSON/mapping.ttl.bak +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010b-JSON/country info.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.countries[*]" - ]; - - rr:subjectMap [ rr:template "http://example.com/{Country Code}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:name ; - rr:objectMap [ rml:reference "Name" ] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0010b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0010b-XML/mapping.ttl index 7aec1f43..e5671357 100644 --- a/src/test/resources/rml-testcases/RMLTC0010b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0010b-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010b-XML/country info.xml"; + rml:source "country info.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/countries/country" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0010b-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0010b-XML/mapping.ttl.bak deleted file mode 100644 index 7aec1f43..00000000 --- a/src/test/resources/rml-testcases/RMLTC0010b-XML/mapping.ttl.bak +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010b-XML/country info.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/countries/country" - ]; - - rr:subjectMap [ rr:template "http://example.com/{CountryCode}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:name ; - rr:objectMap [ rml:reference "Name" ] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0010c-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0010c-CSV/mapping.ttl index 64644aeb..54a96d8a 100644 --- a/src/test/resources/rml-testcases/RMLTC0010c-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0010c-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-CSV/country info.csv"; + rml:source "country info.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak deleted file mode 100644 index 250a85dd..00000000 --- a/src/test/resources/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak +++ /dev/null @@ -1,23 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-CSV/country info.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "http://example.com/{Country Code}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:code ; - rr:objectMap [ rr:template "\{\{\{ {ISO 3166} \}\}\}"; rr:termType rr:Literal] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0010c-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0010c-JSON/mapping.ttl index 576de2ab..680243a4 100644 --- a/src/test/resources/rml-testcases/RMLTC0010c-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0010c-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-JSON/country info.json"; + rml:source "country info.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak deleted file mode 100644 index 04fa74dd..00000000 --- a/src/test/resources/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-JSON/country info.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.countries[*]" - ]; - - rr:subjectMap [ rr:template "http://example.com/{Country Code}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:code ; - rr:objectMap [ rr:template "\{\{\{ {ISO 3166} \}\}\}"; rr:termType rr:Literal] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0010c-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0010c-XML/mapping.ttl index 2d2c9db5..c674d218 100644 --- a/src/test/resources/rml-testcases/RMLTC0010c-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0010c-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-XML/country info.xml"; + rml:source "country info.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/countries/country" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak deleted file mode 100644 index 157c218f..00000000 --- a/src/test/resources/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak +++ /dev/null @@ -1,24 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@prefix activity: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0010c-XML/country info.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/countries/country" - ]; - - rr:subjectMap [ rr:template "http://example.com/{CountryCode}/{Name}" ]; - - rr:predicateObjectMap [ - rr:predicate ex:code ; - rr:objectMap [ rr:template "\{\{\{ {ISO 3166} \}\}\}"; rr:termType rr:Literal] - ] . diff --git a/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl index 7021f6f4..1e0410b2 100644 --- a/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; @@ -37,7 +37,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; + rml:source "sport.csv"; rml:referenceFormulation ql:CSV ]; @@ -63,7 +63,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; + rml:source "student_sport.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak deleted file mode 100644 index 7021f6f4..00000000 --- a/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak +++ /dev/null @@ -1,79 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:firstName; - rr:objectMap [ - rml:reference "FirstName" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:lastName; - rr:objectMap [ - rml:reference "LastName" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/sport/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id; - rr:objectMap [ - rml:reference "ID" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:description; - rr:objectMap [ - rml:reference "Description" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID_Student}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:plays; - rr:objectMap [ - rr:template "http://example.com/sport/{ID_Sport}" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl index e5f8cbda..32936fdd 100644 --- a/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; @@ -38,7 +38,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-JSON/sport.json"; + rml:source "sport.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.sports[*]" ]; @@ -65,7 +65,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-JSON/student_sport.json"; + rml:source "student_sport.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.links[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak deleted file mode 100644 index e5f8cbda..00000000 --- a/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak +++ /dev/null @@ -1,82 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:firstName; - rr:objectMap [ - rml:reference "FirstName" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:lastName; - rr:objectMap [ - rml:reference "LastName" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-JSON/sport.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.sports[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/sport/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id; - rr:objectMap [ - rml:reference "ID" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:description; - rr:objectMap [ - rml:reference "Description" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-JSON/student_sport.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.links[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID_Student}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:plays; - rr:objectMap [ - rr:template "http://example.com/sport/{ID_Sport}" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl index f9181c8d..d055d85f 100644 --- a/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/Students/Student" ]; @@ -38,7 +38,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-XML/sport.xml"; + rml:source "sport.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/Sports/Sport" ]; @@ -65,7 +65,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-XML/student_sport.xml"; + rml:source "student_sport.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/links/link" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak deleted file mode 100644 index f9181c8d..00000000 --- a/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak +++ /dev/null @@ -1,82 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-XML/student.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/Students/Student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:firstName; - rr:objectMap [ - rml:reference "FirstName" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:lastName; - rr:objectMap [ - rml:reference "LastName" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-XML/sport.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/Sports/Sport" - ]; - - rr:subjectMap [ - rr:template "http://example.com/sport/{ID}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:id; - rr:objectMap [ - rml:reference "ID" - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:description; - rr:objectMap [ - rml:reference "Description" - ] - ]. - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC0011b-XML/student_sport.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/links/link" - ]; - - rr:subjectMap [ - rr:template "http://example.com/student/{ID_Student}"; - ]; - - rr:predicateObjectMap [ - rr:predicate ex:plays; - rr:objectMap [ - rr:template "http://example.com/sport/{ID_Sport}" - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0012a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0012a-CSV/mapping.ttl index b875af25..fd3eb6fc 100644 --- a/src/test/resources/rml-testcases/RMLTC0012a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0012a-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-CSV/persons.csv"; + rml:source "persons.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0012a-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0012a-CSV/mapping.ttl.bak deleted file mode 100644 index b875af25..00000000 --- a/src/test/resources/rml-testcases/RMLTC0012a-CSV/mapping.ttl.bak +++ /dev/null @@ -1,33 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-CSV/persons.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0012a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0012a-JSON/mapping.ttl index 09638b19..b969e995 100644 --- a/src/test/resources/rml-testcases/RMLTC0012a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0012a-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-JSON/persons.json"; + rml:source "persons.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0012a-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0012a-JSON/mapping.ttl.bak deleted file mode 100644 index 09638b19..00000000 --- a/src/test/resources/rml-testcases/RMLTC0012a-JSON/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-JSON/persons.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.persons[*]" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0012a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0012a-XML/mapping.ttl index 9e55c5d8..296bf515 100644 --- a/src/test/resources/rml-testcases/RMLTC0012a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0012a-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-XML/persons.xml"; + rml:source "persons.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/Persons/Person" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0012a-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0012a-XML/mapping.ttl.bak deleted file mode 100644 index 9e55c5d8..00000000 --- a/src/test/resources/rml-testcases/RMLTC0012a-XML/mapping.ttl.bak +++ /dev/null @@ -1,34 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012a-XML/persons.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/Persons/Person" - ]; - - rr:subjectMap [ rr:template "{fname}{lname}{amount}"; rr:termType rr:BlankNode; ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:amount ; - rr:objectMap [ - rml:reference "amount"; - ] - ]. diff --git a/src/test/resources/rml-testcases/RMLTC0012b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0012b-CSV/mapping.ttl index 71819182..0e962c75 100644 --- a/src/test/resources/rml-testcases/RMLTC0012b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0012b-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-CSV/persons.csv"; + rml:source "persons.csv"; rml:referenceFormulation ql:CSV ]; @@ -33,7 +33,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-CSV/lives.csv"; + rml:source "lives.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0012b-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0012b-CSV/mapping.ttl.bak deleted file mode 100644 index 71819182..00000000 --- a/src/test/resources/rml-testcases/RMLTC0012b-CSV/mapping.ttl.bak +++ /dev/null @@ -1,52 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-CSV/persons.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "{fname}{lname}"; - rr:termType rr:BlankNode ; - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-CSV/lives.csv"; - rml:referenceFormulation ql:CSV -]; - - rr:subjectMap [ - rr:template "{fname}{lname}"; - rr:termType rr:BlankNode; - ]; - - rr:predicateObjectMap - [ - rr:predicate ex:city ; - rr:objectMap [ - rml:reference "city"; - ] -]; -. diff --git a/src/test/resources/rml-testcases/RMLTC0012b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0012b-JSON/mapping.ttl index 5d92e047..74d9cd34 100644 --- a/src/test/resources/rml-testcases/RMLTC0012b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0012b-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-JSON/persons.json"; + rml:source "persons.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; @@ -34,7 +34,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-JSON/lives.json"; + rml:source "lives.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.lives[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0012b-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0012b-JSON/mapping.ttl.bak deleted file mode 100644 index 5d92e047..00000000 --- a/src/test/resources/rml-testcases/RMLTC0012b-JSON/mapping.ttl.bak +++ /dev/null @@ -1,54 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-JSON/persons.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.persons[*]" - ]; - - rr:subjectMap [ - rr:template "{fname}{lname}"; - rr:termType rr:BlankNode ; - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-JSON/lives.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.lives[*]" -]; - - rr:subjectMap [ - rr:template "{fname}{lname}"; - rr:termType rr:BlankNode; - ]; - - rr:predicateObjectMap - [ - rr:predicate ex:city ; - rr:objectMap [ - rml:reference "city"; - ] -]; -. diff --git a/src/test/resources/rml-testcases/RMLTC0012b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0012b-XML/mapping.ttl index 72f8880f..f1cd0916 100644 --- a/src/test/resources/rml-testcases/RMLTC0012b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0012b-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-XML/persons.xml"; + rml:source "persons.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/Persons/Person" ]; @@ -34,7 +34,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-XML/lives.xml"; + rml:source "lives.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/Lives/Live" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0012b-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0012b-XML/mapping.ttl.bak deleted file mode 100644 index 72f8880f..00000000 --- a/src/test/resources/rml-testcases/RMLTC0012b-XML/mapping.ttl.bak +++ /dev/null @@ -1,54 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-XML/persons.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/Persons/Person" - ]; - - rr:subjectMap [ - rr:template "{fname}{lname}"; - rr:termType rr:BlankNode ; - ]; - - rr:predicateObjectMap [ - rr:predicate foaf:name ; - rr:objectMap [ - rr:template "{fname} {lname}"; - rr:termType rr:Literal ; - ] - ]; - . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases//RMLTC0012b-XML/lives.xml"; - rml:referenceFormulation ql:XPath; - rml:iterator "/Lives/Live" - ]; - - rr:subjectMap [ - rr:template "{fname}{lname}"; - rr:termType rr:BlankNode; - ]; - - rr:predicateObjectMap - [ - rr:predicate ex:city ; - rr:objectMap [ - rml:reference "city"; - ] -]; -. diff --git a/src/test/resources/rml-testcases/RMLTC0013a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0013a-JSON/mapping.ttl index d5782623..9678f07c 100644 --- a/src/test/resources/rml-testcases/RMLTC0013a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0013a-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0013a-JSON/persons.json"; + rml:source "persons.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0015a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0015a-CSV/mapping.ttl index 763304b2..a89720fe 100644 --- a/src/test/resources/rml-testcases/RMLTC0015a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0015a-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0015a-CSV/country_en.csv"; + rml:source "country_en.csv"; rml:referenceFormulation ql:CSV ]; @@ -31,7 +31,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0015a-CSV/country_es.csv"; + rml:source "country_es.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0015a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0015a-JSON/mapping.ttl index 68039ccb..26ce6681 100644 --- a/src/test/resources/rml-testcases/RMLTC0015a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0015a-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0015a-JSON/country_en.json"; + rml:source "country_en.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" ]; @@ -32,7 +32,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0015a-JSON/country_es.json"; + rml:source "country_es.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0015a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0015a-XML/mapping.ttl index 49186d50..4abacbe7 100644 --- a/src/test/resources/rml-testcases/RMLTC0015a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0015a-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0015a-XML/country_en.xml"; + rml:source "country_en.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/countries/country" ]; @@ -32,7 +32,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0015a-XML/country_es.xml"; + rml:source "country_es.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/countries/country" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0019a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0019a-CSV/mapping.ttl index 47b3ed31..a5826211 100644 --- a/src/test/resources/rml-testcases/RMLTC0019a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0019a-CSV/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0019a-CSV/persons.csv"; + rml:source "persons.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0019a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0019a-JSON/mapping.ttl index d802b3c9..0958fc19 100644 --- a/src/test/resources/rml-testcases/RMLTC0019a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0019a-JSON/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0019a-JSON/persons.json"; + rml:source "persons.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0019a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0019a-XML/mapping.ttl index 15f8cf59..46eb3a27 100644 --- a/src/test/resources/rml-testcases/RMLTC0019a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0019a-XML/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0019a-XML/persons.xml"; + rml:source "persons.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/persons/person" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0019b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0019b-CSV/mapping.ttl index 4502b817..a5826211 100644 --- a/src/test/resources/rml-testcases/RMLTC0019b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0019b-CSV/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0019b-CSV/persons.csv"; + rml:source "persons.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0019b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0019b-JSON/mapping.ttl index 774d0c90..0958fc19 100644 --- a/src/test/resources/rml-testcases/RMLTC0019b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0019b-JSON/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0019b-JSON/persons.json"; + rml:source "persons.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0019b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0019b-XML/mapping.ttl index e5a0f963..46eb3a27 100644 --- a/src/test/resources/rml-testcases/RMLTC0019b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0019b-XML/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0019b-XML/persons.xml"; + rml:source "persons.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/persons/person" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0020a-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0020a-CSV/mapping.ttl index 24839804..8eb9f19a 100644 --- a/src/test/resources/rml-testcases/RMLTC0020a-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0020a-CSV/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0020a-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0020a-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0020a-JSON/mapping.ttl index 9749c9a5..c13bae39 100644 --- a/src/test/resources/rml-testcases/RMLTC0020a-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0020a-JSON/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0020a-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0020a-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0020a-XML/mapping.ttl index c6754e0c..0a89c9de 100644 --- a/src/test/resources/rml-testcases/RMLTC0020a-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0020a-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0020a-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0020b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0020b-CSV/mapping.ttl index c8fb5f79..5df5e835 100644 --- a/src/test/resources/rml-testcases/RMLTC0020b-CSV/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0020b-CSV/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0020b-CSV/student.csv"; + rml:source "student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/rml-testcases/RMLTC0020b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0020b-JSON/mapping.ttl index 4dc4750b..287cb790 100644 --- a/src/test/resources/rml-testcases/RMLTC0020b-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0020b-JSON/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0020b-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC0020b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0020b-XML/mapping.ttl index 3fc1d88e..95968f28 100644 --- a/src/test/resources/rml-testcases/RMLTC0020b-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC0020b-XML/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC0020b-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC1001-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC1001-JSON/mapping.ttl index 7e5bbf45..a0fa812e 100644 --- a/src/test/resources/rml-testcases/RMLTC1001-JSON/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC1001-JSON/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC1001-JSON/student.json"; + rml:source "student.json"; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/rml-testcases/RMLTC1001-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC1001-JSON/mapping.ttl.bak deleted file mode 100644 index b183abb4..00000000 --- a/src/test/resources/rml-testcases/RMLTC1001-JSON/mapping.ttl.bak +++ /dev/null @@ -1,27 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC1001-JSON/student.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.students[*]" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}"] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:Sport ; - rr:objectMap [ rml:reference "Sport" ] - ] . - - diff --git a/src/test/resources/rml-testcases/RMLTC1001-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC1001-XML/mapping.ttl index b34a4e8b..e921719d 100644 --- a/src/test/resources/rml-testcases/RMLTC1001-XML/mapping.ttl +++ b/src/test/resources/rml-testcases/RMLTC1001-XML/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "rml-testcases/RMLTC1001-XML/student.xml"; + rml:source "student.xml"; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/rml-testcases/RMLTC1001-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC1001-XML/mapping.ttl.bak deleted file mode 100644 index b6711b9d..00000000 --- a/src/test/resources/rml-testcases/RMLTC1001-XML/mapping.ttl.bak +++ /dev/null @@ -1,27 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "rml-testcases/RMLTC1001-XML/student.json"; - rml:referenceFormulation ql:XPath; - rml:iterator "/students/student" - ]; - - rr:subjectMap [ - rr:template "http://example.com/Student/{ID}"] - ]; - - rr:predicateObjectMap [ - rr:predicate ex:Sport ; - rr:objectMap [ rml:reference "Sport" ] - ] . - - diff --git a/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl index 382c995c..868ae982 100644 --- a/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl +++ b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.ttl @@ -25,7 +25,7 @@ :map_person_0 rml:logicalSource :source_0. :source_0 a rml:LogicalSource; - rml:source "sandbox/function_related/condition-function-on-po/data.json"; + rml:source "data.json"; rml:iterator "$.persons[*]"; rml:referenceFormulation ql:JSONPath. :map_person_0 a rr:TriplesMap; diff --git a/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.yarrrml b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.yarrrml index 4594ba8d..b859e3d1 100644 --- a/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.yarrrml +++ b/src/test/resources/sandbox/function_related/condition-function-on-po/mapping.yarrrml @@ -6,7 +6,7 @@ prefixes: mappings: person: sources: - - ['sandbox/function_related/condition-function-on-po/data.json~jsonpath', '$.persons[*]'] + - ['data.json~jsonpath', '$.persons[*]'] s: http://example.com/$(firstname) po: - [a, foaf:Person] diff --git a/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl index 97d49db0..65eb30fa 100644 --- a/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl +++ b/src/test/resources/sandbox/function_related/condition-on-mapping-subject-function/mapping.ttl @@ -13,7 +13,7 @@ :map_person_0 rml:logicalSource :source_0. :source_0 a rml:LogicalSource; - rml:source "sandbox/function_related/condition-on-mapping-subject-function/input.csv"; + rml:source "input.csv"; rml:referenceFormulation ql:CSV. :map_person_0 a rr:TriplesMap; rdfs:label "person". diff --git a/src/test/resources/sandbox/function_related/condition-on-po/mapping.rml.ttl b/src/test/resources/sandbox/function_related/condition-on-po/mapping.rml.ttl index 4689487b..85b9834c 100644 --- a/src/test/resources/sandbox/function_related/condition-on-po/mapping.rml.ttl +++ b/src/test/resources/sandbox/function_related/condition-on-po/mapping.rml.ttl @@ -11,7 +11,7 @@ :map_person_0 rml:logicalSource :source_0. :source_0 a rml:LogicalSource; - rml:source "sandbox/function_related/condition-on-po/test.csv"; + rml:source "test.csv"; rml:referenceFormulation ql:CSV. :map_person_0 a rr:TriplesMap; rdfs:label "person". diff --git a/src/test/resources/sandbox/function_related/contains/mapping.ttl b/src/test/resources/sandbox/function_related/contains/mapping.ttl index b216cd68..c2943914 100644 --- a/src/test/resources/sandbox/function_related/contains/mapping.ttl +++ b/src/test/resources/sandbox/function_related/contains/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/student.csv"; + rml:source "../../../fno-testcases/student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/function_related/controls_if_contains/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_contains/mapping.ttl index 58007c7b..6f2eff30 100644 --- a/src/test/resources/sandbox/function_related/controls_if_contains/mapping.ttl +++ b/src/test/resources/sandbox/function_related/controls_if_contains/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "sandbox/function_related/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl index f406fa85..78ad86ce 100644 --- a/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl +++ b/src/test/resources/sandbox/function_related/controls_if_contains_true_execute_triplesmap/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "sandbox/function_related/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl index 6f5d517f..f9cc6ed2 100644 --- a/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl +++ b/src/test/resources/sandbox/function_related/controls_if_false/mapping.ttl @@ -15,7 +15,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "sandbox/function_related/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl b/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl index 4639c64e..823ae039 100644 --- a/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl +++ b/src/test/resources/sandbox/function_related/controls_if_true/mapping.ttl @@ -15,7 +15,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "sandbox/function_related/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/function_related/equal/mapping.ttl b/src/test/resources/sandbox/function_related/equal/mapping.ttl index da3a3e3b..34d20ca8 100644 --- a/src/test/resources/sandbox/function_related/equal/mapping.ttl +++ b/src/test/resources/sandbox/function_related/equal/mapping.ttl @@ -15,7 +15,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "sandbox/function_related/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/function_related/notEqual/mapping.ttl b/src/test/resources/sandbox/function_related/notEqual/mapping.ttl index 9dc4ac7f..5f66daab 100644 --- a/src/test/resources/sandbox/function_related/notEqual/mapping.ttl +++ b/src/test/resources/sandbox/function_related/notEqual/mapping.ttl @@ -15,7 +15,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "sandbox/function_related/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl b/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl index 1878791c..07a6bf70 100644 --- a/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl +++ b/src/test/resources/sandbox/function_related/using_trueCondition_and_contains/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "sandbox/function_related/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/mapping.ttl b/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/mapping.ttl index 1ca5a8ba..afaf3df2 100644 --- a/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/mapping.ttl +++ b/src/test/resources/sandbox/function_related/using_trueCondition_and_equal/mapping.ttl @@ -17,7 +17,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "sandbox/function_related/student.csv"; + rml:source "../student.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index 017c8110..1a97f717 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -47,7 +47,8 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour with // This is useful, for example, if you only want to check the tests that should pass. val failing : Array[String] = Array( - "negative_test_cases" + "rml-testcases-invalid-mapping-file" + //"rml-testcases-negative" ) val passing : Array[Tuple2[String,String]] =Array( ("bugs","noopt"), diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 1207039a..1628b94a 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -61,7 +61,7 @@ class SandboxTests extends FunSuite with Matchers with FunctionMappingTest { val (expectedOutput, expectedOutputFormat) = TestUtil.getExpectedOutputs(testDir) - val testOutcome = TestUtil.compareResults(s"StatementEngineTest: ${testDir}", result, expectedOutput, postProcessor.outputFormat, expectedOutputFormat) + val testOutcome = TestUtil.compareResults(s"SandboxTests: ${testDir}", result, expectedOutput, postProcessor.outputFormat, expectedOutputFormat) testOutcome match { case Left(e) => { diff --git a/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala b/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala index 75033fa4..97ae304b 100644 --- a/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala +++ b/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala @@ -24,8 +24,9 @@ **/ package io.rml.framework.util.fileprocessing -import io.rml.framework.core.extractors.{MappingReader, TriplesMapsCache} -import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping} +import io.rml.framework.core.extractors.TriplesMapsCache +import io.rml.framework.core.model.FormattedRMLMapping +import io.rml.framework.core.util.Util import java.io.File @@ -38,8 +39,9 @@ object MappingTestUtil extends FileProcessingUtil[FormattedRMLMapping] { override def processFile(file: File): FormattedRMLMapping = { TriplesMapsCache.clear(); - val mapping = MappingReader().read(file) - FormattedRMLMapping.fromRMLMapping(mapping.asInstanceOf[RMLMapping]) + Util.readMappingFile(file.getCanonicalPath) + //val mapping = MappingReader().read(file) + //FormattedRMLMapping.fromRMLMapping(mapping.asInstanceOf[RMLMapping]) } override def candidateFiles: List[String] = List("mapping.ttl", "mapping.rml.ttl", "example.rml.ttl") diff --git a/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala b/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala index 1dd6b993..49265772 100644 --- a/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala +++ b/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala @@ -25,9 +25,8 @@ package io.rml.framework.util.fileprocessing import io.rml.framework.Main -import io.rml.framework.core.extractors.{MappingReader, TriplesMapsCache} -import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping} -import io.rml.framework.core.util.{Format, NQuads} +import io.rml.framework.core.extractors.TriplesMapsCache +import io.rml.framework.core.util.{Format, NQuads, Util} import io.rml.framework.engine.{NopPostProcessor, PostProcessor} import io.rml.framework.util.logging.Logger import org.apache.flink.api.scala.ExecutionEnvironment @@ -67,9 +66,8 @@ object TripleGeneratorTestUtil extends TestFilesUtil[(List[String], Format)] { def processFile(file: File): (List[String], Format) = { try { TriplesMapsCache.clear(); - val mapping = MappingReader().read(file) - val formattedMapping = FormattedRMLMapping.fromRMLMapping(mapping.asInstanceOf[RMLMapping]) + val formattedMapping = Util.readMappingFile(file.getCanonicalPath) val dataSet = Main.createDataSetFromFormattedMapping(formattedMapping).collect // we assume quads, since we don't use a post processor From f9927082b88a0e0c308bfe476a63bf17c787179e Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 25 Feb 2021 13:59:18 +0100 Subject: [PATCH 144/169] Fixed test code. Closes #95 . Also fixes relative paths used in rml:source *in* the mapping file. --- .../rml/framework/OutputGenerationTest.scala | 75 +++++++++++++------ .../util/fileprocessing/TestFilesUtil.scala | 9 +-- 2 files changed, 57 insertions(+), 27 deletions(-) diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index 1a97f717..292bc2ee 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -25,7 +25,7 @@ package io.rml.framework import io.rml.framework.api.RMLEnvironment -import io.rml.framework.engine.PostProcessor +import io.rml.framework.engine.{NopPostProcessor, PostProcessor} import io.rml.framework.util.TestUtil import io.rml.framework.util.fileprocessing.{ExpectedOutputTestUtil, TripleGeneratorTestUtil} import io.rml.framework.util.logging.Logger @@ -46,43 +46,58 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour with // without causing compilation failures. // This is useful, for example, if you only want to check the tests that should pass. - val failing : Array[String] = Array( + val invalidMappingFile : Array[String] = Array( "rml-testcases-invalid-mapping-file" - //"rml-testcases-negative" ) val passing : Array[Tuple2[String,String]] =Array( ("bugs","noopt"), ("rml-testcases","noopt"), ("fno-testcases", "noopt") ) + + val negative : Array[String] = Array( + "rml-testcases-negative" + ) + val temp : Array[Tuple2[String,String]] = Array( ("rml-testcases/temp","noopt") ) + /////////////////////// + // passing test cases + /////////////////////// - - "Valid mapping file" should behave like validMappingFile("rml-testcases") + passing.foreach { test => + test._1 should behave like validMappingFile(test._1) + } "Valid mapping output generation" should "match the output from output.ttl" in { - - - - passing.foreach(test => { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.com/base/")) - implicit val postProcessor: PostProcessor= TestUtil.pickPostProcessor(test._2) - ExpectedOutputTestUtil.test(test._1, checkGeneratedOutput) + ExpectedOutputTestUtil.test(test._1, true, checkGeneratedOutput) }) - //checkGeneratedOutput(OutputTestHelper.getFile("example2-object").toString) } - failing foreach { - el => + //////////////////////////////////////////// + // test cases where mapping file is invalid + //////////////////////////////////////////// + invalidMappingFile foreach { + el => s"Reading invalid mapping files in $el" should behave like invalidMappingFile(el) } + //////////////////////////////////////////////////////////////////// + // negative test cases: valid mapping but something else goes wrong + //////////////////////////////////////////////////////////////////// + + negative.foreach { test => + test should behave like validMappingFile(test) + RMLEnvironment.setGeneratorBaseIRI(Some("http://example.com/base/")) + implicit val postProcessor: PostProcessor= new NopPostProcessor + ExpectedOutputTestUtil.test(test, false, checkGeneratedOutput) + } /** * Check for thrown TermTypeException when reading invalid term typed subjects. @@ -113,18 +128,34 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour with * * @param testFolderPath */ - def checkGeneratedOutput(testFolderPath: String)(implicit postProcessor: PostProcessor): Unit = { + def checkGeneratedOutput(testFolderPath: String, shouldPass: Boolean)(implicit postProcessor: PostProcessor): Unit = { Logger.logInfo("checkGeneratedOutput(%s)".format(testFolderPath)) val (expectedOutput, expectedOutputFormat) = ExpectedOutputTestUtil.processFilesInTestFolder(testFolderPath).head val tester = TripleGeneratorTestUtil(postProcessor) - var (generatedOutput, generatedOutputFormat) = tester.processFilesInTestFolder(testFolderPath).head - val outcome = TestUtil.compareResults(testFolderPath, generatedOutput, expectedOutput, generatedOutputFormat, expectedOutputFormat) - outcome match { - case Left(e) => { - fail(e) - System.exit(1) + try { + var (generatedOutput, generatedOutputFormat) = tester.processFilesInTestFolder(testFolderPath).head + val outcome = TestUtil.compareResults(testFolderPath, generatedOutput, expectedOutput, generatedOutputFormat, expectedOutputFormat) + outcome match { + case Left(e) => { + if (shouldPass) { + fail(e) + System.exit(1) + } + } + case Right(e) => { + if (!shouldPass) { + fail(e) + System.exit(1) + } + } + } + } catch { + case e => { + if (shouldPass) { + fail(e); + System.exit(1) + } } - case Right(e) => // just go on :) } } diff --git a/src/test/scala/io/rml/framework/util/fileprocessing/TestFilesUtil.scala b/src/test/scala/io/rml/framework/util/fileprocessing/TestFilesUtil.scala index 1ff59c40..12224f70 100644 --- a/src/test/scala/io/rml/framework/util/fileprocessing/TestFilesUtil.scala +++ b/src/test/scala/io/rml/framework/util/fileprocessing/TestFilesUtil.scala @@ -24,12 +24,11 @@ **/ package io.rml.framework.util.fileprocessing -import java.io.File -import java.nio.file.Path - import io.rml.framework.core.util.Util import io.rml.framework.util.logging.Logger +import java.io.File +import java.nio.file.Path import scala.util.Sorting /** @@ -72,11 +71,11 @@ trait TestFilesUtil[R] { * @param rootDir * @param checkFunc */ - def test(rootDir: String, checkFunc: String => Unit): Unit = { + def test(rootDir: String, shouldPass: Boolean, checkFunc: (String, Boolean) => Unit): Unit = { var checkedTestCases = Array("") for (pathString <- getTestCaseFolders(rootDir).map(_.toString).sorted) { - checkFunc(pathString) + checkFunc(pathString, shouldPass) val testCase = new File(pathString).getName Logger.logSuccess("Passed processing: " + testCase) Logger.lineBreak() From 2513552b486e9bb7c72009ee7429b068a4187fb4 Mon Sep 17 00:00:00 2001 From: Michiel Derveeuw Date: Mon, 1 Mar 2021 15:42:44 +0100 Subject: [PATCH 145/169] Use streaming file sink instead of deprecated writeAsText --- src/main/scala/io/rml/framework/Main.scala | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index 8562dbf7..ba375676 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -39,11 +39,15 @@ import io.rml.framework.flink.item.{Item, JoinedItem} import io.rml.framework.flink.source.{EmptyItem, FileDataSet, Source} import io.rml.framework.flink.util.ParameterUtil import io.rml.framework.flink.util.ParameterUtil.{OutputSinkOption, PostProcessorOption} -import org.apache.flink.api.common.serialization.SimpleStringSchema +import org.apache.flink.api.common.serialization.{SimpleStringEncoder, SimpleStringSchema} import org.apache.flink.api.scala._ import org.apache.flink.core.fs.FileSystem.WriteMode +import org.apache.flink.core.fs.Path import org.apache.flink.streaming.api.CheckpointingMode import org.apache.flink.streaming.api.functions.ProcessFunction +import org.apache.flink.streaming.api.functions.sink.filesystem.{OutputFileConfig, StreamingFileSink} +import org.apache.flink.streaming.api.functions.sink.filesystem.bucketassigners.BasePathBucketAssigner +import org.apache.flink.streaming.api.functions.sink.filesystem.rollingpolicies.{OnCheckpointRollingPolicy} import org.apache.flink.streaming.api.scala.{DataStream, OutputTag, StreamExecutionEnvironment} import org.apache.flink.util.Collector @@ -150,7 +154,16 @@ object Main extends Logging { } // write to a file if the parameter is given else if (config.outputSink.equals(OutputSinkOption.File)) { - stream.writeAsText(config.outputPath.get, WriteMode.OVERWRITE) + val sink: StreamingFileSink[String] = StreamingFileSink + .forRowFormat(new Path(config.outputPath.get), new SimpleStringEncoder[String]("UTF-8")) + .withBucketAssigner(new BasePathBucketAssigner[String]) + .withRollingPolicy(OnCheckpointRollingPolicy.build()) + .withOutputFileConfig(OutputFileConfig + .builder() + .withPartSuffix(if (config.postProcessor == PostProcessorOption.JsonLD) ".json" else ".nq") + .build()) + .build() + stream.addSink(sink).name("Streaming file sink") } // discard output if the parameter is given else if (config.outputSink.equals(OutputSinkOption.None)) { From fa4f0841ac4c963e696925ca1c9fe176316ca47b Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Tue, 2 Mar 2021 10:14:03 +0100 Subject: [PATCH 146/169] The graphmap was forgotten in StreamTriplesMap... --- CHANGELOG.md | 4 +++- .../scala/io/rml/framework/core/model/StreamTriplesMap.scala | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d1acd20..400680c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -* Function mapping. * Joins of data streams ## [2.0.1] - +### Added +* Support for functions using the [Function Ontology](https://fno.io/) + ### Changed * Updated Flink from version 1.10.0 to 1.11.3 * Updated Kafka version from version 2.2.2 to 2.4.1 (more versions supported using the universal connector) diff --git a/src/main/scala/io/rml/framework/core/model/StreamTriplesMap.scala b/src/main/scala/io/rml/framework/core/model/StreamTriplesMap.scala index 735db51e..accd081e 100644 --- a/src/main/scala/io/rml/framework/core/model/StreamTriplesMap.scala +++ b/src/main/scala/io/rml/framework/core/model/StreamTriplesMap.scala @@ -61,7 +61,7 @@ abstract class StreamTriplesMap(triplesMap: TriplesMap) extends TriplesMap { * * @return */ - override def graphMap = ??? + override def graphMap = triplesMap.graphMap } From 4d139d058c04b69527e71746a0fa9632a044dd6f Mon Sep 17 00:00:00 2001 From: Michiel Derveeuw Date: Wed, 3 Mar 2021 11:03:27 +0100 Subject: [PATCH 147/169] Enable checkpointing by default if not enabled by the option --- src/main/scala/io/rml/framework/Main.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index ba375676..45956137 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -106,6 +106,10 @@ object Main extends Logging { if (config.checkpointInterval.isDefined) { senv.enableCheckpointing(config.checkpointInterval.get, CheckpointingMode.AT_LEAST_ONCE); // This is what Kafka supports ATM, see https://ci.apache.org/projects/flink/flink-docs-release-1.8/dev/connectors/guarantees.html + + // in order for the StreamingFileSink to work correctly, checkpointing needs to be enabled + } else if (config.outputSink.equals(OutputSinkOption.File) && formattedMapping.containsStreamTriplesMaps()) { + senv.enableCheckpointing(30000, CheckpointingMode.AT_LEAST_ONCE); } if (formattedMapping.containsDatasetTriplesMaps() && !formattedMapping.containsStreamTriplesMaps()) { @@ -160,7 +164,7 @@ object Main extends Logging { .withRollingPolicy(OnCheckpointRollingPolicy.build()) .withOutputFileConfig(OutputFileConfig .builder() - .withPartSuffix(if (config.postProcessor == PostProcessorOption.JsonLD) ".json" else ".nq") + .withPartSuffix(if (config.postProcessor.equals(PostProcessorOption.JsonLD)) ".json" else ".nq") .build()) .build() stream.addSink(sink).name("Streaming file sink") From 8e3d139134b7c86ca47ea4c65fec378b91ead545 Mon Sep 17 00:00:00 2001 From: Michiel Derveeuw Date: Wed, 3 Mar 2021 14:15:42 +0100 Subject: [PATCH 148/169] Parse filename to get correct path and suffix for StreamingFileSink --- src/main/scala/io/rml/framework/Main.scala | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index 45956137..8bd32e7e 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -158,13 +158,21 @@ object Main extends Logging { } // write to a file if the parameter is given else if (config.outputSink.equals(OutputSinkOption.File)) { + val parts = config.outputPath.get.split('.') + val path = parts(0) + val suffix = + if (parts.length > 1) { + "." ++ parts(parts.length - 1) + } else { + if (config.postProcessor.equals(PostProcessorOption.JsonLD)) ".json" else ".huh" + } val sink: StreamingFileSink[String] = StreamingFileSink - .forRowFormat(new Path(config.outputPath.get), new SimpleStringEncoder[String]("UTF-8")) + .forRowFormat(new Path(path), new SimpleStringEncoder[String]("UTF-8")) .withBucketAssigner(new BasePathBucketAssigner[String]) .withRollingPolicy(OnCheckpointRollingPolicy.build()) .withOutputFileConfig(OutputFileConfig .builder() - .withPartSuffix(if (config.postProcessor.equals(PostProcessorOption.JsonLD)) ".json" else ".nq") + .withPartSuffix(suffix) .build()) .build() stream.addSink(sink).name("Streaming file sink") From 95d3db6ed33d570459eb40657bf4ba630076a00a Mon Sep 17 00:00:00 2001 From: Michiel Derveeuw Date: Wed, 3 Mar 2021 15:20:39 +0100 Subject: [PATCH 149/169] Change default extension --- src/main/scala/io/rml/framework/Main.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index 8bd32e7e..54ec008c 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -164,7 +164,7 @@ object Main extends Logging { if (parts.length > 1) { "." ++ parts(parts.length - 1) } else { - if (config.postProcessor.equals(PostProcessorOption.JsonLD)) ".json" else ".huh" + if (config.postProcessor.equals(PostProcessorOption.JsonLD)) ".json" else ".nq" } val sink: StreamingFileSink[String] = StreamingFileSink .forRowFormat(new Path(path), new SimpleStringEncoder[String]("UTF-8")) From 22187abe6654416510419b1bd8b86443516a3596 Mon Sep 17 00:00:00 2001 From: Michiel Derveeuw Date: Wed, 3 Mar 2021 15:41:21 +0100 Subject: [PATCH 150/169] Use entire extension for suffix --- src/main/scala/io/rml/framework/Main.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index 54ec008c..600c9435 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -162,7 +162,7 @@ object Main extends Logging { val path = parts(0) val suffix = if (parts.length > 1) { - "." ++ parts(parts.length - 1) + "." ++ parts.slice(1, parts.length).mkString(".") } else { if (config.postProcessor.equals(PostProcessorOption.JsonLD)) ".json" else ".nq" } From 7ac66ead56e35ce99578cfc6b014d546999539c0 Mon Sep 17 00:00:00 2001 From: Michiel Derveeuw Date: Wed, 3 Mar 2021 16:32:38 +0100 Subject: [PATCH 151/169] Update documentation for StreamingFileSink --- README.md | 6 +++--- .../io/rml/framework/flink/util/ParameterUtil.scala | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5efdd362..70e6033b 100644 --- a/README.md +++ b/README.md @@ -91,9 +91,9 @@ Usage: RMLStreamer [toFile|toKafka|toTCPSocket] [options] --checkpoint-interval - - - - - - - - - - - - - - - - - - - - - - com.ximpleware vtd-xml From 83b2b84d62fdafb5d45f571d77bffcb25c31a9ea Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 18 Mar 2021 12:46:52 +0100 Subject: [PATCH 168/169] Clean up TCP push code and modify tests --- README.md | 49 +------------------ documentation/README_DEVELOPMENT.md | 2 +- documentation/README_Netty_Snapshot.md | 1 + pom.xml | 23 --------- .../resources/json_stream_data_mapping.ttl | 1 - .../std/StdDataSourceExtractor.scala | 5 +- .../core/model/TCPSocketStream.scala | 13 ++--- .../framework/core/vocabulary/RMLVoc.scala | 1 - .../framework/flink/source/StreamUtil.scala | 15 +----- .../RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl | 2 +- .../tcp/RMLTC0012a-CSV-STREAM/mapping.ttl | 2 +- .../RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl | 2 +- .../tcp/RMLTC0012a-JSON-STREAM/mapping.ttl | 2 +- .../RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl | 2 +- .../tcp/RMLTC0012a-XML-STREAM/mapping.ttl | 2 +- .../tcp/RMLFNOTC0001-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTC0002-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTC0003-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTC0004-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTC0005-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTC0006-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTC0007-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTC0008-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTC0013-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTC0018-CSV/mapping.ttl | 3 +- .../tcp/RMLFNOTCA004/mapping.ttl | 3 +- .../tcp/RMLFNOTCA004b/mapping.ttl | 3 +- .../tcp/RMLTC0000-CSV-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0000-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0000-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0001a-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0001a-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0001a-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0001b-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0001b-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0001b-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0002a-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0002a-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0002a-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0002b-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0002b-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0002b-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0002c-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0002c-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0002c-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0003c-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0003c-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0003c-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0006a-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0006a-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0006a-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007a-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0007a-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007a-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007b-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0007b-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007b-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007c-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0007c-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007c-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007d-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0007d-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007d-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007e-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0007e-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007e-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007f-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0007f-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007f-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007g-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0007g-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0007g-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0008a-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0008a-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0008a-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0008c-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0008c-JSON-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0008c-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC0010a-CSV-STREAM-TCP/mapping.ttl | 2 +- .../RMLTC0010a-JSON-STREAM-TCP/mapping.ttl | 2 +- .../mapping.ttl | 2 +- .../tcp/RMLTC0010b-CSV-STREAM-TCP/mapping.ttl | 2 +- .../mapping.ttl | 3 +- .../RMLTC0010b-JSON-STREAM-TCP/mapping.ttl | 3 +- .../mapping.ttl | 3 +- .../tcp/RMLTC0010b-XML-STREAM-TCP/mapping.ttl | 3 +- .../mapping.ttl | 2 +- .../tcp/RMLTC0012a-CSV-STREAM-TCP/mapping.ttl | 2 +- .../mapping.ttl | 2 +- .../RMLTC0012a-JSON-STREAM-TCP/mapping.ttl | 2 +- .../mapping.ttl | 2 +- .../tcp/RMLTC0012a-XML-STREAM-TCP/mapping.ttl | 2 +- .../tcp/RMLTC1001-JSON-STREAM-TCP/mapping.ttl | 3 +- .../tcp/RMLTC1001-XML-STREAM-TCP/mapping.ttl | 3 +- 94 files changed, 94 insertions(+), 204 deletions(-) diff --git a/README.md b/README.md index 898a5a1a..2f7cde90 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Please note that this version works with Flink 1.11.3 with Scala 2.11 support, w ### Building RMLStreamer In order to build a jar file that can be deployed on a Flink cluster, you need: -- a Java JDK >= 11 and <= 13 +- a Java JDK >= 11 and <= 13 (We develop and test on JDK 11) - Apache Maven 3 or higher Clone or download and then build the code in this repository: @@ -46,7 +46,7 @@ The resulting `RMLStreamer-.jar`, found in the `target` folder, can be ### Executing RML Mappings Here we give examples for running RMLStreamer from the command line. We use `FLINK_BIN` to denote the Flink CLI tool, -usually found in the `bin` directory of the Flink installation. E.g. `/home/myuser/flink-1.11.2/bin/flink`. +usually found in the `bin` directory of the Flink installation. E.g. `/home/myuser/flink-1.11.3/bin/flink`. For Windows a `flink.bat` script is provided. The general usage is: @@ -121,7 +121,6 @@ An example of how to define the generation of an RDF stream from a stream in an rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost"; - rmls:type "PULL" ; rmls:port "5005" ]; rml:referenceFormulation ql:JSONPath; @@ -193,38 +192,6 @@ See also https://stackoverflow.com/questions/38639019/flink-kafka-consumer-group The only option for spreading load is to use multiple topics, and assign one RMLStreamer job to one topic. -##### Generating a stream from a file (to be implemented) -``` -<#TripleMap> - - a rr:TriplesMap; - rml:logicalSource [ - rml:source [ - rdf:type rmls:FileStream; - rmls:path "/home/wmaroy/github/rml-framework/akka-pipeline/src/main/resources/io/rml/framework/data/books.json" - ]; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.store.books[*]" - ]; - - rr:subjectMap [ - rr:template "{$.id}" ; - rr:termType rr:IRI; - rr:class skos:Concept - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]. -``` - ##### Generating a stream from a dataset ``` @@ -272,17 +239,6 @@ The following are the classes/terms currently used: * **rmls:port** specifies a port number for the stream mapper to connect to. - - -* **rmls:type** specifies how a streamer will act: - * **"PULL"**: - The stream mapper will act as a client. - It will create a socket and connect to the specified port at the given host name. - **rmls:port** and **rmls:hostName** needs to be specified. - * **"PUSH"**: - The stream mapper will act as a server and will start listening at the given port. - If the given port is taken, the mapper will keep opening subsequent ports until a free port is found. - Only **rmls:port** needs to be specified here. Example of a valid json logical source map using all possible terms: @@ -292,7 +248,6 @@ rml:logicalSource [ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost"; - rmls:type "PULL" ; rmls:port "5005" ]; rml:referenceFormulation ql:JSONPath; diff --git a/documentation/README_DEVELOPMENT.md b/documentation/README_DEVELOPMENT.md index c4a27cc8..75b5069e 100644 --- a/documentation/README_DEVELOPMENT.md +++ b/documentation/README_DEVELOPMENT.md @@ -2,7 +2,7 @@ ## Prerequisites * Git -* Java JDK >= 11 +* Java JDK 11 * Maven 3 * IntelliJ (Eclipse should work too, but consult Flink documentation for set-up) diff --git a/documentation/README_Netty_Snapshot.md b/documentation/README_Netty_Snapshot.md index db9fbb97..ac371745 100644 --- a/documentation/README_Netty_Snapshot.md +++ b/documentation/README_Netty_Snapshot.md @@ -1,4 +1,5 @@ # README: Using JitPack +(kept for reference only, not applicable anymore for RMLStreamer) ### Using JitPack to get unpublished Maven Dependencies from a GitHub/GitLab repository diff --git a/pom.xml b/pom.xml index 958c2dbc..f224437e 100644 --- a/pom.xml +++ b/pom.xml @@ -52,29 +52,6 @@ SOFTWARE. mit - diff --git a/src/main/resources/json_stream_data_mapping.ttl b/src/main/resources/json_stream_data_mapping.ttl index 8a0d4739..91fd48bb 100644 --- a/src/main/resources/json_stream_data_mapping.ttl +++ b/src/main/resources/json_stream_data_mapping.ttl @@ -23,7 +23,6 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost"; - rmls:type "PULL"; rmls:port "5005" ]; rml:referenceFormulation ql:JSONPath; diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdDataSourceExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdDataSourceExtractor.scala index 0e635bd7..f7665b5f 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdDataSourceExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdDataSourceExtractor.scala @@ -107,8 +107,6 @@ class StdDataSourceExtractor extends DataSourceExtractor { require(hostNameProperties.length == 1, resource.uri.toString + ": exactly 1 hostname needed.") val portProperties = resource.listProperties(RMLVoc.Property.PORT) require(portProperties.length == 1, resource.uri.toString + ": exactly 1 port needed.") - val typeProperties = resource.listProperties(RMLVoc.Property.TYPE) - require(typeProperties.length == 1, resource.uri.toString + ": needs type.") val hostName = hostNameProperties.head match { case resource: RDFResource => throw new RMLException(resource.uri + ": hostname must be a literal.") @@ -119,7 +117,6 @@ class StdDataSourceExtractor extends DataSourceExtractor { case literal: Literal => literal.value } - val _type = ExtractorUtil.matchLiteral(typeProperties.head) - TCPSocketStream(hostName, port.toInt, _type.value) + TCPSocketStream(hostName, port.toInt) } } diff --git a/src/main/scala/io/rml/framework/core/model/TCPSocketStream.scala b/src/main/scala/io/rml/framework/core/model/TCPSocketStream.scala index eb22bba6..dced720f 100644 --- a/src/main/scala/io/rml/framework/core/model/TCPSocketStream.scala +++ b/src/main/scala/io/rml/framework/core/model/TCPSocketStream.scala @@ -26,19 +26,12 @@ package io.rml.framework.core.model import java.util.Objects -case class TCPSocketStream(hostName: String, port: Int, _type: String) extends StreamDataSource { +case class TCPSocketStream(hostName: String, port: Int) extends StreamDataSource { override def uri: ExplicitNode = { - val hashValue = Objects.hash(hostName, Integer.valueOf(port), _type) + val hashValue = Objects.hash(hostName, Integer.valueOf(port)) Uri(hashValue.toHexString) } } -object TCPSocketStream { - - object TYPE { - val PUSH = "PUSH" - val PULL = "PULL" - } - -} +//object TCPSocketStream diff --git a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala index 7aba736c..0008f65f 100644 --- a/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala +++ b/src/main/scala/io/rml/framework/core/vocabulary/RMLVoc.scala @@ -89,7 +89,6 @@ object RMLVoc { val HOSTNAME = Namespaces("rmls", "hostName") val PORT = Namespaces("rmls", "port") val PATH = Namespaces("rmls", "path") - val TYPE = Namespaces("rmls", "type") /////////////////////////////////////////////////////////////////////////// // RMLS: Kafka Source diff --git a/src/main/scala/io/rml/framework/flink/source/StreamUtil.scala b/src/main/scala/io/rml/framework/flink/source/StreamUtil.scala index 990945ed..844c8c14 100644 --- a/src/main/scala/io/rml/framework/flink/source/StreamUtil.scala +++ b/src/main/scala/io/rml/framework/flink/source/StreamUtil.scala @@ -29,24 +29,11 @@ import io.rml.framework.core.model.TCPSocketStream import io.rml.framework.core.util.StreamerConfig import org.apache.flink.api.scala._ import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment} -//import org.apache.flink.streaming.connectors.netty.example.TcpReceiverSource object StreamUtil { def createTcpSocketSource(tCPSocketStream: TCPSocketStream, delimiter:String="\n")(implicit env: StreamExecutionEnvironment): DataStream[String] = { - - tCPSocketStream._type match { - //TODO Update flink to 1.3.3 to use latest methods in scala without java -> scala conversion. - - /** - * Flink 1.3.2's scala socketTextStream can't use custom multi-char/String delimiter (there is delimiter param but it's not being used) - * - */ - - - case TCPSocketStream.TYPE.PULL => new DataStream[String](env.getJavaEnv.socketTextStream(tCPSocketStream.hostName, tCPSocketStream.port, delimiter)) - //case TCPSocketStream.TYPE.PUSH => env.addSource(new TcpReceiverSource(tCPSocketStream.port)).setParallelism(1) // to avoid library to setup multiple instances - } + new DataStream[String](env.getJavaEnv.socketTextStream(tCPSocketStream.hostName, tCPSocketStream.port, delimiter)) } /** diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl index 2bd488ab..1abe59ff 100644 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl +++ b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM-SPLIT/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM/mapping.ttl b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM/mapping.ttl index 2bd488ab..1abe59ff 100644 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM/mapping.ttl +++ b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-CSV-STREAM/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl index 369d197e..6e8207b0 100644 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl +++ b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM-SPLIT/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; ]; rml:referenceFormulation ql:JSONPath; ]; diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM/mapping.ttl b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM/mapping.ttl index 9c6ad611..93745d16 100644 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM/mapping.ttl +++ b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-JSON-STREAM/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl index c927b794..9c04365c 100644 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl +++ b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM-SPLIT/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; ]; rml:referenceFormulation ql:XPath; ]; diff --git a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM/mapping.ttl b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM/mapping.ttl index 226e82c3..b7c83e3e 100644 --- a/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM/mapping.ttl +++ b/src/test/resources/json-ld/stream/tcp/RMLTC0012a-XML-STREAM/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; ]; rml:referenceFormulation ql:XPath; rml:iterator "/Persons/Person" ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/mapping.ttl index 694e17e4..fc1ec139 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0001-CSV/mapping.ttl @@ -23,8 +23,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/mapping.ttl index 6b6aa1f2..e96ae332 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0002-CSV/mapping.ttl @@ -22,8 +22,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/mapping.ttl index 5e3289ed..3dca3dec 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0003-CSV/mapping.ttl @@ -22,8 +22,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/mapping.ttl index 0ac32471..65f87b91 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0004-CSV/mapping.ttl @@ -22,8 +22,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/mapping.ttl index 54a8a36c..1bf55b63 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0005-CSV/mapping.ttl @@ -22,8 +22,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/mapping.ttl index 735a42f0..ba9b4510 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0006-CSV/mapping.ttl @@ -22,8 +22,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/mapping.ttl index 3c123e13..1a53c5ea 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0007-CSV/mapping.ttl @@ -22,8 +22,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/mapping.ttl index a948b384..3933a577 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0008-CSV/mapping.ttl @@ -22,8 +22,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/mapping.ttl index 5ab8b98f..97c3d837 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0013-CSV/mapping.ttl @@ -22,8 +22,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/mapping.ttl index 067af2ce..2e2c7c07 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTC0018-CSV/mapping.ttl @@ -22,8 +22,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/mapping.ttl index c7223981..3b95aa81 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004/mapping.ttl @@ -23,8 +23,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/mapping.ttl b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/mapping.ttl index ebf90bf2..8fa21bce 100644 --- a/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/mapping.ttl +++ b/src/test/resources/stream/fno-testcases/tcp/RMLFNOTCA004b/mapping.ttl @@ -23,8 +23,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0000-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0000-CSV-STREAM-TCP/mapping.ttl index 6c105c11..2900a29c 100644 --- a/src/test/resources/stream/tcp/RMLTC0000-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0000-CSV-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ] ; diff --git a/src/test/resources/stream/tcp/RMLTC0000-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0000-JSON-STREAM-TCP/mapping.ttl index aae32754..6ed17bdf 100644 --- a/src/test/resources/stream/tcp/RMLTC0000-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0000-JSON-STREAM-TCP/mapping.ttl @@ -14,7 +14,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ] ; diff --git a/src/test/resources/stream/tcp/RMLTC0000-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0000-XML-STREAM-TCP/mapping.ttl index 44db5aa9..988e75a9 100644 --- a/src/test/resources/stream/tcp/RMLTC0000-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0000-XML-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ] ; diff --git a/src/test/resources/stream/tcp/RMLTC0001a-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0001a-CSV-STREAM-TCP/mapping.ttl index 9b07bf3a..ecb0eec9 100644 --- a/src/test/resources/stream/tcp/RMLTC0001a-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0001a-CSV-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0001a-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0001a-JSON-STREAM-TCP/mapping.ttl index 1547ae72..982fbe7a 100644 --- a/src/test/resources/stream/tcp/RMLTC0001a-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0001a-JSON-STREAM-TCP/mapping.ttl @@ -14,7 +14,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0001a-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0001a-XML-STREAM-TCP/mapping.ttl index 8b685a6e..57e12a60 100644 --- a/src/test/resources/stream/tcp/RMLTC0001a-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0001a-XML-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0001b-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0001b-CSV-STREAM-TCP/mapping.ttl index d16a5de8..f52f3721 100644 --- a/src/test/resources/stream/tcp/RMLTC0001b-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0001b-CSV-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0001b-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0001b-JSON-STREAM-TCP/mapping.ttl index 3d76606a..985397a5 100644 --- a/src/test/resources/stream/tcp/RMLTC0001b-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0001b-JSON-STREAM-TCP/mapping.ttl @@ -14,7 +14,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0001b-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0001b-XML-STREAM-TCP/mapping.ttl index fada58c1..7467bd71 100644 --- a/src/test/resources/stream/tcp/RMLTC0001b-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0001b-XML-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0002a-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0002a-CSV-STREAM-TCP/mapping.ttl index 04b98cea..32589b8a 100644 --- a/src/test/resources/stream/tcp/RMLTC0002a-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0002a-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0002a-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0002a-JSON-STREAM-TCP/mapping.ttl index 4ef9759c..bcd7cd95 100644 --- a/src/test/resources/stream/tcp/RMLTC0002a-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0002a-JSON-STREAM-TCP/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0002a-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0002a-XML-STREAM-TCP/mapping.ttl index 9aa924d1..b2b3ab44 100644 --- a/src/test/resources/stream/tcp/RMLTC0002a-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0002a-XML-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0002b-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0002b-CSV-STREAM-TCP/mapping.ttl index dff5d562..5c654cd3 100644 --- a/src/test/resources/stream/tcp/RMLTC0002b-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0002b-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0002b-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0002b-JSON-STREAM-TCP/mapping.ttl index 1da6a9f3..903d90db 100644 --- a/src/test/resources/stream/tcp/RMLTC0002b-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0002b-JSON-STREAM-TCP/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0002b-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0002b-XML-STREAM-TCP/mapping.ttl index ccb7b640..72abd6b9 100644 --- a/src/test/resources/stream/tcp/RMLTC0002b-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0002b-XML-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0002c-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0002c-CSV-STREAM-TCP/mapping.ttl index ba103d49..4e137ee6 100644 --- a/src/test/resources/stream/tcp/RMLTC0002c-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0002c-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0002c-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0002c-JSON-STREAM-TCP/mapping.ttl index acdf252a..d8423a0b 100644 --- a/src/test/resources/stream/tcp/RMLTC0002c-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0002c-JSON-STREAM-TCP/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0002c-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0002c-XML-STREAM-TCP/mapping.ttl index 686fbfdd..0d575dce 100644 --- a/src/test/resources/stream/tcp/RMLTC0002c-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0002c-XML-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0003c-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0003c-CSV-STREAM-TCP/mapping.ttl index d9e4bc78..3f6d5671 100644 --- a/src/test/resources/stream/tcp/RMLTC0003c-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0003c-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0003c-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0003c-JSON-STREAM-TCP/mapping.ttl index 073897c1..9939f323 100644 --- a/src/test/resources/stream/tcp/RMLTC0003c-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0003c-JSON-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0003c-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0003c-XML-STREAM-TCP/mapping.ttl index a5711cea..3156f98f 100644 --- a/src/test/resources/stream/tcp/RMLTC0003c-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0003c-XML-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0006a-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0006a-CSV-STREAM-TCP/mapping.ttl index 9e5b7d39..2140f898 100644 --- a/src/test/resources/stream/tcp/RMLTC0006a-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0006a-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0006a-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0006a-JSON-STREAM-TCP/mapping.ttl index 594b69ec..65505885 100644 --- a/src/test/resources/stream/tcp/RMLTC0006a-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0006a-JSON-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0006a-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0006a-XML-STREAM-TCP/mapping.ttl index 5c4c6ede..021a2220 100644 --- a/src/test/resources/stream/tcp/RMLTC0006a-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0006a-XML-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007a-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007a-CSV-STREAM-TCP/mapping.ttl index 36f250cf..a6112fed 100644 --- a/src/test/resources/stream/tcp/RMLTC0007a-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007a-CSV-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007a-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007a-JSON-STREAM-TCP/mapping.ttl index a91acde5..94181b84 100644 --- a/src/test/resources/stream/tcp/RMLTC0007a-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007a-JSON-STREAM-TCP/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007a-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007a-XML-STREAM-TCP/mapping.ttl index c6cbf84c..338a4510 100644 --- a/src/test/resources/stream/tcp/RMLTC0007a-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007a-XML-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007b-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007b-CSV-STREAM-TCP/mapping.ttl index f98f3494..48db2dac 100644 --- a/src/test/resources/stream/tcp/RMLTC0007b-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007b-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007b-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007b-JSON-STREAM-TCP/mapping.ttl index 4627f4ad..1e70336c 100644 --- a/src/test/resources/stream/tcp/RMLTC0007b-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007b-JSON-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007b-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007b-XML-STREAM-TCP/mapping.ttl index e133871d..1c5a86b1 100644 --- a/src/test/resources/stream/tcp/RMLTC0007b-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007b-XML-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007c-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007c-CSV-STREAM-TCP/mapping.ttl index d878613a..b3b042d4 100644 --- a/src/test/resources/stream/tcp/RMLTC0007c-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007c-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007c-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007c-JSON-STREAM-TCP/mapping.ttl index dba4d312..d8bc4571 100644 --- a/src/test/resources/stream/tcp/RMLTC0007c-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007c-JSON-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007c-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007c-XML-STREAM-TCP/mapping.ttl index 8557e629..4a65c4d8 100644 --- a/src/test/resources/stream/tcp/RMLTC0007c-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007c-XML-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007d-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007d-CSV-STREAM-TCP/mapping.ttl index 79ee95c0..be88c510 100644 --- a/src/test/resources/stream/tcp/RMLTC0007d-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007d-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007d-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007d-JSON-STREAM-TCP/mapping.ttl index fb477fcb..90ebc349 100644 --- a/src/test/resources/stream/tcp/RMLTC0007d-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007d-JSON-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007d-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007d-XML-STREAM-TCP/mapping.ttl index 39d17b71..0fc46314 100644 --- a/src/test/resources/stream/tcp/RMLTC0007d-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007d-XML-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007e-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007e-CSV-STREAM-TCP/mapping.ttl index aba4e8f1..e6cf9592 100644 --- a/src/test/resources/stream/tcp/RMLTC0007e-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007e-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007e-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007e-JSON-STREAM-TCP/mapping.ttl index 3e2e4d79..f91d7ddd 100644 --- a/src/test/resources/stream/tcp/RMLTC0007e-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007e-JSON-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007e-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007e-XML-STREAM-TCP/mapping.ttl index afc0c79f..9878cbbb 100644 --- a/src/test/resources/stream/tcp/RMLTC0007e-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007e-XML-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007f-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007f-CSV-STREAM-TCP/mapping.ttl index b60d372b..4b4927ec 100644 --- a/src/test/resources/stream/tcp/RMLTC0007f-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007f-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007f-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007f-JSON-STREAM-TCP/mapping.ttl index d99d0de0..562765e7 100644 --- a/src/test/resources/stream/tcp/RMLTC0007f-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007f-JSON-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007f-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007f-XML-STREAM-TCP/mapping.ttl index b87c555a..490c6087 100644 --- a/src/test/resources/stream/tcp/RMLTC0007f-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007f-XML-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007g-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007g-CSV-STREAM-TCP/mapping.ttl index 1be1fa8e..ece0a050 100644 --- a/src/test/resources/stream/tcp/RMLTC0007g-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007g-CSV-STREAM-TCP/mapping.ttl @@ -10,7 +10,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007g-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007g-JSON-STREAM-TCP/mapping.ttl index 7e038a60..f35f3775 100644 --- a/src/test/resources/stream/tcp/RMLTC0007g-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007g-JSON-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0007g-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0007g-XML-STREAM-TCP/mapping.ttl index 501be889..f948d72f 100644 --- a/src/test/resources/stream/tcp/RMLTC0007g-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0007g-XML-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0008a-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0008a-CSV-STREAM-TCP/mapping.ttl index de26610a..a3a0c901 100644 --- a/src/test/resources/stream/tcp/RMLTC0008a-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0008a-CSV-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0008a-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0008a-JSON-STREAM-TCP/mapping.ttl index 1f779eaa..aaab8e5d 100644 --- a/src/test/resources/stream/tcp/RMLTC0008a-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0008a-JSON-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0008a-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0008a-XML-STREAM-TCP/mapping.ttl index e765b989..d689e710 100644 --- a/src/test/resources/stream/tcp/RMLTC0008a-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0008a-XML-STREAM-TCP/mapping.ttl @@ -11,7 +11,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0008c-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0008c-CSV-STREAM-TCP/mapping.ttl index fafa860d..090d848d 100644 --- a/src/test/resources/stream/tcp/RMLTC0008c-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0008c-CSV-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0008c-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0008c-JSON-STREAM-TCP/mapping.ttl index ad9faf95..5acc424a 100644 --- a/src/test/resources/stream/tcp/RMLTC0008c-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0008c-JSON-STREAM-TCP/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0008c-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0008c-XML-STREAM-TCP/mapping.ttl index 8c369ae2..2e207ee2 100644 --- a/src/test/resources/stream/tcp/RMLTC0008c-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0008c-XML-STREAM-TCP/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0010a-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0010a-CSV-STREAM-TCP/mapping.ttl index a2bcd1da..73a4bfee 100644 --- a/src/test/resources/stream/tcp/RMLTC0010a-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0010a-CSV-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0010a-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0010a-JSON-STREAM-TCP/mapping.ttl index b48095de..d98f93c4 100644 --- a/src/test/resources/stream/tcp/RMLTC0010a-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0010a-JSON-STREAM-TCP/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" diff --git a/src/test/resources/stream/tcp/RMLTC0010b-CSV-SPLIT-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0010b-CSV-SPLIT-STREAM-TCP/mapping.ttl index bb9437f6..2635eb31 100644 --- a/src/test/resources/stream/tcp/RMLTC0010b-CSV-SPLIT-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0010b-CSV-SPLIT-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0010b-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0010b-CSV-STREAM-TCP/mapping.ttl index 1ec80b32..363f303b 100644 --- a/src/test/resources/stream/tcp/RMLTC0010b-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0010b-CSV-STREAM-TCP/mapping.ttl @@ -13,7 +13,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0010b-JSON-SPLIT-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0010b-JSON-SPLIT-STREAM-TCP/mapping.ttl index bbf1493c..0529776e 100644 --- a/src/test/resources/stream/tcp/RMLTC0010b-JSON-SPLIT-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0010b-JSON-SPLIT-STREAM-TCP/mapping.ttl @@ -16,8 +16,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; ]; diff --git a/src/test/resources/stream/tcp/RMLTC0010b-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0010b-JSON-STREAM-TCP/mapping.ttl index 37fb26dd..02118236 100644 --- a/src/test/resources/stream/tcp/RMLTC0010b-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0010b-JSON-STREAM-TCP/mapping.ttl @@ -16,8 +16,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.countries[*]" diff --git a/src/test/resources/stream/tcp/RMLTC0010b-XML-SPLIT-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0010b-XML-SPLIT-STREAM-TCP/mapping.ttl index 884e1344..2612087f 100644 --- a/src/test/resources/stream/tcp/RMLTC0010b-XML-SPLIT-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0010b-XML-SPLIT-STREAM-TCP/mapping.ttl @@ -16,8 +16,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:XPath; ]; diff --git a/src/test/resources/stream/tcp/RMLTC0010b-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0010b-XML-STREAM-TCP/mapping.ttl index 8ddf88a1..f1a43165 100644 --- a/src/test/resources/stream/tcp/RMLTC0010b-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0010b-XML-STREAM-TCP/mapping.ttl @@ -17,8 +17,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/countries/country" diff --git a/src/test/resources/stream/tcp/RMLTC0012a-CSV-SPLIT-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0012a-CSV-SPLIT-STREAM-TCP/mapping.ttl index 2bd488ab..da7e9668 100644 --- a/src/test/resources/stream/tcp/RMLTC0012a-CSV-SPLIT-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0012a-CSV-SPLIT-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0012a-CSV-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0012a-CSV-STREAM-TCP/mapping.ttl index 2bd488ab..121e3f39 100644 --- a/src/test/resources/stream/tcp/RMLTC0012a-CSV-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0012a-CSV-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/stream/tcp/RMLTC0012a-JSON-SPLIT-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0012a-JSON-SPLIT-STREAM-TCP/mapping.ttl index 369d197e..8aacc9ba 100644 --- a/src/test/resources/stream/tcp/RMLTC0012a-JSON-SPLIT-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0012a-JSON-SPLIT-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; ]; diff --git a/src/test/resources/stream/tcp/RMLTC0012a-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0012a-JSON-STREAM-TCP/mapping.ttl index 9c6ad611..254dc7f7 100644 --- a/src/test/resources/stream/tcp/RMLTC0012a-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0012a-JSON-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.persons[*]" ]; diff --git a/src/test/resources/stream/tcp/RMLTC0012a-XML-SPLIT-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0012a-XML-SPLIT-STREAM-TCP/mapping.ttl index c927b794..e493ab74 100644 --- a/src/test/resources/stream/tcp/RMLTC0012a-XML-SPLIT-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0012a-XML-SPLIT-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; ]; diff --git a/src/test/resources/stream/tcp/RMLTC0012a-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC0012a-XML-STREAM-TCP/mapping.ttl index 226e82c3..6611f37e 100644 --- a/src/test/resources/stream/tcp/RMLTC0012a-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC0012a-XML-STREAM-TCP/mapping.ttl @@ -12,7 +12,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ; rmls:type "PULL" ]; + rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/Persons/Person" ]; diff --git a/src/test/resources/stream/tcp/RMLTC1001-JSON-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC1001-JSON-STREAM-TCP/mapping.ttl index bced3792..c4d3b004 100644 --- a/src/test/resources/stream/tcp/RMLTC1001-JSON-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC1001-JSON-STREAM-TCP/mapping.ttl @@ -15,8 +15,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:JSONPath; rml:iterator "$.students[*]" diff --git a/src/test/resources/stream/tcp/RMLTC1001-XML-STREAM-TCP/mapping.ttl b/src/test/resources/stream/tcp/RMLTC1001-XML-STREAM-TCP/mapping.ttl index b9f76f28..f1a01a12 100644 --- a/src/test/resources/stream/tcp/RMLTC1001-XML-STREAM-TCP/mapping.ttl +++ b/src/test/resources/stream/tcp/RMLTC1001-XML-STREAM-TCP/mapping.ttl @@ -15,8 +15,7 @@ rml:source [ rdf:type rmls:TCPSocketStream ; rmls:hostName "localhost" ; - rmls:port "9999" ; - rmls:type "PULL" + rmls:port "9999" ]; rml:referenceFormulation ql:XPath; rml:iterator "/students/student" From 72dd86a163fc6abb12678923449aff5b99e70cca Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Thu, 18 Mar 2021 13:05:19 +0100 Subject: [PATCH 169/169] Update functions readme; delete unused resources. --- documentation/README_Functions.md | 3 +- src/main/resources/__________functions.ttl | 288 ------------------ src/main/resources/csv_data_mapping.ttl | 94 ------ src/main/resources/json_data_mapping.ttl | 123 -------- src/main/resources/json_join_data_mapping.ttl | 96 ------ .../resources/json_stream_data_mapping.ttl | 128 -------- .../resources/json_stream_file_mapping.ttl | 128 -------- src/main/resources/xml_data_mapping.ttl | 52 ---- src/main/resources/xml_join_data_mapping.ttl | 96 ------ 9 files changed, 2 insertions(+), 1006 deletions(-) delete mode 100644 src/main/resources/__________functions.ttl delete mode 100644 src/main/resources/csv_data_mapping.ttl delete mode 100644 src/main/resources/json_data_mapping.ttl delete mode 100644 src/main/resources/json_join_data_mapping.ttl delete mode 100644 src/main/resources/json_stream_data_mapping.ttl delete mode 100644 src/main/resources/json_stream_file_mapping.ttl delete mode 100644 src/main/resources/xml_data_mapping.ttl delete mode 100644 src/main/resources/xml_join_data_mapping.ttl diff --git a/documentation/README_Functions.md b/documentation/README_Functions.md index c05d4bad..d53ac3bf 100644 --- a/documentation/README_Functions.md +++ b/documentation/README_Functions.md @@ -186,5 +186,6 @@ to load and bind every function as specified in the testcase's `mapping.ttl`. # Remarks -- When the RMLStreamer is unable to find a function description or function mapping, bind method parameters to values, it will be logged as an error to the console. +- When the RMLStreamer is unable to find a function description or function mapping, bind method parameters to values, it will be logged as an error to the console + and the function will not be applied. \ No newline at end of file diff --git a/src/main/resources/__________functions.ttl b/src/main/resources/__________functions.ttl deleted file mode 100644 index 2aad6d4a..00000000 --- a/src/main/resources/__________functions.ttl +++ /dev/null @@ -1,288 +0,0 @@ -@prefix fno: . -@prefix lib: . -@prefix xsd: . -@prefix dcterms: . -@prefix rdf: . -@prefix rdfs: . - -@prefix : . -@prefix idlab-fn: . -@prefix grel: . - -######################## -### String functions ### -######################## - -grel:toUpperCase a fno:Function ; - fno:name "to Uppercase" ; - rdfs:label "to Uppercase" ; - dcterms:description "Returns the input with all letters in upper case." ; - fno:expects ( grel:valueParam ) ; - fno:returns ( grel:stringOut ) ; - lib:providedBy [ - lib:localLibrary "GrelFunctions.jar"; - lib:class "GrelFunctions"; - lib:method "toUppercase" - ]. - -grel:toLowerCase a fno:Function ; - fno:name "to Lowercase" ; - rdfs:label "to Lowercase" ; - dcterms:description "Returns the input with all letters in lower case." ; - fno:expects ( grel:valueParam ) ; - fno:returns ( grel:stringOut ) ; - lib:providedBy [ - lib:localLibrary "GrelFunctions.jar"; - lib:class "GrelFunctions"; - lib:method "toLowerCase" - ]. - -grel:concat a fno:Function ; - fno:name "concat" ; - rdfs:label "concat" ; - dcterms:description "Returns the concatenation of two strings." ; - fno:expects ( grel:valueParam grel:valueParam2 ) ; - fno:returns ( grel:stringOut ) ; - lib:providedBy [ - lib:localLibrary "GrelFunctions.jar"; - lib:class "GrelFunctions"; - lib:method "concat" - ]. - -grel:escape a fno:Function ; - fno:name "escape" ; - rdfs:label "escape" ; - dcterms:description "Escapes a string, with a mode parameter." ; - fno:expects ( grel:valueParam grel:modeParam ) ; - fno:returns ( grel:stringOut ) ; - lib:providedBy [ - lib:localLibrary "GrelFunctions.jar"; - lib:class "GrelFunctions"; - lib:method "escape" - ]. - -grel:random a fno:Function ; - fno:name "random" ; - rdfs:label "random" ; - dcterms:description "Returns a random uuid." ; - fno:expects ( ) ; - fno:returns ( grel:stringOut ) ; - lib:providedBy [ - lib:localLibrary "GrelFunctions.jar"; - lib:class "GrelFunctions"; - lib:method "random" - ]. - -grel:toUpperCaseURL a fno:Function ; - fno:name "toUpperCaseURL" ; - rdfs:label "toUpperCaseURL" ; - dcterms:description "Returns an uppercase, valid url." ; - fno:expects ( grel:valueParam ) ; - fno:returns ( grel:stringOut ) ; - lib:providedBy [ - lib:localLibrary "GrelFunctions.jar"; - lib:class "GrelFunctions"; - lib:method "toUpperCaseURL" - ]. - -idlab-fn:equal a fno:Function ; - fno:name "equal" ; - rdfs:label "equal" ; - dcterms:description "Returns true if strings are equal." ; - fno:expects ( grel:valueParam grel:valueParam2 ) ; - fno:returns ( grel:stringOut ) ; - lib:providedBy [ - lib:localLibrary "UtilFunctions.jar"; - lib:class "UtilFunctions"; - lib:method "equal" - ]. - -idlab-fn:notEqual a fno:Function ; - fno:name "not equal" ; - rdfs:label "not equal" ; - dcterms:description "Returns true if strings are not equal." ; - fno:expects ( grel:valueParam grel:valueParam2 ) ; - fno:returns ( grel:stringOut ) ; - lib:providedBy [ - lib:localLibrary "UtilFunctions.jar"; - lib:class "UtilFunctions"; - lib:method "notEqual" - ]. - -grel:valueParam a fno:Parameter ; - fno:name "input value" ; - rdfs:label "input value" ; - fno:type xsd:string ; - fno:predicate grel:valueParameter . - -grel:valueParam2 a fno:Parameter ; - fno:name "input value 2" ; - rdfs:label "input value 2" ; - fno:type xsd:string ; - fno:predicate grel:valueParameter2 . - -grel:modeParam a fno:Parameter ; - fno:name "mode value" ; - rdfs:label "mode value" ; - fno:type xsd:string ; - fno:predicate grel:modeParameter . - -grel:stringOut a fno:Output ; - fno:name "output string" ; - rdfs:label "output string" ; - fno:type xsd:string ; - fno:predicate grel:stringOutput . - -####################### -### IDLab Functions ### -####################### - -idlab-fn:stringContainsOtherString a fno:Function ; - fno:name "stringContainsOtherString" ; - rdfs:label "stringContainsOtherString" ; - dcterms:description "Returns true if a string is found in a delimited string." ; - fno:expects ( idlab-fn:_str idlab-fn:_otherStr idlab-fn:_delimiter ) ; - fno:returns ( idlab-fn:_stringOut ) ; - lib:providedBy [ - lib:localLibrary "IDLabFunctions.jar"; - lib:class "IDLabFunctions"; - lib:method "stringContainsOtherString" - ]. - -idlab-fn:listContainsElement a fno:Function ; - fno:name "listContainsElement" ; - rdfs:label "listContainsElement" ; - dcterms:description "Returns true if the string is found in the list" ; - fno:expects ( idlab-fn:_list idlab-fn:_str ) ; - fno:returns ( idlab-fn:_stringOut ) ; - lib:providedBy [ - lib:localLibrary "IDLabFunctions.jar"; - lib:class "IDLabFunctions"; - lib:method "listContainsElement" - ]. - -idlab-fn:getMIMEType a fno:Function ; - fno:name "getMIMEType" ; - rdfs:label "getMIMEType" ; - dcterms:description "Returns the MIME Type of a filename" ; - fno:expects ( idlab-fn:_str ) ; - fno:returns ( idlab-fn:_stringOut ) ; - lib:providedBy [ - lib:localLibrary "IDLabFunctions.jar"; - lib:class "IDLabFunctions"; - lib:method "getMIMEType" - ]. - -idlab-fn:decide a fno:Function ; - fno:name "decide" ; - rdfs:label "decide" ; - dcterms:description "Returns a given value if input is equal to another given value" ; - fno:expects ( idlab-fn:_str idlab-fn:_expectedStr idlab-fn:_result ) ; - fno:returns ( idlab-fn:_stringOut ) ; - lib:providedBy [ - lib:localLibrary "IDLabFunctions.jar"; - lib:class "IDLabFunctions"; - lib:method "decide" - ]. - -idlab-fn:dbpediaSpotlight a fno:Function ; - fno:name "DBpedia Spotlight annotate" ; - rdfs:label "DBpedia Spotlight annotate" ; - dcterms:description "Returns the DBpedia URLs of the detected entities in the input text" ; - fno:expects ( idlab-fn:_str idlab-fn:_endpoint ) ; - fno:returns ( idlab-fn:_stringOut ) ; - lib:providedBy [ - lib:localLibrary "IDLabFunctions.jar"; - lib:class "IDLabFunctions"; - lib:method "dbpediaSpotlight" - ]. - -idlab-fn:trueCondition a fno:Function ; - fno:name "True condition" ; - rdfs:label "True condition" ; - dcterms:description "Returns the value if the given boolean is true, else null" ; - fno:expects ( idlab-fn:_strBoolean idlab-fn:_str ) ; - fno:returns ( idlab-fn:_stringOut ) ; - lib:providedBy [ - lib:localLibrary "IDLabFunctions.jar"; - lib:class "IDLabFunctions"; - lib:method "trueCondition" - ]. - -idlab-fn:readFile a fno:Function ; - fno:name "Read local file as string" ; - rdfs:label "Read local file as string" ; - dcterms:description "Returns the content of a local file as string" ; - fno:expects ( idlab-fn:_path ) ; - fno:returns ( idlab-fn:_stringOut ) ; - lib:providedBy [ - lib:localLibrary "IDLabFunctions.jar"; - lib:class "IDLabFunctions"; - lib:method "readFile" - ]. - -idlab-fn:_path a fno:Parameter ; - fno:name "input path" ; - rdfs:label "input path" ; - fno:type xsd:string ; - fno:predicate idlab-fn:path . - -idlab-fn:_str a fno:Parameter ; - fno:name "input string" ; - rdfs:label "input string" ; - fno:type xsd:string ; - fno:predicate idlab-fn:str . - -idlab-fn:_strBoolean a fno:Parameter ; - fno:name "boolean encoded as string" ; - rdfs:label "boolean encoded as string" ; - fno:type xsd:string ; - fno:predicate idlab-fn:strBoolean . - -idlab-fn:_endpoint a fno:Parameter ; - fno:name "endpoint url string" ; - rdfs:label "endpoint url string" ; - fno:type xsd:string ; - fno:predicate idlab-fn:endpoint . - -idlab-fn:_otherStr a fno:Parameter ; - fno:name "other input string" ; - rdfs:label "other input string" ; - fno:type xsd:string ; - fno:predicate idlab-fn:otherStr . - -idlab-fn:_expectedStr a fno:Parameter ; - fno:name "expected input string" ; - rdfs:label "expected input string" ; - fno:type xsd:string ; - fno:predicate idlab-fn:expectedStr . - -idlab-fn:_result a fno:Parameter ; - fno:name "result string" ; - rdfs:label "result string" ; - fno:type xsd:string ; - fno:predicate idlab-fn:result . - -idlab-fn:_list a fno:Parameter ; - fno:name "list" ; - rdfs:label "list" ; - fno:type rdf:List ; - fno:predicate idlab-fn:list . - -idlab-fn:_listOut a fno:Parameter ; - fno:name "output list" ; - rdfs:label "output list" ; - fno:type rdf:List ; - fno:predicate idlab-fn:listOut . - -idlab-fn:_delimiter a fno:Parameter ; - fno:name "delimiter" ; - rdfs:label "delimiter" ; - fno:type xsd:string ; - fno:predicate idlab-fn:delimiter . - -idlab-fn:_stringOut a fno:Output ; - fno:name "output string" ; - rdfs:label "output string" ; - fno:type xsd:string ; - fno:predicate idlab-fn:stringOut . \ No newline at end of file diff --git a/src/main/resources/csv_data_mapping.ttl b/src/main/resources/csv_data_mapping.ttl deleted file mode 100644 index 1ed1a719..00000000 --- a/src/main/resources/csv_data_mapping.ttl +++ /dev/null @@ -1,94 +0,0 @@ -@prefix rr: . -@prefix rml: . -@prefix ql: . -@prefix rdfs: . -@prefix oslo: . -@prefix adms: . -@prefix skos: . -@prefix vcard: . -@prefix dcterms: . -@prefix adms: . -@prefix locn: . - - - -# LIJSTProducttype - - <#LogicalSource> - a rml:LogicalSource; - rml:source "/home/wmaroy/github/rml-framework/akka-pipeline/src/main/resources/io/rml/framework/data/airplane_data_headers.csv"; - rml:referenceFormulation ql:CSV. - - <#LogicalSource_2> - a rml:LogicalSource; - rml:source "/home/wmaroy/github/rml-framework/akka-pipeline/src/main/resources/io/rml/framework/data/airplane_data_headers.csv"; - rml:referenceFormulation ql:CSV. - - <#LIJSTProducttype_only_subject> - - a rr:TriplesMap; - rml:logicalSource <#LogicalSource>; - - rr:subjectMap [ - rr:template "https://io.rml.airports/{Name}"; - rr:termType rr:IRI; - rr:class skos:Concept - ]. - - - <#ParentTriplesMap> - a rr:TriplesMap; - rml:logicalSource <#LogicalSource_2>; - rr:subjectMap [ - rr:template "https://io.rml.airports/parent/{Name}"; - rr:termType rr:IRI; - rr:class skos:Concept - ]. - - <#LIJSTProducttype> - - a rr:TriplesMap; - rml:logicalSource <#LogicalSource>; - - rr:subjectMap [ - rml:reference "AirlineID"; - rr:termType rr:IRI; - rr:class skos:Concept - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "Name"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:parent; - rr:termType rr:IRI - ]; - rr:objectMap [ - rr:parentTriplesMap <#ParentTriplesMap>; - rr:joinCondition [ - rr:parent "Name" ; - rr:child "Name" - ]; - rr:termType rr:IRI - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:city; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "City"; - rr:termType rr:Literal - ] - ]. diff --git a/src/main/resources/json_data_mapping.ttl b/src/main/resources/json_data_mapping.ttl deleted file mode 100644 index e58d25dc..00000000 --- a/src/main/resources/json_data_mapping.ttl +++ /dev/null @@ -1,123 +0,0 @@ -@prefix rr: . -@prefix rml: . -@prefix ql: . -@prefix rdfs: . -@prefix oslo: . -@prefix adms: . -@prefix skos: . -@prefix vcard: . -@prefix dcterms: . -@prefix adms: . -@prefix locn: . - - - -# LIJSTProducttype - - <#LIJSTProducttype> - - a rr:TriplesMap; - rml:logicalSource [ - rml:source "/home/wmaroy/github/rml-framework/akka-pipeline/src/main/resources/io/rml/framework/data/books_small.json"; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.store.books" - ]; - - rr:subjectMap [ - rml:reference "id"; - rr:termType rr:IRI; - rr:class skos:Concept - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "id"; - rr:termType rr:Literal - ] - ]; - - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "id"; - rr:termType rr:Literal - ] - ]; - - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "id"; - rr:termType rr:Literal - ] - ]; - - - - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rr:template "test/{id}"; - rr:termType rr:IRI - ] - ]. diff --git a/src/main/resources/json_join_data_mapping.ttl b/src/main/resources/json_join_data_mapping.ttl deleted file mode 100644 index 5213b412..00000000 --- a/src/main/resources/json_join_data_mapping.ttl +++ /dev/null @@ -1,96 +0,0 @@ -@prefix rr: . -@prefix rml: . -@prefix ql: . -@prefix rdfs: . -@prefix oslo: . -@prefix adms: . -@prefix skos: . -@prefix vcard: . -@prefix dcterms: . -@prefix adms: . -@prefix locn: . - - - -# LIJSTProducttype - - <#LogicalSource> - a rml:LogicalSource; - rml:source "file:///home/wmaroy/github/rml-framework/akka-pipeline/src/main/resources/io/rml/framework/data/books.json"; - rml:iterator "id" ; - rml:referenceFormulation ql:JSONPath. - - <#LogicalSource_2> - a rml:LogicalSource; - rml:source "file:///home/wmaroy/github/rml-framework/akka-pipeline/src/main/resources/io/rml/framework/data/books.json"; - rml:iterator "id" ; - rml:referenceFormulation ql:JSONPath. - - <#LIJSTProducttype_only_subject> - - a rr:TriplesMap; - rml:logicalSource <#LogicalSource>; - - rr:subjectMap [ - rr:template "https://io.rml.airports/{id}"; - rr:termType rr:IRI; - rr:class skos:Concept - ]. - - - <#ParentTriplesMap> - a rr:TriplesMap; - rml:logicalSource <#LogicalSource_2>; - rr:subjectMap [ - rr:template "https://io.rml.airports/parent/{id}"; - rr:termType rr:IRI; - rr:class skos:Concept - ]. - - <#LIJSTProducttype> - - a rr:TriplesMap; - rml:logicalSource <#LogicalSource>; - - rr:subjectMap [ - rml:reference "id"; - rr:termType rr:IRI; - rr:class skos:Concept - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:parent; - rr:termType rr:IRI - ]; - rr:objectMap [ - rr:parentTriplesMap <#ParentTriplesMap>; - rr:joinCondition [ - rr:parent "id" ; - rr:child "id" - ]; - rr:termType rr:IRI - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:city; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "id"; - rr:termType rr:Literal - ] - ]. diff --git a/src/main/resources/json_stream_data_mapping.ttl b/src/main/resources/json_stream_data_mapping.ttl deleted file mode 100644 index 91fd48bb..00000000 --- a/src/main/resources/json_stream_data_mapping.ttl +++ /dev/null @@ -1,128 +0,0 @@ -@prefix rr: . -@prefix rml: . -@prefix rmls: . -@prefix ql: . -@prefix rdfs: . -@prefix oslo: . -@prefix adms: . -@prefix skos: . -@prefix vcard: . -@prefix dcterms: . -@prefix adms: . -@prefix locn: . -@prefix rdf: . - - - -# LIJSTProducttype - - <#LIJSTProducttype> - - a rr:TriplesMap; - rml:logicalSource [ - rml:source [ - rdf:type rmls:TCPSocketStream ; - rmls:hostName "localhost"; - rmls:port "5005" - ]; - rml:referenceFormulation ql:JSONPath; - ]; - - rr:subjectMap [ - rml:reference "$.id"; - rr:termType rr:IRI; - rr:class skos:Concept - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - - - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rr:template "test/{$.id}"; - rr:termType rr:IRI - ] - ]. diff --git a/src/main/resources/json_stream_file_mapping.ttl b/src/main/resources/json_stream_file_mapping.ttl deleted file mode 100644 index e4fc428e..00000000 --- a/src/main/resources/json_stream_file_mapping.ttl +++ /dev/null @@ -1,128 +0,0 @@ -@prefix rr: . -@prefix rml: . -@prefix rmls: . -@prefix ql: . -@prefix rdfs: . -@prefix oslo: . -@prefix adms: . -@prefix skos: . -@prefix vcard: . -@prefix dcterms: . -@prefix adms: . -@prefix locn: . -@prefix rdf: . - - - -# LIJSTProducttype - - <#LIJSTProducttype> - - a rr:TriplesMap; - rml:logicalSource [ - rml:source [ - rdf:type rmls:FileStream; - rmls:path "/home/wmaroy/github/rml-framework/akka-pipeline/src/main/resources/io/rml/framework/data/books.json" - ]; - rml:referenceFormulation ql:JSONPath; - rml:iterator "$.store.books[*]" - ]; - - rr:subjectMap [ - rr:template "{$.id}" ; - rr:termType rr:IRI; - rr:class skos:Concept - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - - - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "$.id"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rr:template "{$.id}"; - rr:termType rr:IRI - ] - ]. diff --git a/src/main/resources/xml_data_mapping.ttl b/src/main/resources/xml_data_mapping.ttl deleted file mode 100644 index d18736d2..00000000 --- a/src/main/resources/xml_data_mapping.ttl +++ /dev/null @@ -1,52 +0,0 @@ -@prefix rr: . -@prefix rml: . -@prefix ql: . -@prefix rdfs: . -@prefix oslo: . -@prefix adms: . -@prefix skos: . -@prefix vcard: . -@prefix dcterms: . -@prefix adms: . -@prefix locn: . - - - -# LIJSTProducttype - - <#LIJSTProducttype> - - a rr:TriplesMap; - rml:logicalSource [ - rml:source "/home/wmaroy/Downloads/standard"; - rml:referenceFormulation ql:XPath; - rml:iterator "/site/regions/africa/item" - ]; - - rr:subjectMap [ - rml:reference "/item/name"; - rr:termType rr:IRI; - rr:class skos:Concept - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "/item/location"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rr:template "test/{/item/location}"; - rr:termType rr:IRI - ] - ]. diff --git a/src/main/resources/xml_join_data_mapping.ttl b/src/main/resources/xml_join_data_mapping.ttl deleted file mode 100644 index a5653faa..00000000 --- a/src/main/resources/xml_join_data_mapping.ttl +++ /dev/null @@ -1,96 +0,0 @@ -@prefix rr: . -@prefix rml: . -@prefix ql: . -@prefix rdfs: . -@prefix oslo: . -@prefix adms: . -@prefix skos: . -@prefix vcard: . -@prefix dcterms: . -@prefix adms: . -@prefix locn: . - - - -# LIJSTProducttype - - <#LogicalSource> - a rml:LogicalSource; - rml:source "/home/wmaroy/Downloads/standard"; - rml:referenceFormulation ql:XPath; - rml:iterator "/site/regions/africa/item". - - <#LogicalSource_2> - a rml:LogicalSource; - rml:source "/home/wmaroy/Downloads/standard"; - rml:referenceFormulation ql:XPath; - rml:iterator "/site/regions/africa/item". - - <#LIJSTProducttype_only_subject> - - a rr:TriplesMap; - rml:logicalSource <#LogicalSource>; - - rr:subjectMap [ - rr:template "https://io.rml.airports/{/item/name}"; - rr:termType rr:IRI; - rr:class skos:Concept - ]. - - - <#ParentTriplesMap> - a rr:TriplesMap; - rml:logicalSource <#LogicalSource_2>; - rr:subjectMap [ - rr:template "https://io.rml.airports/parent/{/item/location}"; - rr:termType rr:IRI; - rr:class skos:Concept - ]. - - <#LIJSTProducttype> - - a rr:TriplesMap; - rml:logicalSource <#LogicalSource>; - - rr:subjectMap [ - rml:reference "/item/name"; - rr:termType rr:IRI; - rr:class skos:Concept - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:title; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "/item/name"; - rr:termType rr:Literal - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:parent; - rr:termType rr:IRI - ]; - rr:objectMap [ - rr:parentTriplesMap <#ParentTriplesMap>; - rr:joinCondition [ - rr:parent "/item/name" ; - rr:child "/item/name" - ]; - rr:termType rr:IRI - ] - ]; - - rr:predicateObjectMap [ - rr:predicateMap [ - rr:constant dcterms:city; - rr:termType rr:IRI - ]; - rr:objectMap [ - rml:reference "/item/name"; - rr:termType rr:Literal - ] - ].

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 literal 0 HcmV?d00001 diff --git a/documentation/img/copy_repo_link.png b/documentation/img/copy_repo_link.png new file mode 100644 index 0000000000000000000000000000000000000000..c9b3bd88e867c6cbc66bd83aa32f8502d50d0c88 GIT binary patch literal 87729 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 literal 0 HcmV?d00001 diff --git a/documentation/img/get_build.png b/documentation/img/get_build.png new file mode 100644 index 0000000000000000000000000000000000000000..82f96d6b8ad661ef6b85603dd71e5fcda457bc87 GIT binary patch literal 58758 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%0D+#l58k?_OZ7y1 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 literal 0 HcmV?d00001 diff --git a/documentation/img/paste_repo_link.png b/documentation/img/paste_repo_link.png new file mode 100644 index 0000000000000000000000000000000000000000..9ddd2884a4ed7f697a7155993b3bd231dec1b628 GIT binary patch literal 185531 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

|Kp?c>*zK^u$ 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ಱi+3}G~Fe4k7F5Yzrq#vdH}ij;2* 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 z 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≺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�(gwP)>9FxEnU*j15wa-k%p`ry{EAA^ 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
CLy1XjM0ai2t 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/functions.ttl b/src/main/resources/functions.ttl new file mode 100644 index 00000000..2aad6d4a --- /dev/null +++ b/src/main/resources/functions.ttl @@ -0,0 +1,288 @@ +@prefix fno: . +@prefix lib: . +@prefix xsd: . +@prefix dcterms: . +@prefix rdf: . +@prefix rdfs: . + +@prefix : . +@prefix idlab-fn: . +@prefix grel: . + +######################## +### String functions ### +######################## + +grel:toUpperCase a fno:Function ; + fno:name "to Uppercase" ; + rdfs:label "to Uppercase" ; + dcterms:description "Returns the input with all letters in upper case." ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:stringOut ) ; + lib:providedBy [ + lib:localLibrary "GrelFunctions.jar"; + lib:class "GrelFunctions"; + lib:method "toUppercase" + ]. + +grel:toLowerCase a fno:Function ; + fno:name "to Lowercase" ; + rdfs:label "to Lowercase" ; + dcterms:description "Returns the input with all letters in lower case." ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:stringOut ) ; + lib:providedBy [ + lib:localLibrary "GrelFunctions.jar"; + lib:class "GrelFunctions"; + lib:method "toLowerCase" + ]. + +grel:concat a fno:Function ; + fno:name "concat" ; + rdfs:label "concat" ; + dcterms:description "Returns the concatenation of two strings." ; + fno:expects ( grel:valueParam grel:valueParam2 ) ; + fno:returns ( grel:stringOut ) ; + lib:providedBy [ + lib:localLibrary "GrelFunctions.jar"; + lib:class "GrelFunctions"; + lib:method "concat" + ]. + +grel:escape a fno:Function ; + fno:name "escape" ; + rdfs:label "escape" ; + dcterms:description "Escapes a string, with a mode parameter." ; + fno:expects ( grel:valueParam grel:modeParam ) ; + fno:returns ( grel:stringOut ) ; + lib:providedBy [ + lib:localLibrary "GrelFunctions.jar"; + lib:class "GrelFunctions"; + lib:method "escape" + ]. + +grel:random a fno:Function ; + fno:name "random" ; + rdfs:label "random" ; + dcterms:description "Returns a random uuid." ; + fno:expects ( ) ; + fno:returns ( grel:stringOut ) ; + lib:providedBy [ + lib:localLibrary "GrelFunctions.jar"; + lib:class "GrelFunctions"; + lib:method "random" + ]. + +grel:toUpperCaseURL a fno:Function ; + fno:name "toUpperCaseURL" ; + rdfs:label "toUpperCaseURL" ; + dcterms:description "Returns an uppercase, valid url." ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:stringOut ) ; + lib:providedBy [ + lib:localLibrary "GrelFunctions.jar"; + lib:class "GrelFunctions"; + lib:method "toUpperCaseURL" + ]. + +idlab-fn:equal a fno:Function ; + fno:name "equal" ; + rdfs:label "equal" ; + dcterms:description "Returns true if strings are equal." ; + fno:expects ( grel:valueParam grel:valueParam2 ) ; + fno:returns ( grel:stringOut ) ; + lib:providedBy [ + lib:localLibrary "UtilFunctions.jar"; + lib:class "UtilFunctions"; + lib:method "equal" + ]. + +idlab-fn:notEqual a fno:Function ; + fno:name "not equal" ; + rdfs:label "not equal" ; + dcterms:description "Returns true if strings are not equal." ; + fno:expects ( grel:valueParam grel:valueParam2 ) ; + fno:returns ( grel:stringOut ) ; + lib:providedBy [ + lib:localLibrary "UtilFunctions.jar"; + lib:class "UtilFunctions"; + lib:method "notEqual" + ]. + +grel:valueParam a fno:Parameter ; + fno:name "input value" ; + rdfs:label "input value" ; + fno:type xsd:string ; + fno:predicate grel:valueParameter . + +grel:valueParam2 a fno:Parameter ; + fno:name "input value 2" ; + rdfs:label "input value 2" ; + fno:type xsd:string ; + fno:predicate grel:valueParameter2 . + +grel:modeParam a fno:Parameter ; + fno:name "mode value" ; + rdfs:label "mode value" ; + fno:type xsd:string ; + fno:predicate grel:modeParameter . + +grel:stringOut a fno:Output ; + fno:name "output string" ; + rdfs:label "output string" ; + fno:type xsd:string ; + fno:predicate grel:stringOutput . + +####################### +### IDLab Functions ### +####################### + +idlab-fn:stringContainsOtherString a fno:Function ; + fno:name "stringContainsOtherString" ; + rdfs:label "stringContainsOtherString" ; + dcterms:description "Returns true if a string is found in a delimited string." ; + fno:expects ( idlab-fn:_str idlab-fn:_otherStr idlab-fn:_delimiter ) ; + fno:returns ( idlab-fn:_stringOut ) ; + lib:providedBy [ + lib:localLibrary "IDLabFunctions.jar"; + lib:class "IDLabFunctions"; + lib:method "stringContainsOtherString" + ]. + +idlab-fn:listContainsElement a fno:Function ; + fno:name "listContainsElement" ; + rdfs:label "listContainsElement" ; + dcterms:description "Returns true if the string is found in the list" ; + fno:expects ( idlab-fn:_list idlab-fn:_str ) ; + fno:returns ( idlab-fn:_stringOut ) ; + lib:providedBy [ + lib:localLibrary "IDLabFunctions.jar"; + lib:class "IDLabFunctions"; + lib:method "listContainsElement" + ]. + +idlab-fn:getMIMEType a fno:Function ; + fno:name "getMIMEType" ; + rdfs:label "getMIMEType" ; + dcterms:description "Returns the MIME Type of a filename" ; + fno:expects ( idlab-fn:_str ) ; + fno:returns ( idlab-fn:_stringOut ) ; + lib:providedBy [ + lib:localLibrary "IDLabFunctions.jar"; + lib:class "IDLabFunctions"; + lib:method "getMIMEType" + ]. + +idlab-fn:decide a fno:Function ; + fno:name "decide" ; + rdfs:label "decide" ; + dcterms:description "Returns a given value if input is equal to another given value" ; + fno:expects ( idlab-fn:_str idlab-fn:_expectedStr idlab-fn:_result ) ; + fno:returns ( idlab-fn:_stringOut ) ; + lib:providedBy [ + lib:localLibrary "IDLabFunctions.jar"; + lib:class "IDLabFunctions"; + lib:method "decide" + ]. + +idlab-fn:dbpediaSpotlight a fno:Function ; + fno:name "DBpedia Spotlight annotate" ; + rdfs:label "DBpedia Spotlight annotate" ; + dcterms:description "Returns the DBpedia URLs of the detected entities in the input text" ; + fno:expects ( idlab-fn:_str idlab-fn:_endpoint ) ; + fno:returns ( idlab-fn:_stringOut ) ; + lib:providedBy [ + lib:localLibrary "IDLabFunctions.jar"; + lib:class "IDLabFunctions"; + lib:method "dbpediaSpotlight" + ]. + +idlab-fn:trueCondition a fno:Function ; + fno:name "True condition" ; + rdfs:label "True condition" ; + dcterms:description "Returns the value if the given boolean is true, else null" ; + fno:expects ( idlab-fn:_strBoolean idlab-fn:_str ) ; + fno:returns ( idlab-fn:_stringOut ) ; + lib:providedBy [ + lib:localLibrary "IDLabFunctions.jar"; + lib:class "IDLabFunctions"; + lib:method "trueCondition" + ]. + +idlab-fn:readFile a fno:Function ; + fno:name "Read local file as string" ; + rdfs:label "Read local file as string" ; + dcterms:description "Returns the content of a local file as string" ; + fno:expects ( idlab-fn:_path ) ; + fno:returns ( idlab-fn:_stringOut ) ; + lib:providedBy [ + lib:localLibrary "IDLabFunctions.jar"; + lib:class "IDLabFunctions"; + lib:method "readFile" + ]. + +idlab-fn:_path a fno:Parameter ; + fno:name "input path" ; + rdfs:label "input path" ; + fno:type xsd:string ; + fno:predicate idlab-fn:path . + +idlab-fn:_str a fno:Parameter ; + fno:name "input string" ; + rdfs:label "input string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:str . + +idlab-fn:_strBoolean a fno:Parameter ; + fno:name "boolean encoded as string" ; + rdfs:label "boolean encoded as string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:strBoolean . + +idlab-fn:_endpoint a fno:Parameter ; + fno:name "endpoint url string" ; + rdfs:label "endpoint url string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:endpoint . + +idlab-fn:_otherStr a fno:Parameter ; + fno:name "other input string" ; + rdfs:label "other input string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:otherStr . + +idlab-fn:_expectedStr a fno:Parameter ; + fno:name "expected input string" ; + rdfs:label "expected input string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:expectedStr . + +idlab-fn:_result a fno:Parameter ; + fno:name "result string" ; + rdfs:label "result string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:result . + +idlab-fn:_list a fno:Parameter ; + fno:name "list" ; + rdfs:label "list" ; + fno:type rdf:List ; + fno:predicate idlab-fn:list . + +idlab-fn:_listOut a fno:Parameter ; + fno:name "output list" ; + rdfs:label "output list" ; + fno:type rdf:List ; + fno:predicate idlab-fn:listOut . + +idlab-fn:_delimiter a fno:Parameter ; + fno:name "delimiter" ; + rdfs:label "delimiter" ; + fno:type xsd:string ; + fno:predicate idlab-fn:delimiter . + +idlab-fn:_stringOut a fno:Output ; + fno:name "output string" ; + rdfs:label "output string" ; + fno:type xsd:string ; + fno:predicate idlab-fn:stringOut . \ No newline at end of file From 32fa206252dfea851f031c4a29cfd1472fe6fb2a Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 14:10:10 +0200 Subject: [PATCH 007/169] wip: function feature - changes to extractors, model and engine extractor changes: - output type of an extractor (R) is now covariant - transferred StdTransformationMappingExtractor from function_map branch - transferred TransformationMappnig from function_map branch assembler changes: - replaced NotImplementedErrors with implementation --- .../io/rml/framework/api/RMLEnvironment.scala | 2 +- .../framework/core/extractors/Extractor.scala | 2 +- .../core/extractors/GraphExtractor.scala | 2 +- .../core/extractors/MappingExtractor.scala | 19 ++++++-- .../core/extractors/MappingReader.scala | 17 +++++--- .../extractors/std/StdMappingExtractor.scala | 2 +- .../extractors/std/StdMappingReader.scala | 8 ++-- .../StdTransformationMappingExtractor.scala | 22 ++++++++++ .../core/model/TransformationMapping.scala | 43 +++++++++++++++++++ .../model/std/StdTransformationMapping.scala | 7 +++ .../io/rml/framework/core/util/Util.scala | 4 +- .../FunctionMapGeneratorAssembler.scala | 30 +++++++------ .../statement/ObjectGeneratorAssembler.scala | 9 ++-- 13 files changed, 129 insertions(+), 38 deletions(-) create mode 100644 src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala create mode 100644 src/main/scala/io/rml/framework/core/model/TransformationMapping.scala create mode 100644 src/main/scala/io/rml/framework/core/model/std/StdTransformationMapping.scala diff --git a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala index 92cc24c8..2d3278da 100644 --- a/src/main/scala/io/rml/framework/api/RMLEnvironment.scala +++ b/src/main/scala/io/rml/framework/api/RMLEnvironment.scala @@ -58,7 +58,7 @@ object RMLEnvironment { def loadMappingFromFile(path: String): RMLMapping = { val file = new File(path) - FormattedRMLMapping.fromRMLMapping(MappingReader().read(file)) + FormattedRMLMapping.fromRMLMapping(MappingReader().read(file).asInstanceOf[RMLMapping]) } def executeMapping(): Unit = ??? diff --git a/src/main/scala/io/rml/framework/core/extractors/Extractor.scala b/src/main/scala/io/rml/framework/core/extractors/Extractor.scala index 0e78bea2..2d7fa16b 100644 --- a/src/main/scala/io/rml/framework/core/extractors/Extractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/Extractor.scala @@ -34,7 +34,7 @@ import io.rml.framework.shared.RMLException * @tparam T RDFNode to extract from. * @tparam R Return type of extract. */ -trait Extractor[T <: RDFNode, R] { +trait Extractor[T <: RDFNode, +R] { /** * Extract. diff --git a/src/main/scala/io/rml/framework/core/extractors/GraphExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/GraphExtractor.scala index 6b5b7c23..18765f1a 100644 --- a/src/main/scala/io/rml/framework/core/extractors/GraphExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/GraphExtractor.scala @@ -27,4 +27,4 @@ package io.rml.framework.core.extractors import io.rml.framework.core.model.rdf.RDFGraph -trait GraphExtractor[T] extends Extractor[RDFGraph, T] +trait GraphExtractor[+T] extends Extractor[RDFGraph, T] diff --git a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala index 474cddf9..aa397189 100644 --- a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala @@ -25,11 +25,22 @@ package io.rml.framework.core.extractors -import io.rml.framework.core.extractors.std.StdMappingExtractor -import io.rml.framework.core.model.RMLMapping +import io.rml.framework.core.extractors.std.{StdFunctionMapExtractor, StdMappingExtractor, StdTransformationMappingExtractor} +import io.rml.framework.core.model.{Graph, RMLMapping, TransformationMapping} -trait MappingExtractor extends GraphExtractor[RMLMapping] +trait MappingExtractor [+T<: Graph]extends GraphExtractor[T] object MappingExtractor { - def apply(): MappingExtractor = new StdMappingExtractor() + + // todo: can this be safely deleted? + def apply(): MappingExtractor[RMLMapping] = new StdMappingExtractor() + + def apply [T<:Graph](cls: Any): MappingExtractor[Graph] = { + cls match{ + case RMLMapping => new StdMappingExtractor() + case TransformationMapping => new StdTransformationMappingExtractor() + case _ => throw new IllegalArgumentException("Given args can only be subclasses of Mapping") + } + + } } diff --git a/src/main/scala/io/rml/framework/core/extractors/MappingReader.scala b/src/main/scala/io/rml/framework/core/extractors/MappingReader.scala index d6eafd35..1255b6de 100644 --- a/src/main/scala/io/rml/framework/core/extractors/MappingReader.scala +++ b/src/main/scala/io/rml/framework/core/extractors/MappingReader.scala @@ -28,13 +28,13 @@ package io.rml.framework.core.extractors import java.io.File import io.rml.framework.core.extractors.std.StdMappingReader -import io.rml.framework.core.model.{RMLMapping, Uri} +import io.rml.framework.core.model.{Graph, RMLMapping, Uri} import io.rml.framework.shared.ReadException /** * This trait defines interfaces for reading RML mappings from file or from in-memory strings. */ -trait MappingReader { +trait MappingReader[+OUT] { /** * Reads a file and converts it to an RMLMapping. @@ -44,7 +44,7 @@ trait MappingReader { * @return */ @throws(classOf[ReadException]) - def read(file: File): RMLMapping + def read(file: File): OUT /** * Reads a dump and converts it to an RMLMapping @@ -55,7 +55,7 @@ trait MappingReader { * @return */ @throws(classOf[ReadException]) - def read(dump: String, graphUri: Uri): RMLMapping + def read(dump: String, graphUri: Uri): OUT } @@ -63,12 +63,17 @@ trait MappingReader { * Object with factory apply method for MappingReader. */ object MappingReader { - - def apply(mappingExtractor: MappingExtractor = MappingExtractor()): MappingReader = { + def apply(mappingExtractor: MappingExtractor[Graph] = MappingExtractor(RMLMapping)): MappingReader[Graph] = { lazy val reader = new StdMappingReader(mappingExtractor) reader } +// def apply(mappingExtractor: MappingExtractor[Graph] = MappingExtractor()) +// : MappingReader[Graph] = { +// lazy val reader = new StdMappingReader(mappingExtractor) +// reader +// } + } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdMappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdMappingExtractor.scala index 4e673904..de7db01f 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdMappingExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdMappingExtractor.scala @@ -33,7 +33,7 @@ import io.rml.framework.core.model.rdf.RDFGraph * Extractor for RMLMappings that injects all dependencies for all * sub-extractors. */ -class StdMappingExtractor extends MappingExtractor { +class StdMappingExtractor extends MappingExtractor[RMLMapping] { /** * Extract. diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdMappingReader.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdMappingReader.scala index 5f7865af..1f11b597 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdMappingReader.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdMappingReader.scala @@ -30,14 +30,14 @@ import java.io.File import io.rml.framework.api.RMLEnvironment import io.rml.framework.core.extractors.{MappingExtractor, MappingReader} import io.rml.framework.core.model.rdf.RDFGraph -import io.rml.framework.core.model.{RMLMapping, Uri} +import io.rml.framework.core.model.{Graph, RMLMapping, Uri} import io.rml.framework.core.util.Turtle import io.rml.framework.shared.ReadException /** * Standard implementation of the MappingReader trait */ -class StdMappingReader(mappingExtractor: MappingExtractor) extends MappingReader { +class StdMappingReader[T<:Graph](mappingExtractor: MappingExtractor[T]) extends MappingReader[T] { /** * Reads a file and converts it to an RMLMapping. @@ -47,7 +47,7 @@ class StdMappingReader(mappingExtractor: MappingExtractor) extends MappingReader * @return */ @throws(classOf[ReadException]) - override def read(file: File): RMLMapping = { + override def read(file: File): T = { val graph: RDFGraph = RDFGraph.fromFile(file, RMLEnvironment.getMappingFileBaseIRI(), Turtle) mappingExtractor.extract(graph) } @@ -61,7 +61,7 @@ class StdMappingReader(mappingExtractor: MappingExtractor) extends MappingReader * @return */ @throws(classOf[ReadException]) - override def read(dump: String, graphUri: Uri): RMLMapping = { + override def read(dump: String, graphUri: Uri): T = { val graph: RDFGraph = RDFGraph(Some(graphUri)) graph.read(dump, RMLEnvironment.getMappingFileBaseIRI(), Turtle) mappingExtractor.extract(graph) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala new file mode 100644 index 00000000..3d4915ef --- /dev/null +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala @@ -0,0 +1,22 @@ +package io.rml.framework.core.extractors.std + +import io.rml.framework.core.extractors.MappingExtractor +import io.rml.framework.core.function.TransformationLoader +import io.rml.framework.core.model.TransformationMapping +import io.rml.framework.core.model.rdf.RDFGraph + +class StdTransformationMappingExtractor extends MappingExtractor[TransformationMapping] { + /** + * Extract. + * + * @param node Node to extract from. + * @return + */ + override def extract(node: RDFGraph): TransformationMapping = { + val loader = TransformationLoader() + + loader.parseTransformations(node) + + TransformationMapping("defaulty", loader) + } +} diff --git a/src/main/scala/io/rml/framework/core/model/TransformationMapping.scala b/src/main/scala/io/rml/framework/core/model/TransformationMapping.scala new file mode 100644 index 00000000..ec693b4b --- /dev/null +++ b/src/main/scala/io/rml/framework/core/model/TransformationMapping.scala @@ -0,0 +1,43 @@ +package io.rml.framework.core.model + +import io.rml.framework.core.function.TransformationLoader +import io.rml.framework.core.model.std.StdTransformationMapping + +trait TransformationMapping extends Graph { + + /** + * A transformation loader object which contains information + * in the mapping document to load function dynamically. + * + * Note: Functions are not loaded from the libraries + * at the moment of initialization of the [[TransformationLoader]]. + * It only has information on library path and classes containing + * the function. + * Functions will be loaded on demand when reading through the + * RML mapping file. + * + * @return + */ + def transformationLoader: TransformationLoader + + +} + +object TransformationMapping { + + //TODO: Temporary solution to passing the mapping object to function map extractors! + // Need refactoring! + private var mapping: Option[TransformationMapping] = None + + + def getOpt: Option[TransformationMapping] = { + mapping + } + + def apply(identifier: String, transformationLoader: TransformationLoader): TransformationMapping = { + val defMapping = StdTransformationMapping(identifier, transformationLoader) + mapping = Some(defMapping) + defMapping + + } +} diff --git a/src/main/scala/io/rml/framework/core/model/std/StdTransformationMapping.scala b/src/main/scala/io/rml/framework/core/model/std/StdTransformationMapping.scala new file mode 100644 index 00000000..0d1109cb --- /dev/null +++ b/src/main/scala/io/rml/framework/core/model/std/StdTransformationMapping.scala @@ -0,0 +1,7 @@ +package io.rml.framework.core.model.std + +import io.rml.framework.core.function.TransformationLoader +import io.rml.framework.core.model.TransformationMapping + +case class StdTransformationMapping(identifier: String, transformationLoader: TransformationLoader) extends TransformationMapping { +} diff --git a/src/main/scala/io/rml/framework/core/util/Util.scala b/src/main/scala/io/rml/framework/core/util/Util.scala index 780279fa..bc6fb5f0 100644 --- a/src/main/scala/io/rml/framework/core/util/Util.scala +++ b/src/main/scala/io/rml/framework/core/util/Util.scala @@ -31,7 +31,7 @@ import java.nio.file.{Files, Paths} import java.util.regex.Pattern import io.rml.framework.core.extractors.MappingReader -import io.rml.framework.core.model.{FormattedRMLMapping, Literal, Node} +import io.rml.framework.core.model.{FormattedRMLMapping, Literal, Node, RMLMapping} import io.rml.framework.shared.ReadException import scala.collection.mutable.ListBuffer @@ -190,7 +190,7 @@ object Util { */ def readMappingFile(path: String): FormattedRMLMapping = { val mappingFile = getFile(path) - val mapping = MappingReader().read(mappingFile) + val mapping = MappingReader().read(mappingFile).asInstanceOf[RMLMapping] FormattedRMLMapping.fromRMLMapping(mapping) } diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index 78bdd9b7..ab00cc7c 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -25,6 +25,7 @@ package io.rml.framework.engine.statement import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.function.model.Transformation import io.rml.framework.core.model._ import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item @@ -53,8 +54,9 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { private def parseFunction(assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): - FunctionMap = { + Transformation = { + this.logInfo("parseFunction (assembledPom)") val placeHolder: List[FlinkRDFQuad] = generateFunctionTriples(new EmptyItem(), assembledPom) val functionName = Uri(placeHolder .filter( quad => quad.predicate.value == Uri(RMLVoc.Property.EXECUTES)) @@ -63,15 +65,15 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { .value .toString) - throw new NotImplementedError() -// val transformationMapping = TransformationMapping -// .getOpt -// .getOrElse( throw new IllegalStateException("Transformation mapping hasn't been read/init yet")) -// -// transformationMapping -// .transformationLoader -// .loadTransformation(functionName) -// .getOrElse(throw new IllegalStateException(s"Function $functionName doesn't exist")) + //throw new NotImplementedError() + val transformationMapping = TransformationMapping + .getOpt + .getOrElse( throw new IllegalStateException("Transformation mapping hasn't been read/init yet")) + + transformationMapping + .transformationLoader + .loadTransformation(functionName) + .getOrElse(throw new IllegalStateException(s"Function $functionName doesn't exist")) } /** @@ -81,7 +83,7 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { * @param assembledPom List of predicate object generator functions * @return anon function taking in [[Item]] and returns entities using the function */ - private def createAssemblerFunction(function: FunctionMap, assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Item => Option[Iterable[Entity]] = { + private def createAssemblerFunction(function: Transformation, assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Item => Option[Iterable[Entity]] = { (item: Item) => { val triples: List[FlinkRDFQuad] = generateFunctionTriples(item, assembledPom) val args: Map[Uri, String] = triples.filter(triple => triple.predicate.uri != Uri(RMLVoc.Property.EXECUTES)) @@ -91,9 +93,9 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { parameterName -> parameterValue }) .toMap - throw new NotImplementedError() -// function.initialize() -// function.execute(args) + //throw new NotImplementedError() + function.initialize() + function.execute(args) } } diff --git a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala index a3f4d7ee..2a0413a4 100644 --- a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala @@ -25,7 +25,8 @@ package io.rml.framework.engine.statement -import io.rml.framework.core.model.{Entity, ObjectMap, Uri} +import io.rml.framework.core.function.TransformationUtils +import io.rml.framework.core.model.{Entity, Literal, ObjectMap, Uri} import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item @@ -44,9 +45,9 @@ class ObjectGeneratorAssembler extends TermMapGeneratorAssembler { termTypeString match { case RMLVoc.Class.IRI => item.map(iter => iter.map(elem => Uri(elem.toString))) case _ => item.map(iter => iter.flatMap(elem => { - throw new NotImplementedError() -// val castedResult = TransformationUtils.typeCastDataType(elem, objectMap.datatype) -// castedResult.map(v => Literal(v.toString, objectMap.datatype, objectMap.language)) + + val castedResult = TransformationUtils.typeCastDataType(elem, objectMap.datatype) + castedResult.map(v => Literal(v.toString, objectMap.datatype, objectMap.language)) })) } From 9ca7921f0d12b7ebf6c80f15e4626cdba2df7389 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 14:15:28 +0200 Subject: [PATCH 008/169] wip: function feature - updated tests --- src/test/scala/io/rml/framework/Test.scala | 4 ++-- .../rml/framework/util/fileprocessing/MappingTestUtil.scala | 4 ++-- .../util/fileprocessing/TripleGeneratorTestUtil.scala | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/scala/io/rml/framework/Test.scala b/src/test/scala/io/rml/framework/Test.scala index 64dafa8b..661da3af 100644 --- a/src/test/scala/io/rml/framework/Test.scala +++ b/src/test/scala/io/rml/framework/Test.scala @@ -27,7 +27,7 @@ package io.rml.framework import java.io.File import io.rml.framework.core.extractors.MappingReader -import io.rml.framework.core.model.FormattedRMLMapping +import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping} import io.rml.framework.engine.NopPostProcessor import io.rml.framework.util.logging.Logger import org.apache.flink.api.scala.ExecutionEnvironment @@ -42,7 +42,7 @@ object Test extends App { val file = new File(classLoader.getResource("rml-testcases/RMLTC0007d-CSV/mapping.ttl").getFile) val mapping = MappingReader().read(file) - val formattedMapping = FormattedRMLMapping.fromRMLMapping(mapping) + val formattedMapping = FormattedRMLMapping.fromRMLMapping(mapping.asInstanceOf[RMLMapping]) Logger.logInfo("" + formattedMapping.standardStaticTriplesMaps.size) val result = Main.createDataSetFromFormattedMapping(formattedMapping).collect().reduce((a, b) => a + "\n" + b) System.out.println(result) diff --git a/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala b/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala index ae8efd03..5accc5cf 100644 --- a/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala +++ b/src/test/scala/io/rml/framework/util/fileprocessing/MappingTestUtil.scala @@ -27,7 +27,7 @@ package io.rml.framework.util.fileprocessing import java.io.File import io.rml.framework.core.extractors.MappingReader -import io.rml.framework.core.model.FormattedRMLMapping +import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping} /** * Test helper to read the mapping file and generate a FormattedRMLMapping @@ -38,7 +38,7 @@ object MappingTestUtil extends FileProcessingUtil[FormattedRMLMapping] { override def processFile(file: File): FormattedRMLMapping = { val mapping = MappingReader().read(file) - FormattedRMLMapping.fromRMLMapping(mapping) + FormattedRMLMapping.fromRMLMapping(mapping.asInstanceOf[RMLMapping]) } override def candidateFiles: List[String] = List("mapping.ttl", "mapping.rml.ttl", "example.rml.ttl") diff --git a/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala b/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala index 501fee73..05104c51 100644 --- a/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala +++ b/src/test/scala/io/rml/framework/util/fileprocessing/TripleGeneratorTestUtil.scala @@ -28,7 +28,7 @@ import java.io.File import io.rml.framework.Main import io.rml.framework.core.extractors.MappingReader -import io.rml.framework.core.model.FormattedRMLMapping +import io.rml.framework.core.model.{FormattedRMLMapping, RMLMapping} import io.rml.framework.core.util.{Format, NQuads} import io.rml.framework.engine.{NopPostProcessor, PostProcessor} import io.rml.framework.util.logging.Logger @@ -68,7 +68,7 @@ object TripleGeneratorTestUtil extends TestFilesUtil[(List[String], Format)] { try { val mapping = MappingReader().read(file) - val formattedMapping = FormattedRMLMapping.fromRMLMapping(mapping) + val formattedMapping = FormattedRMLMapping.fromRMLMapping(mapping.asInstanceOf[RMLMapping]) val dataSet = Main.createDataSetFromFormattedMapping(formattedMapping).collect // we assume quads, since we don't use a post processor From 795c51370532097e36f4d6dde766aa2e14a861db Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 14:16:16 +0200 Subject: [PATCH 009/169] wip: function feature - added sandbox tests sandbox tests are for experimental purposes --- .../RMLFNOTC0001-CSV/mapping_explicit.ttl | 40 +++++++++++++++++++ .../scala/io/rml/framework/SandboxTests.scala | 33 ++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl new file mode 100644 index 00000000..78900620 --- /dev/null +++ b/src/test/resources/sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl @@ -0,0 +1,40 @@ +# Function on object, 1 reference parameter + +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{Name}" + ]; + + rr:predicateObjectMap [ + rr:predicate foaf:name; + rr:objectMap [ + a fnml:FunctionTermMap ; + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toUpperCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "Name" ] ] + ] + ] + ]. diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 297ddf83..e4259c76 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -28,15 +28,23 @@ import java.io.File import io.rml.framework.Main import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.extractors.{MappingExtractor, MappingReader} +import io.rml.framework.core.function.TransformationLoader +import io.rml.framework.core.model.TransformationMapping import io.rml.framework.core.util.Util import io.rml.framework.engine.NopPostProcessor import io.rml.framework.util.TestUtil + import io.rml.framework.util.logging.Logger import org.apache.flink.api.scala.ExecutionEnvironment import org.apache.flink.streaming.api.scala._ import org.scalatest.{FunSuite, Matchers} +import io.rml.framework.util.logging.Logger + +class SandboxTests extends FunSuite with Matchers { + + val functionFile = new File(getClass.getClassLoader.getResource("functions.ttl").getFile) -class SandboxTests extends FunSuite with Matchers { private def executeTest(mappingFile: String): Unit = { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.org/base/")) @@ -47,6 +55,10 @@ class SandboxTests extends FunSuite with Matchers { val testDir = Util.getFile(new File(mappingFile).getParent) val mappingFileAbs = new File(testDir, new File(mappingFile).getName) + // load functions [depr: transormations] + TransformationLoader().parseTransformations(functionFile) + + MappingReader(MappingExtractor(TransformationMapping)).read(functionFile) // read the mapping val formattedMapping = Util.readMappingFile(mappingFileAbs.getAbsolutePath) @@ -76,6 +88,16 @@ class SandboxTests extends FunSuite with Matchers { // mapping.ttl vs. mapping_explicit.ttl // + test("log with colors"){ + Logger.logInfo("this is info") + Logger.logDebug("this is debug") // must be turned on + Logger.logSuccess("this is success") + Logger.logError("this is error") + Logger.logWarning("this is warning") + Logger.lineBreak() + } + + test("sandbox/fno-testcases/RMLFNOTC0000-CSV") { executeTest("sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl") } @@ -84,5 +106,14 @@ class SandboxTests extends FunSuite with Matchers { executeTest("sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl") } + test("sandbox/fno-testcases/RMLFNOTC0001-CSV") { + executeTest("sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl") + } + + test("sandbox/fno-testcases/RMLFNOTC0001-CSV-explicit") { + executeTest("sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl") + } + + } From 936a267e9ada97cff92a8f7a7e872fe55c0de233 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 14:20:28 +0200 Subject: [PATCH 010/169] removed redundant line --- src/test/scala/io/rml/framework/SandboxTests.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index e4259c76..3622784b 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -55,9 +55,7 @@ class SandboxTests extends FunSuite with Matchers { val testDir = Util.getFile(new File(mappingFile).getParent) val mappingFileAbs = new File(testDir, new File(mappingFile).getName) - // load functions [depr: transormations] - TransformationLoader().parseTransformations(functionFile) - + // load functions MappingReader(MappingExtractor(TransformationMapping)).read(functionFile) // read the mapping val formattedMapping = Util.readMappingFile(mappingFileAbs.getAbsolutePath) From 6005fbfa87eb020d6c980754f018128aa243793a Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 16:46:49 +0200 Subject: [PATCH 011/169] wip: function feature - moving failing FNO tests to /failing Tests - transferred fno-testcases from function_map_gdm - filtered out failing test cases by trying to generate outputs fno mapping files using the RML Mapper, and moved them to the failing directory - filtered out test cases that didn't pass the OutputGenerationTests Following mapping files fail using the RML Mapper when generating output fno-testcases/RMLFNOTC0005-CSV/mapping.ttl fno-testcases/RMLFNOTC0004-CSV/mapping.ttl fno-testcases/RMLFNOTC0006-CSV/mapping.ttl fno-testcases/RMLFNOTC0012-CSV/mapping.ttl fno-testcases/RMLFNOTC0007-CSV/mapping.ttl Following mapping files fail using the RML Streamer running OutputGenerationTests fno-testcases/RMLFNOTC0011-CSV/mapping.ttl fno-testcases/RMLFNOTC0014-CSV/mapping.ttl fno-testcases/RMLFNOTC0015-CSV/mapping.ttl fno-testcases/RMLFNOTC0016-CSV/mapping.ttl --- .../RMLFNOTC0000-CSV/mapping.ttl | 0 .../RMLFNOTC0000-CSV/output.ttl | 0 .../RMLFNOTC0004-CSV/mapping.ttl | 0 .../RMLFNOTC0004-CSV/output.ttl | 0 .../RMLFNOTC0004-CSV/output.ttl.bak} | 0 .../RMLFNOTC0005-CSV/mapping.ttl | 0 .../RMLFNOTC0005-CSV/output.ttl | 0 .../failing/RMLFNOTC0005-CSV/output.ttl.bak | 1 + .../RMLFNOTC0005-CSV/student.csv | 0 .../RMLFNOTC0006-CSV/mapping.ttl | 0 .../RMLFNOTC0006-CSV/output.nq | 0 .../RMLFNOTC0007-CSV/mapping.ttl | 0 .../RMLFNOTC0007-CSV/output.ttl | 0 .../RMLFNOTC0007-CSV/output.ttl.bak} | 0 .../RMLFNOTC0011-CSV/mapping.ttl | 0 .../resources/failing/RMLFNOTC0011-CSV/output.ttl | 1 + .../failing/RMLFNOTC0011-CSV/output.ttl.bak | 1 + .../RMLFNOTC0012-CSV/mapping.ttl | 0 .../RMLFNOTC0012-CSV/output.ttl | 0 .../failing/RMLFNOTC0012-CSV/output.ttl.bak | 0 .../RMLFNOTC0014-CSV/mapping.ttl | 0 .../resources/failing/RMLFNOTC0014-CSV/output.ttl | 1 + .../RMLFNOTC0014-CSV/output.ttl.bak} | 0 .../RMLFNOTC0015-CSV/mapping.ttl | 0 .../resources/failing/RMLFNOTC0015-CSV/output.ttl | 1 + .../failing/RMLFNOTC0015-CSV/output.ttl.bak | 1 + .../RMLFNOTC0016-CSV/mapping.ttl | 0 .../RMLFNOTC0016-CSV/output.nq | 0 .../resources/failing/RMLFNOTC0016-CSV/output.ttl | 1 + .../fno-testcases/RMLFNOTC0001-CSV/output.ttl | 2 +- .../fno-testcases/RMLFNOTC0001-CSV/output.ttl.bak | 1 + .../fno-testcases/RMLFNOTC0002-CSV/output.ttl | 2 +- .../RMLFNOTC0002-CSV/output.ttl.bak} | 0 .../fno-testcases/RMLFNOTC0003-CSV/output.ttl | 2 +- .../RMLFNOTC0003-CSV/output.ttl.bak} | 0 .../fno-testcases/RMLFNOTC0008-CSV/output.ttl | 2 +- .../fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak | 1 + .../fno-testcases/RMLFNOTC0013-CSV/output.ttl | 2 +- .../fno-testcases/RMLFNOTC0013-CSV/output.ttl.bak | 1 + .../fno-testcases/RMLFNOTC0018-CSV/output.ttl | 2 +- .../fno-testcases/RMLFNOTC0018-CSV/output.ttl.bak | 1 + .../fno-testcases/RMLFNOTC0021-JSON/output.ttl | 14 +++++++------- .../fno-testcases/RMLFNOTC0021-JSON/output.ttl.bak | 7 +++++++ .../io/rml/framework/OutputGenerationTest.scala | 9 +++++++++ 44 files changed, 40 insertions(+), 13 deletions(-) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0000-CSV/mapping.ttl (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0000-CSV/output.ttl (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0004-CSV/mapping.ttl (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0004-CSV/output.ttl (100%) rename src/test/resources/{fno-testcases/RMLFNOTC0015-CSV/output.ttl => failing/RMLFNOTC0004-CSV/output.ttl.bak} (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0005-CSV/mapping.ttl (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0005-CSV/output.ttl (100%) create mode 100644 src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl.bak rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0005-CSV/student.csv (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0006-CSV/mapping.ttl (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0006-CSV/output.nq (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0007-CSV/mapping.ttl (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0007-CSV/output.ttl (100%) rename src/test/resources/{fno-testcases/RMLFNOTC0011-CSV/output.ttl => failing/RMLFNOTC0007-CSV/output.ttl.bak} (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0011-CSV/mapping.ttl (100%) create mode 100644 src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl create mode 100644 src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl.bak rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0012-CSV/mapping.ttl (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0012-CSV/output.ttl (100%) create mode 100644 src/test/resources/failing/RMLFNOTC0012-CSV/output.ttl.bak rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0014-CSV/mapping.ttl (100%) create mode 100644 src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl rename src/test/resources/{fno-testcases/RMLFNOTC0014-CSV/output.ttl => failing/RMLFNOTC0014-CSV/output.ttl.bak} (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0015-CSV/mapping.ttl (100%) create mode 100644 src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl create mode 100644 src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl.bak rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0016-CSV/mapping.ttl (100%) rename src/test/resources/{fno-testcases => failing}/RMLFNOTC0016-CSV/output.nq (100%) create mode 100644 src/test/resources/failing/RMLFNOTC0016-CSV/output.ttl create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl.bak rename src/test/resources/{sandbox/fno-testcases/RMLFNOTC0002-CSV/output.ttl => fno-testcases/RMLFNOTC0002-CSV/output.ttl.bak} (100%) rename src/test/resources/{sandbox/fno-testcases/RMLFNOTC0003-CSV/output.ttl => fno-testcases/RMLFNOTC0003-CSV/output.ttl.bak} (100%) create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl.bak create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl.bak create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl.bak diff --git a/src/test/resources/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0000-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0000-CSV/mapping.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0000-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0000-CSV/output.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0000-CSV/output.ttl rename to src/test/resources/failing/RMLFNOTC0000-CSV/output.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0004-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0004-CSV/mapping.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0004-CSV/output.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl rename to src/test/resources/failing/RMLFNOTC0004-CSV/output.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0015-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0004-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0015-CSV/output.ttl rename to src/test/resources/failing/RMLFNOTC0004-CSV/output.ttl.bak diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0005-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0005-CSV/mapping.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl rename to src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl.bak b/src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl.bak new file mode 100644 index 00000000..80493637 --- /dev/null +++ b/src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl.bak @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv b/src/test/resources/failing/RMLFNOTC0005-CSV/student.csv similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0005-CSV/student.csv rename to src/test/resources/failing/RMLFNOTC0005-CSV/student.csv diff --git a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0006-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0006-CSV/mapping.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq b/src/test/resources/failing/RMLFNOTC0006-CSV/output.nq similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq rename to src/test/resources/failing/RMLFNOTC0006-CSV/output.nq diff --git a/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0007-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0007-CSV/mapping.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0007-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0007-CSV/output.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0007-CSV/output.ttl rename to src/test/resources/failing/RMLFNOTC0007-CSV/output.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0007-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl rename to src/test/resources/failing/RMLFNOTC0007-CSV/output.ttl.bak diff --git a/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0011-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0011-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl new file mode 100644 index 00000000..a5026672 --- /dev/null +++ b/src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl @@ -0,0 +1 @@ + "VENUS"^^. diff --git a/src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl.bak b/src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl.bak new file mode 100644 index 00000000..a5026672 --- /dev/null +++ b/src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl.bak @@ -0,0 +1 @@ + "VENUS"^^. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0012-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0012-CSV/mapping.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0012-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0012-CSV/output.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0012-CSV/output.ttl rename to src/test/resources/failing/RMLFNOTC0012-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0012-CSV/output.ttl.bak b/src/test/resources/failing/RMLFNOTC0012-CSV/output.ttl.bak new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0014-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0014-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl new file mode 100644 index 00000000..33a517b5 --- /dev/null +++ b/src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl @@ -0,0 +1 @@ + "Venus". diff --git a/src/test/resources/fno-testcases/RMLFNOTC0014-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0014-CSV/output.ttl rename to src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl.bak diff --git a/src/test/resources/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0015-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0015-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl new file mode 100644 index 00000000..45cf0634 --- /dev/null +++ b/src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl @@ -0,0 +1 @@ + . diff --git a/src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl.bak b/src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl.bak new file mode 100644 index 00000000..4aa4759e --- /dev/null +++ b/src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl.bak @@ -0,0 +1 @@ + . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl b/src/test/resources/failing/RMLFNOTC0016-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl rename to src/test/resources/failing/RMLFNOTC0016-CSV/mapping.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0016-CSV/output.nq b/src/test/resources/failing/RMLFNOTC0016-CSV/output.nq similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0016-CSV/output.nq rename to src/test/resources/failing/RMLFNOTC0016-CSV/output.nq diff --git a/src/test/resources/failing/RMLFNOTC0016-CSV/output.ttl b/src/test/resources/failing/RMLFNOTC0016-CSV/output.ttl new file mode 100644 index 00000000..56126792 --- /dev/null +++ b/src/test/resources/failing/RMLFNOTC0016-CSV/output.ttl @@ -0,0 +1 @@ + "Venus" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl index b0369690..57872f74 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl @@ -1 +1 @@ - "VENUS" . + "VENUS". diff --git a/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl.bak new file mode 100644 index 00000000..b0369690 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0001-CSV/output.ttl.bak @@ -0,0 +1 @@ + "VENUS" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl index fb8edf94..6b504619 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl @@ -1 +1 @@ - "NAME" . + "NAME". diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/sandbox/fno-testcases/RMLFNOTC0002-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0002-CSV/output.ttl.bak diff --git a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl index af03220c..7f158a88 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl @@ -1 +1 @@ - "A&B" . + "A&B". diff --git a/src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/sandbox/fno-testcases/RMLFNOTC0003-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0003-CSV/output.ttl.bak diff --git a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl index 9020be0f..5b69f570 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl @@ -1 +1 @@ - "NAME: VENUS" . + "NAME: VENUS". diff --git a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak new file mode 100644 index 00000000..9020be0f --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak @@ -0,0 +1 @@ + "NAME: VENUS" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl index 6629e021..9578e600 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl @@ -1 +1 @@ - "" . + "". diff --git a/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl.bak new file mode 100644 index 00000000..6629e021 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0013-CSV/output.ttl.bak @@ -0,0 +1 @@ + "" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl index 2296c1ec..556a47d4 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl @@ -1 +1 @@ - "BEN & PIETER" . + "BEN & PIETER". diff --git a/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl.bak new file mode 100644 index 00000000..2296c1ec --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0018-CSV/output.ttl.bak @@ -0,0 +1 @@ + "BEN & PIETER" . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl index 445fac6f..f90ed809 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl @@ -1,7 +1,7 @@ - . - "John" . - . - "Edward" . - "Steve" . - . - . + . + "John". + . + "Edward". + "Steve". + . + . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl.bak new file mode 100644 index 00000000..445fac6f --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl.bak @@ -0,0 +1,7 @@ + . + "John" . + . + "Edward" . + "Steve" . + . + . diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index eeeff367..d4d90686 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -24,7 +24,11 @@ **/ package io.rml.framework +import java.io.File + import io.rml.framework.api.RMLEnvironment +import io.rml.framework.core.extractors.{MappingExtractor, MappingReader} +import io.rml.framework.core.model.TransformationMapping import io.rml.framework.engine.PostProcessor import io.rml.framework.util.TestUtil import io.rml.framework.util.fileprocessing.{ExpectedOutputTestUtil, TripleGeneratorTestUtil} @@ -35,6 +39,7 @@ import scala.util.control.Exception class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { + val functionFile = new File(getClass.getClassLoader.getResource("functions.ttl").getFile) // dev note: // Explicit type annotation allows to completely comment out the elements of the failing, passing or temp arrays // without causing compilation failures. @@ -53,12 +58,16 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { ) + "Valid mapping file" should behave like validMappingFile("rml-testcases") "Valid mapping output generation" should "match the output from output.ttl" in { + // load functions + MappingReader(MappingExtractor(TransformationMapping)).read(functionFile) passing.foreach(test => { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.com/base/")) + implicit val postProcessor: PostProcessor= TestUtil.pickPostProcessor(test._2) ExpectedOutputTestUtil.test(test._1, checkGeneratedOutput) }) From fe8defa5c9714763d4e942b5b5ce0384fdc13ae2 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 16:47:51 +0200 Subject: [PATCH 012/169] wip: function feature - added sandbox tests --- .../scala/io/rml/framework/SandboxTests.scala | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 3622784b..5a31f13f 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -113,5 +113,38 @@ class SandboxTests extends FunSuite with Matchers { } + /** + * [STATE @ do 28 mei 2020 14:48:03 CEST] FAILING + * log. source: students.csv + * used function: grel:toUpperCaseURL + * value parameter: reference to "Name" + */ + test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { + executeTest("sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl") + } + + + /** + * [STATE @ do 28 mei 2020 14:48:03 CEST] WORKING + * log. source: students.csv + * used function: grel:toUpperCase + * value parameter: template using {Name} + */ + test("sandbox/fno-testcases/RMLFNOTC0008-CSV") { + executeTest("sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl") + } + + + /** + * [STATE @ ] + * log. source: students.csv + * used function: grel:toUpperCase + * value parameter: reference to "Name" + */ + test("sandbox/fno-testcases/RMLFNOTC0011-CSV") { + executeTest("sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl") + } + + } From f1b886f40136252d63aa576b56e2b30344704e0b Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 28 May 2020 17:15:15 +0200 Subject: [PATCH 013/169] wip: function feature - Output Generation Tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ran Output Generation Tests on both rml-testcases and fno-testcases. Failing using RML Streamer [RML-TESTCASES] - rml-testcases/RMLTC0011b-JSON →moved to failing - rml-testcases/RMLTC0011b-XML → moved to failing After moving the above test cases to /failing, the output generation tests were successful. However, the reason for them failing still requires introspection. --- .../resources/{rml-testcases => }/RMLTC0011b-CSV/mapping.ttl | 0 .../{rml-testcases => }/RMLTC0011b-CSV/mapping.ttl.bak | 0 .../resources/{rml-testcases => }/RMLTC0011b-CSV/output.ttl | 0 src/test/resources/{rml-testcases => }/RMLTC0011b-CSV/sport.csv | 0 .../resources/{rml-testcases => }/RMLTC0011b-CSV/student.csv | 0 .../{rml-testcases => }/RMLTC0011b-CSV/student_sport.csv | 0 .../{rml-testcases => failing}/RMLTC0011b-JSON/mapping.ttl | 0 .../{rml-testcases => failing}/RMLTC0011b-JSON/mapping.ttl.bak | 0 .../{rml-testcases => failing}/RMLTC0011b-JSON/output.ttl | 0 .../{rml-testcases => failing}/RMLTC0011b-JSON/sport.json | 0 .../{rml-testcases => failing}/RMLTC0011b-JSON/student.json | 0 .../RMLTC0011b-JSON/student_sport.json | 0 .../{rml-testcases => failing}/RMLTC0011b-XML/mapping.ttl | 0 .../{rml-testcases => failing}/RMLTC0011b-XML/mapping.ttl.bak | 0 .../{rml-testcases => failing}/RMLTC0011b-XML/output.ttl | 0 .../{rml-testcases => failing}/RMLTC0011b-XML/sport.xml | 0 .../{rml-testcases => failing}/RMLTC0011b-XML/student.xml | 0 .../{rml-testcases => failing}/RMLTC0011b-XML/student_sport.xml | 0 src/test/scala/io/rml/framework/OutputGenerationTest.scala | 2 +- 19 files changed, 1 insertion(+), 1 deletion(-) rename src/test/resources/{rml-testcases => }/RMLTC0011b-CSV/mapping.ttl (100%) rename src/test/resources/{rml-testcases => }/RMLTC0011b-CSV/mapping.ttl.bak (100%) rename src/test/resources/{rml-testcases => }/RMLTC0011b-CSV/output.ttl (100%) rename src/test/resources/{rml-testcases => }/RMLTC0011b-CSV/sport.csv (100%) rename src/test/resources/{rml-testcases => }/RMLTC0011b-CSV/student.csv (100%) rename src/test/resources/{rml-testcases => }/RMLTC0011b-CSV/student_sport.csv (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-JSON/mapping.ttl (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-JSON/mapping.ttl.bak (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-JSON/output.ttl (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-JSON/sport.json (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-JSON/student.json (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-JSON/student_sport.json (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-XML/mapping.ttl (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-XML/mapping.ttl.bak (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-XML/output.ttl (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-XML/sport.xml (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-XML/student.xml (100%) rename src/test/resources/{rml-testcases => failing}/RMLTC0011b-XML/student_sport.xml (100%) diff --git a/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl b/src/test/resources/RMLTC0011b-CSV/mapping.ttl similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl rename to src/test/resources/RMLTC0011b-CSV/mapping.ttl diff --git a/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak b/src/test/resources/RMLTC0011b-CSV/mapping.ttl.bak similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak rename to src/test/resources/RMLTC0011b-CSV/mapping.ttl.bak diff --git a/src/test/resources/rml-testcases/RMLTC0011b-CSV/output.ttl b/src/test/resources/RMLTC0011b-CSV/output.ttl similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-CSV/output.ttl rename to src/test/resources/RMLTC0011b-CSV/output.ttl diff --git a/src/test/resources/rml-testcases/RMLTC0011b-CSV/sport.csv b/src/test/resources/RMLTC0011b-CSV/sport.csv similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-CSV/sport.csv rename to src/test/resources/RMLTC0011b-CSV/sport.csv diff --git a/src/test/resources/rml-testcases/RMLTC0011b-CSV/student.csv b/src/test/resources/RMLTC0011b-CSV/student.csv similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-CSV/student.csv rename to src/test/resources/RMLTC0011b-CSV/student.csv diff --git a/src/test/resources/rml-testcases/RMLTC0011b-CSV/student_sport.csv b/src/test/resources/RMLTC0011b-CSV/student_sport.csv similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-CSV/student_sport.csv rename to src/test/resources/RMLTC0011b-CSV/student_sport.csv diff --git a/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl b/src/test/resources/failing/RMLTC0011b-JSON/mapping.ttl similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl rename to src/test/resources/failing/RMLTC0011b-JSON/mapping.ttl diff --git a/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak b/src/test/resources/failing/RMLTC0011b-JSON/mapping.ttl.bak similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak rename to src/test/resources/failing/RMLTC0011b-JSON/mapping.ttl.bak diff --git a/src/test/resources/rml-testcases/RMLTC0011b-JSON/output.ttl b/src/test/resources/failing/RMLTC0011b-JSON/output.ttl similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-JSON/output.ttl rename to src/test/resources/failing/RMLTC0011b-JSON/output.ttl diff --git a/src/test/resources/rml-testcases/RMLTC0011b-JSON/sport.json b/src/test/resources/failing/RMLTC0011b-JSON/sport.json similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-JSON/sport.json rename to src/test/resources/failing/RMLTC0011b-JSON/sport.json diff --git a/src/test/resources/rml-testcases/RMLTC0011b-JSON/student.json b/src/test/resources/failing/RMLTC0011b-JSON/student.json similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-JSON/student.json rename to src/test/resources/failing/RMLTC0011b-JSON/student.json diff --git a/src/test/resources/rml-testcases/RMLTC0011b-JSON/student_sport.json b/src/test/resources/failing/RMLTC0011b-JSON/student_sport.json similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-JSON/student_sport.json rename to src/test/resources/failing/RMLTC0011b-JSON/student_sport.json diff --git a/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl b/src/test/resources/failing/RMLTC0011b-XML/mapping.ttl similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl rename to src/test/resources/failing/RMLTC0011b-XML/mapping.ttl diff --git a/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak b/src/test/resources/failing/RMLTC0011b-XML/mapping.ttl.bak similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak rename to src/test/resources/failing/RMLTC0011b-XML/mapping.ttl.bak diff --git a/src/test/resources/rml-testcases/RMLTC0011b-XML/output.ttl b/src/test/resources/failing/RMLTC0011b-XML/output.ttl similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-XML/output.ttl rename to src/test/resources/failing/RMLTC0011b-XML/output.ttl diff --git a/src/test/resources/rml-testcases/RMLTC0011b-XML/sport.xml b/src/test/resources/failing/RMLTC0011b-XML/sport.xml similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-XML/sport.xml rename to src/test/resources/failing/RMLTC0011b-XML/sport.xml diff --git a/src/test/resources/rml-testcases/RMLTC0011b-XML/student.xml b/src/test/resources/failing/RMLTC0011b-XML/student.xml similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-XML/student.xml rename to src/test/resources/failing/RMLTC0011b-XML/student.xml diff --git a/src/test/resources/rml-testcases/RMLTC0011b-XML/student_sport.xml b/src/test/resources/failing/RMLTC0011b-XML/student_sport.xml similarity index 100% rename from src/test/resources/rml-testcases/RMLTC0011b-XML/student_sport.xml rename to src/test/resources/failing/RMLTC0011b-XML/student_sport.xml diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index d4d90686..8ab84d3d 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -50,7 +50,7 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { ) val passing : Array[Tuple2[String,String]] =Array( // ("bugs","noopt"), - //("rml-testcases","noopt"), + ("rml-testcases","noopt"), ("fno-testcases", "noopt") ) val temp : Array[Tuple2[String,String]] = Array( From 7c812703c39623451deaf07f32540fac63b76e23 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 29 May 2020 09:38:36 +0200 Subject: [PATCH 014/169] wip: feature function - clean up + changed test to pending --- .../scala/io/rml/framework/SandboxTests.scala | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 5a31f13f..52bcbc15 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -81,28 +81,6 @@ class SandboxTests extends FunSuite with Matchers { } - // - // sandbox/fno-testcases/RMLFNOTC0000-CSV - // mapping.ttl vs. mapping_explicit.ttl - // - - test("log with colors"){ - Logger.logInfo("this is info") - Logger.logDebug("this is debug") // must be turned on - Logger.logSuccess("this is success") - Logger.logError("this is error") - Logger.logWarning("this is warning") - Logger.lineBreak() - } - - - test("sandbox/fno-testcases/RMLFNOTC0000-CSV") { - executeTest("sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl") - } - - test("sandbox/fno-testcases/RMLFNOTC0000-CSV-explicit") { - executeTest("sandbox/fno-testcases/RMLFNOTC0000-CSV/mapping_explicit.ttl") - } test("sandbox/fno-testcases/RMLFNOTC0001-CSV") { executeTest("sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl") @@ -120,6 +98,7 @@ class SandboxTests extends FunSuite with Matchers { * value parameter: reference to "Name" */ test("sandbox/fno-testcases/RMLFNOTC0004-CSV") { + pending executeTest("sandbox/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl") } @@ -142,7 +121,8 @@ class SandboxTests extends FunSuite with Matchers { * value parameter: reference to "Name" */ test("sandbox/fno-testcases/RMLFNOTC0011-CSV") { - executeTest("sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl") + pending + //executeTest("sandbox/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl") } From 83d6bfa367dfcef0eb9fe2382af96d4ce6ef4d9e Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 29 May 2020 13:30:01 +0200 Subject: [PATCH 015/169] wip: feature function - set example 10 test to pending The RML Mapper throws the following error when reading this mapping file: ERROR be.ugent.rml.cli.Main .main(315) - Expected ':', found '/' [line 1] --- .../scala/io/rml/framework/engine/StatementEngineTest.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/scala/io/rml/framework/engine/StatementEngineTest.scala b/src/test/scala/io/rml/framework/engine/StatementEngineTest.scala index 91ac40b6..6aa89c4c 100644 --- a/src/test/scala/io/rml/framework/engine/StatementEngineTest.scala +++ b/src/test/scala/io/rml/framework/engine/StatementEngineTest.scala @@ -70,7 +70,12 @@ class StatementEngineTest extends FunSuite with Matchers { } + /** [STATE @ vr 29 mei 2020 13:24:55 CEST] FAILING + * java -jar ~/Github/RML/rmlmapper.jar -m example10/mapping.ttl  ✔  10090  13:24:14 + * 13:24:26.959 [main] ERROR be.ugent.rml.cli.Main .main(315) - Expected ':', found '/' [line 1] + */ test("example10") { + pending executeTest("example10/mapping.rml.ttl") } From 994321cfa1cd0305451d8e5d950588e52b04b6ea Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 29 May 2020 13:52:58 +0200 Subject: [PATCH 016/169] wip: function feature - added separate directories for rml and fno MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit e.g; failing ├── fno-testcases │   ├── RMLFNOTC0000-CSV │   ├── RMLFNOTC0004-CSV │   ├── RMLFNOTC0005-CSV │   ├── RMLFNOTC0006-CSV │   ├── RMLFNOTC0007-CSV │   ├── RMLFNOTC0011-CSV │   ├── RMLFNOTC0012-CSV │   ├── RMLFNOTC0014-CSV │   ├── RMLFNOTC0015-CSV │   ├── RMLFNOTC0016-CSV │   ├── RMLFNOTCA001 │   └── student.csv ├── remote_source │   └── RMLTC1003-CSV └── rml-testcases ├── RMLTC0009b-CSV ├── RMLTC0009b-JSON ├── RMLTC0009b-XML ├── RMLTC0010c-CSV ├── RMLTC0010c-JSON ├── RMLTC0010c-XML ├── RMLTC0011b-JSON ├── RMLTC0011b-XML └── RMLTC1003-CSV --- .../failing/{ => fno-testcases}/RMLFNOTC0000-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0000-CSV/output.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0004-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0004-CSV/output.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0004-CSV/output.ttl.bak | 0 .../failing/{ => fno-testcases}/RMLFNOTC0005-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0005-CSV/output.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0005-CSV/output.ttl.bak | 0 .../failing/{ => fno-testcases}/RMLFNOTC0005-CSV/student.csv | 0 .../failing/{ => fno-testcases}/RMLFNOTC0006-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0006-CSV/output.nq | 0 .../failing/{ => fno-testcases}/RMLFNOTC0007-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0007-CSV/output.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0007-CSV/output.ttl.bak | 0 .../failing/{ => fno-testcases}/RMLFNOTC0011-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0011-CSV/output.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0011-CSV/output.ttl.bak | 0 .../failing/{ => fno-testcases}/RMLFNOTC0012-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0012-CSV/output.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0012-CSV/output.ttl.bak | 0 .../failing/{ => fno-testcases}/RMLFNOTC0014-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0014-CSV/output.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0014-CSV/output.ttl.bak | 0 .../failing/{ => fno-testcases}/RMLFNOTC0015-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0015-CSV/output.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0015-CSV/output.ttl.bak | 0 .../failing/{ => fno-testcases}/RMLFNOTC0016-CSV/mapping.ttl | 0 .../failing/{ => fno-testcases}/RMLFNOTC0016-CSV/output.nq | 0 .../failing/{ => fno-testcases}/RMLFNOTC0016-CSV/output.ttl | 0 src/test/resources/failing/fno-testcases/student.csv | 2 ++ .../failing/{ => rml-testcases}/RMLTC0009b-CSV/mapping.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0009b-CSV/output.nq | 0 .../failing/{ => rml-testcases}/RMLTC0009b-CSV/sport.csv | 0 .../failing/{ => rml-testcases}/RMLTC0009b-CSV/student.csv | 0 .../failing/{ => rml-testcases}/RMLTC0009b-JSON/mapping.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0009b-JSON/output.nq | 0 .../failing/{ => rml-testcases}/RMLTC0009b-JSON/sport.json | 0 .../failing/{ => rml-testcases}/RMLTC0009b-JSON/student.json | 0 .../failing/{ => rml-testcases}/RMLTC0009b-XML/mapping.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0009b-XML/output.nq | 0 .../failing/{ => rml-testcases}/RMLTC0009b-XML/sport.xml | 0 .../failing/{ => rml-testcases}/RMLTC0009b-XML/student.xml | 0 .../failing/{ => rml-testcases}/RMLTC0010c-CSV/country info.csv | 0 .../failing/{ => rml-testcases}/RMLTC0010c-CSV/mapping.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0010c-CSV/mapping.ttl.bak | 0 .../failing/{ => rml-testcases}/RMLTC0010c-CSV/output.ttl | 0 .../{ => rml-testcases}/RMLTC0010c-JSON/country info.json | 0 .../failing/{ => rml-testcases}/RMLTC0010c-JSON/mapping.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0010c-JSON/mapping.ttl.bak | 0 .../failing/{ => rml-testcases}/RMLTC0010c-JSON/output.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0010c-XML/country info.xml | 0 .../failing/{ => rml-testcases}/RMLTC0010c-XML/mapping.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0010c-XML/mapping.ttl.bak | 0 .../failing/{ => rml-testcases}/RMLTC0010c-XML/output.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0011b-JSON/mapping.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0011b-JSON/mapping.ttl.bak | 0 .../failing/{ => rml-testcases}/RMLTC0011b-JSON/output.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0011b-JSON/sport.json | 0 .../failing/{ => rml-testcases}/RMLTC0011b-JSON/student.json | 0 .../{ => rml-testcases}/RMLTC0011b-JSON/student_sport.json | 0 .../failing/{ => rml-testcases}/RMLTC0011b-XML/mapping.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0011b-XML/mapping.ttl.bak | 0 .../failing/{ => rml-testcases}/RMLTC0011b-XML/output.ttl | 0 .../failing/{ => rml-testcases}/RMLTC0011b-XML/sport.xml | 0 .../failing/{ => rml-testcases}/RMLTC0011b-XML/student.xml | 0 .../{ => rml-testcases}/RMLTC0011b-XML/student_sport.xml | 0 .../failing/{ => rml-testcases}/RMLTC1003-CSV/mapping.ttl | 0 .../failing/{ => rml-testcases}/RMLTC1003-CSV/mapping.ttl.bak | 0 .../failing/{ => rml-testcases}/RMLTC1003-CSV/output.ttl | 0 69 files changed, 2 insertions(+) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0000-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0000-CSV/output.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0004-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0004-CSV/output.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0004-CSV/output.ttl.bak (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0005-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0005-CSV/output.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0005-CSV/output.ttl.bak (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0005-CSV/student.csv (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0006-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0006-CSV/output.nq (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0007-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0007-CSV/output.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0007-CSV/output.ttl.bak (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0011-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0011-CSV/output.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0011-CSV/output.ttl.bak (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0012-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0012-CSV/output.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0012-CSV/output.ttl.bak (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0014-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0014-CSV/output.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0014-CSV/output.ttl.bak (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0015-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0015-CSV/output.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0015-CSV/output.ttl.bak (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0016-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0016-CSV/output.nq (100%) rename src/test/resources/failing/{ => fno-testcases}/RMLFNOTC0016-CSV/output.ttl (100%) create mode 100644 src/test/resources/failing/fno-testcases/student.csv rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-CSV/output.nq (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-CSV/sport.csv (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-CSV/student.csv (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-JSON/mapping.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-JSON/output.nq (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-JSON/sport.json (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-JSON/student.json (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-XML/mapping.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-XML/output.nq (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-XML/sport.xml (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0009b-XML/student.xml (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-CSV/country info.csv (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-CSV/mapping.ttl.bak (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-CSV/output.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-JSON/country info.json (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-JSON/mapping.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-JSON/mapping.ttl.bak (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-JSON/output.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-XML/country info.xml (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-XML/mapping.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-XML/mapping.ttl.bak (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0010c-XML/output.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-JSON/mapping.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-JSON/mapping.ttl.bak (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-JSON/output.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-JSON/sport.json (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-JSON/student.json (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-JSON/student_sport.json (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-XML/mapping.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-XML/mapping.ttl.bak (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-XML/output.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-XML/sport.xml (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-XML/student.xml (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC0011b-XML/student_sport.xml (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC1003-CSV/mapping.ttl (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC1003-CSV/mapping.ttl.bak (100%) rename src/test/resources/failing/{ => rml-testcases}/RMLTC1003-CSV/output.ttl (100%) diff --git a/src/test/resources/failing/RMLFNOTC0000-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0000-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0000-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0000-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0000-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0000-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0000-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0004-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0004-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0004-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLFNOTC0004-CSV/output.ttl.bak rename to src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak diff --git a/src/test/resources/failing/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0005-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLFNOTC0005-CSV/output.ttl.bak rename to src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak diff --git a/src/test/resources/failing/RMLFNOTC0005-CSV/student.csv b/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/student.csv similarity index 100% rename from src/test/resources/failing/RMLFNOTC0005-CSV/student.csv rename to src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/student.csv diff --git a/src/test/resources/failing/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0006-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0006-CSV/output.nq b/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq similarity index 100% rename from src/test/resources/failing/RMLFNOTC0006-CSV/output.nq rename to src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq diff --git a/src/test/resources/failing/RMLFNOTC0007-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0007-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0007-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0007-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0007-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLFNOTC0007-CSV/output.ttl.bak rename to src/test/resources/failing/fno-testcases/RMLFNOTC0007-CSV/output.ttl.bak diff --git a/src/test/resources/failing/RMLFNOTC0011-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0011-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLFNOTC0011-CSV/output.ttl.bak rename to src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak diff --git a/src/test/resources/failing/RMLFNOTC0012-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0012-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0012-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0012-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0012-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLFNOTC0012-CSV/output.ttl.bak rename to src/test/resources/failing/fno-testcases/RMLFNOTC0012-CSV/output.ttl.bak diff --git a/src/test/resources/failing/RMLFNOTC0014-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0014-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLFNOTC0014-CSV/output.ttl.bak rename to src/test/resources/failing/fno-testcases/RMLFNOTC0014-CSV/output.ttl.bak diff --git a/src/test/resources/failing/RMLFNOTC0015-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0015-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/output.ttl diff --git a/src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLFNOTC0015-CSV/output.ttl.bak rename to src/test/resources/failing/fno-testcases/RMLFNOTC0015-CSV/output.ttl.bak diff --git a/src/test/resources/failing/RMLFNOTC0016-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0016-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLFNOTC0016-CSV/output.nq b/src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/output.nq similarity index 100% rename from src/test/resources/failing/RMLFNOTC0016-CSV/output.nq rename to src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/output.nq diff --git a/src/test/resources/failing/RMLFNOTC0016-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLFNOTC0016-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0016-CSV/output.ttl diff --git a/src/test/resources/failing/fno-testcases/student.csv b/src/test/resources/failing/fno-testcases/student.csv new file mode 100644 index 00000000..052b9915 --- /dev/null +++ b/src/test/resources/failing/fno-testcases/student.csv @@ -0,0 +1,2 @@ +Id,Name,Comment,Class +1,Venus,A&B,A diff --git a/src/test/resources/failing/RMLTC0009b-CSV/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0009b-CSV/mapping.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLTC0009b-CSV/output.nq b/src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/output.nq similarity index 100% rename from src/test/resources/failing/RMLTC0009b-CSV/output.nq rename to src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/output.nq diff --git a/src/test/resources/failing/RMLTC0009b-CSV/sport.csv b/src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/sport.csv similarity index 100% rename from src/test/resources/failing/RMLTC0009b-CSV/sport.csv rename to src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/sport.csv diff --git a/src/test/resources/failing/RMLTC0009b-CSV/student.csv b/src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/student.csv similarity index 100% rename from src/test/resources/failing/RMLTC0009b-CSV/student.csv rename to src/test/resources/failing/rml-testcases/RMLTC0009b-CSV/student.csv diff --git a/src/test/resources/failing/RMLTC0009b-JSON/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0009b-JSON/mapping.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/mapping.ttl diff --git a/src/test/resources/failing/RMLTC0009b-JSON/output.nq b/src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/output.nq similarity index 100% rename from src/test/resources/failing/RMLTC0009b-JSON/output.nq rename to src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/output.nq diff --git a/src/test/resources/failing/RMLTC0009b-JSON/sport.json b/src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/sport.json similarity index 100% rename from src/test/resources/failing/RMLTC0009b-JSON/sport.json rename to src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/sport.json diff --git a/src/test/resources/failing/RMLTC0009b-JSON/student.json b/src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/student.json similarity index 100% rename from src/test/resources/failing/RMLTC0009b-JSON/student.json rename to src/test/resources/failing/rml-testcases/RMLTC0009b-JSON/student.json diff --git a/src/test/resources/failing/RMLTC0009b-XML/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0009b-XML/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0009b-XML/mapping.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0009b-XML/mapping.ttl diff --git a/src/test/resources/failing/RMLTC0009b-XML/output.nq b/src/test/resources/failing/rml-testcases/RMLTC0009b-XML/output.nq similarity index 100% rename from src/test/resources/failing/RMLTC0009b-XML/output.nq rename to src/test/resources/failing/rml-testcases/RMLTC0009b-XML/output.nq diff --git a/src/test/resources/failing/RMLTC0009b-XML/sport.xml b/src/test/resources/failing/rml-testcases/RMLTC0009b-XML/sport.xml similarity index 100% rename from src/test/resources/failing/RMLTC0009b-XML/sport.xml rename to src/test/resources/failing/rml-testcases/RMLTC0009b-XML/sport.xml diff --git a/src/test/resources/failing/RMLTC0009b-XML/student.xml b/src/test/resources/failing/rml-testcases/RMLTC0009b-XML/student.xml similarity index 100% rename from src/test/resources/failing/RMLTC0009b-XML/student.xml rename to src/test/resources/failing/rml-testcases/RMLTC0009b-XML/student.xml diff --git a/src/test/resources/failing/RMLTC0010c-CSV/country info.csv b/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/country info.csv similarity index 100% rename from src/test/resources/failing/RMLTC0010c-CSV/country info.csv rename to src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/country info.csv diff --git a/src/test/resources/failing/RMLTC0010c-CSV/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0010c-CSV/mapping.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLTC0010c-CSV/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLTC0010c-CSV/mapping.ttl.bak rename to src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/mapping.ttl.bak diff --git a/src/test/resources/failing/RMLTC0010c-CSV/output.ttl b/src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0010c-CSV/output.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0010c-CSV/output.ttl diff --git a/src/test/resources/failing/RMLTC0010c-JSON/country info.json b/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/country info.json similarity index 100% rename from src/test/resources/failing/RMLTC0010c-JSON/country info.json rename to src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/country info.json diff --git a/src/test/resources/failing/RMLTC0010c-JSON/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0010c-JSON/mapping.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl diff --git a/src/test/resources/failing/RMLTC0010c-JSON/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLTC0010c-JSON/mapping.ttl.bak rename to src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/mapping.ttl.bak diff --git a/src/test/resources/failing/RMLTC0010c-JSON/output.ttl b/src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/output.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0010c-JSON/output.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0010c-JSON/output.ttl diff --git a/src/test/resources/failing/RMLTC0010c-XML/country info.xml b/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/country info.xml similarity index 100% rename from src/test/resources/failing/RMLTC0010c-XML/country info.xml rename to src/test/resources/failing/rml-testcases/RMLTC0010c-XML/country info.xml diff --git a/src/test/resources/failing/RMLTC0010c-XML/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0010c-XML/mapping.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl diff --git a/src/test/resources/failing/RMLTC0010c-XML/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLTC0010c-XML/mapping.ttl.bak rename to src/test/resources/failing/rml-testcases/RMLTC0010c-XML/mapping.ttl.bak diff --git a/src/test/resources/failing/RMLTC0010c-XML/output.ttl b/src/test/resources/failing/rml-testcases/RMLTC0010c-XML/output.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0010c-XML/output.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0010c-XML/output.ttl diff --git a/src/test/resources/failing/RMLTC0011b-JSON/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0011b-JSON/mapping.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/mapping.ttl diff --git a/src/test/resources/failing/RMLTC0011b-JSON/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLTC0011b-JSON/mapping.ttl.bak rename to src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak diff --git a/src/test/resources/failing/RMLTC0011b-JSON/output.ttl b/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/output.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0011b-JSON/output.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/output.ttl diff --git a/src/test/resources/failing/RMLTC0011b-JSON/sport.json b/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/sport.json similarity index 100% rename from src/test/resources/failing/RMLTC0011b-JSON/sport.json rename to src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/sport.json diff --git a/src/test/resources/failing/RMLTC0011b-JSON/student.json b/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/student.json similarity index 100% rename from src/test/resources/failing/RMLTC0011b-JSON/student.json rename to src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/student.json diff --git a/src/test/resources/failing/RMLTC0011b-JSON/student_sport.json b/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/student_sport.json similarity index 100% rename from src/test/resources/failing/RMLTC0011b-JSON/student_sport.json rename to src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/student_sport.json diff --git a/src/test/resources/failing/RMLTC0011b-XML/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0011b-XML/mapping.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0011b-XML/mapping.ttl diff --git a/src/test/resources/failing/RMLTC0011b-XML/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLTC0011b-XML/mapping.ttl.bak rename to src/test/resources/failing/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak diff --git a/src/test/resources/failing/RMLTC0011b-XML/output.ttl b/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/output.ttl similarity index 100% rename from src/test/resources/failing/RMLTC0011b-XML/output.ttl rename to src/test/resources/failing/rml-testcases/RMLTC0011b-XML/output.ttl diff --git a/src/test/resources/failing/RMLTC0011b-XML/sport.xml b/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/sport.xml similarity index 100% rename from src/test/resources/failing/RMLTC0011b-XML/sport.xml rename to src/test/resources/failing/rml-testcases/RMLTC0011b-XML/sport.xml diff --git a/src/test/resources/failing/RMLTC0011b-XML/student.xml b/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/student.xml similarity index 100% rename from src/test/resources/failing/RMLTC0011b-XML/student.xml rename to src/test/resources/failing/rml-testcases/RMLTC0011b-XML/student.xml diff --git a/src/test/resources/failing/RMLTC0011b-XML/student_sport.xml b/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/student_sport.xml similarity index 100% rename from src/test/resources/failing/RMLTC0011b-XML/student_sport.xml rename to src/test/resources/failing/rml-testcases/RMLTC0011b-XML/student_sport.xml diff --git a/src/test/resources/failing/RMLTC1003-CSV/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/RMLTC1003-CSV/mapping.ttl rename to src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl diff --git a/src/test/resources/failing/RMLTC1003-CSV/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl.bak similarity index 100% rename from src/test/resources/failing/RMLTC1003-CSV/mapping.ttl.bak rename to src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl.bak diff --git a/src/test/resources/failing/RMLTC1003-CSV/output.ttl b/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/RMLTC1003-CSV/output.ttl rename to src/test/resources/failing/rml-testcases/RMLTC1003-CSV/output.ttl From 2bb77190fea21b76df9d9d883b369acb9d522f9d Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 2 Jun 2020 09:04:26 +0200 Subject: [PATCH 017/169] wip: function feature - added sandbox tests, and set them all to pending --- .../RMLTC0011b-CSV-small/mapping.ttl | 80 +++++++++++++++++++ .../RMLTC0011b-CSV-small/mapping.ttl.bak | 79 ++++++++++++++++++ .../RMLTC0011b-CSV-small/output.ttl | 4 + .../RMLTC0011b-CSV-small/sport.csv | 4 + .../RMLTC0011b-CSV-small/student.csv | 4 + .../RMLTC0011b-CSV-small/student_sport.csv | 5 ++ .../rml-testcases/RMLTC0011b-CSV/mapping.ttl | 79 ++++++++++++++++++ .../RMLTC0011b-CSV/mapping.ttl.bak | 79 ++++++++++++++++++ .../rml-testcases/RMLTC0011b-CSV/output.ttl | 17 ++++ .../rml-testcases/RMLTC0011b-CSV/sport.csv | 4 + .../rml-testcases/RMLTC0011b-CSV/student.csv | 4 + .../RMLTC0011b-CSV/student_sport.csv | 5 ++ .../scala/io/rml/framework/SandboxTests.scala | 32 ++++++++ 13 files changed, 396 insertions(+) create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl.bak create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/output.ttl create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/sport.csv create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student.csv create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student_sport.csv create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/output.ttl create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/sport.csv create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student.csv create mode 100644 src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student_sport.csv diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl new file mode 100644 index 00000000..964e6d31 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl @@ -0,0 +1,80 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . + +@base . + +# +# a rr:TriplesMap; + +# rml:logicalSource [ +# rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; +# rml:referenceFormulation ql:CSV +# ]; + +# rr:subjectMap [ +# rr:template "http://example.com/student/{ID}"; +# ]; + +# rr:predicateObjectMap [ +# rr:predicate ex:firstName; +# rr:objectMap [ +# rml:reference "FirstName" +# ] +# ]; + +# rr:predicateObjectMap [ +# rr:predicate ex:lastName; +# rr:objectMap [ +# rml:reference "LastName" +# ] +# ]. + +# +# a rr:TriplesMap; + +# rml:logicalSource [ +# rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; +# rml:referenceFormulation ql:CSV +# ]; + +# rr:subjectMap [ +# rr:template "http://example.com/sport/{ID}"; +# ]; + +# rr:predicateObjectMap [ +# rr:predicate ex:id; +# rr:objectMap [ +# rml:reference "ID" +# ] +# ]; + +# rr:predicateObjectMap [ +# rr:predicate ex:description; +# rr:objectMap [ +# rml:reference "Description" +# ] +# ]. + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/student/{ID_Student}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:plays; + rr:objectMap [ + rr:template "http://example.com/sport/{ID_Sport}"; + + ] + ]. diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl.bak b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl.bak new file mode 100644 index 00000000..7021f6f4 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl.bak @@ -0,0 +1,79 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/student/{ID}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:firstName; + rr:objectMap [ + rml:reference "FirstName" + ] + ]; + + rr:predicateObjectMap [ + rr:predicate ex:lastName; + rr:objectMap [ + rml:reference "LastName" + ] + ]. + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/sport/{ID}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:id; + rr:objectMap [ + rml:reference "ID" + ] + ]; + + rr:predicateObjectMap [ + rr:predicate ex:description; + rr:objectMap [ + rml:reference "Description" + ] + ]. + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/student/{ID_Student}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:plays; + rr:objectMap [ + rr:template "http://example.com/sport/{ID_Sport}" + ] + ]. diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/output.ttl b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/output.ttl new file mode 100644 index 00000000..7754ec89 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/output.ttl @@ -0,0 +1,4 @@ + . + . + . + . diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/sport.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/sport.csv new file mode 100644 index 00000000..98446d06 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/sport.csv @@ -0,0 +1,4 @@ +ID,Description +110,Tennis +111,Football +112,Formula1 diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student.csv new file mode 100644 index 00000000..acf08c28 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student.csv @@ -0,0 +1,4 @@ +ID,FirstName,LastName +10,Venus,Williams +11,Fernando,Alonso +12,David,Villa diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student_sport.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student_sport.csv new file mode 100644 index 00000000..381e9213 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV-small/student_sport.csv @@ -0,0 +1,5 @@ +ID_Student,ID_Sport +10,110 +11,111 +11,112 +12,111 diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl new file mode 100644 index 00000000..7021f6f4 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl @@ -0,0 +1,79 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/student/{ID}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:firstName; + rr:objectMap [ + rml:reference "FirstName" + ] + ]; + + rr:predicateObjectMap [ + rr:predicate ex:lastName; + rr:objectMap [ + rml:reference "LastName" + ] + ]. + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/sport/{ID}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:id; + rr:objectMap [ + rml:reference "ID" + ] + ]; + + rr:predicateObjectMap [ + rr:predicate ex:description; + rr:objectMap [ + rml:reference "Description" + ] + ]. + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/student/{ID_Student}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:plays; + rr:objectMap [ + rr:template "http://example.com/sport/{ID_Sport}" + ] + ]. diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak new file mode 100644 index 00000000..7021f6f4 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak @@ -0,0 +1,79 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/student/{ID}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:firstName; + rr:objectMap [ + rml:reference "FirstName" + ] + ]; + + rr:predicateObjectMap [ + rr:predicate ex:lastName; + rr:objectMap [ + rml:reference "LastName" + ] + ]. + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/sport.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/sport/{ID}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:id; + rr:objectMap [ + rml:reference "ID" + ] + ]; + + rr:predicateObjectMap [ + rr:predicate ex:description; + rr:objectMap [ + rml:reference "Description" + ] + ]. + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "rml-testcases/RMLTC0011b-CSV/student_sport.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/student/{ID_Student}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:plays; + rr:objectMap [ + rr:template "http://example.com/sport/{ID_Sport}" + ] + ]. diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/output.ttl b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/output.ttl new file mode 100644 index 00000000..d2759cec --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/output.ttl @@ -0,0 +1,17 @@ + "Williams" . + "Venus" . + "Villa" . + "David" . + "Alonso" . + "Fernando" . + "Tennis" . + "110" . + "Football" . + "111" . + "Formula1" . + "112" . + . + . + . + . + diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/sport.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/sport.csv new file mode 100644 index 00000000..98446d06 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/sport.csv @@ -0,0 +1,4 @@ +ID,Description +110,Tennis +111,Football +112,Formula1 diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student.csv new file mode 100644 index 00000000..acf08c28 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student.csv @@ -0,0 +1,4 @@ +ID,FirstName,LastName +10,Venus,Williams +11,Fernando,Alonso +12,David,Villa diff --git a/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student_sport.csv b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student_sport.csv new file mode 100644 index 00000000..381e9213 --- /dev/null +++ b/src/test/resources/sandbox/rml-testcases/RMLTC0011b-CSV/student_sport.csv @@ -0,0 +1,5 @@ +ID_Student,ID_Sport +10,110 +11,111 +11,112 +12,111 diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 52bcbc15..00aa2818 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -81,12 +81,44 @@ class SandboxTests extends FunSuite with Matchers { } + /** + * RML TESTCASES + */ + + /** + * [STATE @ ] + + */ + test("sandbox/rml-testcases/RMLTC0011b-CSV") { + pending + executeTest("sandbox/rml-testcases/RMLTC0011b-CSV/mapping.ttl") + + } + + /** + * [STATE @ ] + * + + */ + test("sandbox/rml-testcases/RMLTC0011b-CSV-small") { + pending + executeTest("sandbox/rml-testcases/RMLTC0011b-CSV-small/mapping.ttl") + + } + + + + /** + * FNO TEST CASES + */ test("sandbox/fno-testcases/RMLFNOTC0001-CSV") { + pending executeTest("sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping.ttl") } test("sandbox/fno-testcases/RMLFNOTC0001-CSV-explicit") { + pending executeTest("sandbox/fno-testcases/RMLFNOTC0001-CSV/mapping_explicit.ttl") } From 4e71eeba4025a1dc4150f2c2298f2c6cac1d0761 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 2 Jun 2020 09:53:28 +0200 Subject: [PATCH 018/169] wip: function feature - fix: incorrect literal term type assignment+ doc A resource was being incorrectly classified as a Literal when the resource had a template property. The RML Spec states: If the term map does not have a `rr:termType` property, then its term type is: - `rr:Literal`, if it is an object map and at least one of the following conditions is true: - It is a reference-based term map. - It has a `rml:referenceFormulation` property (and thus a specified language tag). - It has a `rr:datatype` property (and thus a specified datatype). - `rr:IRI`, otherwise. --- .../std/StdObjectMapExtractor.scala | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala index 8d49b761..f1922640 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala @@ -80,21 +80,21 @@ class StdObjectMapExtractor(stdFunctionMapExtractor: FunctionMapExtractor) exten case resource: RDFResource => Some(extractObjectMap(resource)) } - -// //case resource: RDFResource => Some(extractObjectMap(resource)) -// case resource: RDFResource => { -// // if resource hasn't a type specified, check whether it has the function value property -// val functionValueProperties = resource.listProperties(Uri(RMLVoc.Property.FUNCTIONVALUE).toString) -// if(functionValueProperties.nonEmpty | resource.getType.eq(Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)))) -// None -// else -// Some(extractObjectMap(resource)) -// } -// // case resource.getType match { -// // case Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)) => None // TODO: rethink this -// // case _ => Some(extractObjectMap(resource)) -// // } -// } + // TODO: safe to delete? + // //case resource: RDFResource => Some(extractObjectMap(resource)) + // case resource: RDFResource => { + // // if resource hasn't a type specified, check whether it has the function value property + // val functionValueProperties = resource.listProperties(Uri(RMLVoc.Property.FUNCTIONVALUE).toString) + // if(functionValueProperties.nonEmpty | resource.getType.eq(Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)))) + // None + // else + // Some(extractObjectMap(resource)) + // } + // // case resource.getType match { + // // case Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)) => None // TODO: rethink this + // // case _ => Some(extractObjectMap(resource)) + // // } + // } } @@ -149,16 +149,16 @@ class StdObjectMapExtractor(stdFunctionMapExtractor: FunctionMapExtractor) exten } } else { - - // if this is a reference-based term map or contains an referenceFormulation or has a datatype property the - // or has a functionValue property or a template without term type, the - // term type is a literal + // the term type is Literal when one of the following is true + // - the resource is a reference-based term map + // - the resource contains a referenceFormulation + // - the resource has a datatype property + // - the resource has a functionValue property // TODO: verify val elements = resource.listProperties(RMLVoc.Property.REFERENCE) ++ resource.listProperties(RMLVoc.Property.REFERENCEFORMULATION) ++ resource.listProperties(RMLVoc.Property.DATATYPE) ++ - resource.listProperties(RMLVoc.Property.FUNCTIONVALUE) ++ - resource.listProperties(RMLVoc.Property.TEMPLATE) + resource.listProperties(RMLVoc.Property.FUNCTIONVALUE) if (elements.nonEmpty) Some(Uri(RMLVoc.Class.LITERAL)) else Some(Uri(RMLVoc.Class.IRI)) From 73101ec511a715b8cd780edcd9737a49149759ed Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 2 Jun 2020 09:54:09 +0200 Subject: [PATCH 019/169] wip set sandbox test to pending --- src/test/scala/io/rml/framework/SandboxTests.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 00aa2818..973bda33 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -142,6 +142,7 @@ class SandboxTests extends FunSuite with Matchers { * value parameter: template using {Name} */ test("sandbox/fno-testcases/RMLFNOTC0008-CSV") { + pending executeTest("sandbox/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl") } From 35ebd8a0c62f5fab8927de89ba135b91e324fdd7 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 2 Jun 2020 10:09:08 +0200 Subject: [PATCH 020/169] wip: feature function #25 - refactored tests. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [LOCAL] mvn clean test → build succesful & all tests passed. --- .../RMLFNOTC0008-CSV/mapping.ttl | 0 .../fno-testcases/RMLFNOTC0008-CSV/output.ttl | 0 .../RMLFNOTC0008-CSV/output.ttl.bak | 0 .../rml-testcases/RMLTC1003-CSV/mapping.ttl | 29 ------------------- .../RMLTC1003-CSV/mapping.ttl.bak | 29 ------------------- .../rml-testcases/RMLTC1003-CSV/output.ttl | 2 -- .../RMLTC0011b-CSV/mapping.ttl | 0 .../RMLTC0011b-CSV/mapping.ttl.bak | 0 .../RMLTC0011b-CSV/output.ttl | 0 .../RMLTC0011b-CSV/sport.csv | 0 .../RMLTC0011b-CSV/student.csv | 0 .../RMLTC0011b-CSV/student_sport.csv | 0 .../rml-testcases/RMLTC0011b-JSON/mapping.ttl | 0 .../RMLTC0011b-JSON/mapping.ttl.bak | 0 .../rml-testcases/RMLTC0011b-JSON/output.ttl | 0 .../rml-testcases/RMLTC0011b-JSON/sport.json | 0 .../RMLTC0011b-JSON/student.json | 0 .../RMLTC0011b-JSON/student_sport.json | 0 .../rml-testcases/RMLTC0011b-XML/mapping.ttl | 0 .../RMLTC0011b-XML/mapping.ttl.bak | 0 .../rml-testcases/RMLTC0011b-XML/output.ttl | 0 .../rml-testcases/RMLTC0011b-XML/sport.xml | 0 .../rml-testcases/RMLTC0011b-XML/student.xml | 0 .../RMLTC0011b-XML/student_sport.xml | 0 24 files changed, 60 deletions(-) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl (100%) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0008-CSV/output.ttl (100%) rename src/test/resources/{ => failing}/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak (100%) delete mode 100644 src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl delete mode 100644 src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl.bak delete mode 100644 src/test/resources/failing/rml-testcases/RMLTC1003-CSV/output.ttl rename src/test/resources/{ => rml-testcases}/RMLTC0011b-CSV/mapping.ttl (100%) rename src/test/resources/{ => rml-testcases}/RMLTC0011b-CSV/mapping.ttl.bak (100%) rename src/test/resources/{ => rml-testcases}/RMLTC0011b-CSV/output.ttl (100%) rename src/test/resources/{ => rml-testcases}/RMLTC0011b-CSV/sport.csv (100%) rename src/test/resources/{ => rml-testcases}/RMLTC0011b-CSV/student.csv (100%) rename src/test/resources/{ => rml-testcases}/RMLTC0011b-CSV/student_sport.csv (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-JSON/mapping.ttl (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-JSON/output.ttl (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-JSON/sport.json (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-JSON/student.json (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-JSON/student_sport.json (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-XML/mapping.ttl (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-XML/output.ttl (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-XML/sport.xml (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-XML/student.xml (100%) rename src/test/resources/{failing => }/rml-testcases/RMLTC0011b-XML/student_sport.xml (100%) diff --git a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/mapping.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/output.ttl similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl rename to src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/output.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak rename to src/test/resources/failing/fno-testcases/RMLFNOTC0008-CSV/output.ttl.bak diff --git a/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl b/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl deleted file mode 100644 index 4c2e28e1..00000000 --- a/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl +++ /dev/null @@ -1,29 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "http://rml.io/data/dataRetrieval/dcat/Airport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{id}" - ]; - - rr:predicateObjectMap [ - rr:predicate ex:city; - rr:objectMap [ - rml:reference "city" - ] - ]. - - diff --git a/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl.bak b/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl.bak deleted file mode 100644 index 4c2e28e1..00000000 --- a/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/mapping.ttl.bak +++ /dev/null @@ -1,29 +0,0 @@ -@prefix rr: . -@prefix foaf: . -@prefix ex: . -@prefix xsd: . -@prefix rml: . -@prefix ql: . - -@base . - - - a rr:TriplesMap; - - rml:logicalSource [ - rml:source "http://rml.io/data/dataRetrieval/dcat/Airport.csv"; - rml:referenceFormulation ql:CSV - ]; - - rr:subjectMap [ - rr:template "http://example.com/{id}" - ]; - - rr:predicateObjectMap [ - rr:predicate ex:city; - rr:objectMap [ - rml:reference "city" - ] - ]. - - diff --git a/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/output.ttl b/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/output.ttl deleted file mode 100644 index 31168c83..00000000 --- a/src/test/resources/failing/rml-testcases/RMLTC1003-CSV/output.ttl +++ /dev/null @@ -1,2 +0,0 @@ - "Brussels". - "Athens". diff --git a/src/test/resources/RMLTC0011b-CSV/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl similarity index 100% rename from src/test/resources/RMLTC0011b-CSV/mapping.ttl rename to src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl diff --git a/src/test/resources/RMLTC0011b-CSV/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak similarity index 100% rename from src/test/resources/RMLTC0011b-CSV/mapping.ttl.bak rename to src/test/resources/rml-testcases/RMLTC0011b-CSV/mapping.ttl.bak diff --git a/src/test/resources/RMLTC0011b-CSV/output.ttl b/src/test/resources/rml-testcases/RMLTC0011b-CSV/output.ttl similarity index 100% rename from src/test/resources/RMLTC0011b-CSV/output.ttl rename to src/test/resources/rml-testcases/RMLTC0011b-CSV/output.ttl diff --git a/src/test/resources/RMLTC0011b-CSV/sport.csv b/src/test/resources/rml-testcases/RMLTC0011b-CSV/sport.csv similarity index 100% rename from src/test/resources/RMLTC0011b-CSV/sport.csv rename to src/test/resources/rml-testcases/RMLTC0011b-CSV/sport.csv diff --git a/src/test/resources/RMLTC0011b-CSV/student.csv b/src/test/resources/rml-testcases/RMLTC0011b-CSV/student.csv similarity index 100% rename from src/test/resources/RMLTC0011b-CSV/student.csv rename to src/test/resources/rml-testcases/RMLTC0011b-CSV/student.csv diff --git a/src/test/resources/RMLTC0011b-CSV/student_sport.csv b/src/test/resources/rml-testcases/RMLTC0011b-CSV/student_sport.csv similarity index 100% rename from src/test/resources/RMLTC0011b-CSV/student_sport.csv rename to src/test/resources/rml-testcases/RMLTC0011b-CSV/student_sport.csv diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/mapping.ttl rename to src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak rename to src/test/resources/rml-testcases/RMLTC0011b-JSON/mapping.ttl.bak diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/output.ttl b/src/test/resources/rml-testcases/RMLTC0011b-JSON/output.ttl similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/output.ttl rename to src/test/resources/rml-testcases/RMLTC0011b-JSON/output.ttl diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/sport.json b/src/test/resources/rml-testcases/RMLTC0011b-JSON/sport.json similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/sport.json rename to src/test/resources/rml-testcases/RMLTC0011b-JSON/sport.json diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/student.json b/src/test/resources/rml-testcases/RMLTC0011b-JSON/student.json similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/student.json rename to src/test/resources/rml-testcases/RMLTC0011b-JSON/student.json diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/student_sport.json b/src/test/resources/rml-testcases/RMLTC0011b-JSON/student_sport.json similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-JSON/student_sport.json rename to src/test/resources/rml-testcases/RMLTC0011b-JSON/student_sport.json diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/mapping.ttl b/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-XML/mapping.ttl rename to src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak b/src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak rename to src/test/resources/rml-testcases/RMLTC0011b-XML/mapping.ttl.bak diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/output.ttl b/src/test/resources/rml-testcases/RMLTC0011b-XML/output.ttl similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-XML/output.ttl rename to src/test/resources/rml-testcases/RMLTC0011b-XML/output.ttl diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/sport.xml b/src/test/resources/rml-testcases/RMLTC0011b-XML/sport.xml similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-XML/sport.xml rename to src/test/resources/rml-testcases/RMLTC0011b-XML/sport.xml diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/student.xml b/src/test/resources/rml-testcases/RMLTC0011b-XML/student.xml similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-XML/student.xml rename to src/test/resources/rml-testcases/RMLTC0011b-XML/student.xml diff --git a/src/test/resources/failing/rml-testcases/RMLTC0011b-XML/student_sport.xml b/src/test/resources/rml-testcases/RMLTC0011b-XML/student_sport.xml similarity index 100% rename from src/test/resources/failing/rml-testcases/RMLTC0011b-XML/student_sport.xml rename to src/test/resources/rml-testcases/RMLTC0011b-XML/student_sport.xml From 5f995a9fd218580a5ca07b262f56a8d14e98f0c9 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Wed, 3 Jun 2020 12:03:24 +0200 Subject: [PATCH 021/169] wip: feature function #25 - RMLFNOTC0004-CSV now working Changes to mapping.file - added namespace grel - changed valueParameter 's prefix namespace to grel - changed function's prefix namespace to grel (previously: idlab-fn) Changes to code - PredicateGeneratorAssembler can now assemble functions to generate predicates --- .../PredicateGeneratorAssembler.scala | 23 +++++++++++++++++-- .../RMLFNOTC0004-CSV/mapping.ttl | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/scala/io/rml/framework/engine/statement/PredicateGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/PredicateGeneratorAssembler.scala index 0256fe94..4ec05927 100644 --- a/src/main/scala/io/rml/framework/engine/statement/PredicateGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/PredicateGeneratorAssembler.scala @@ -25,13 +25,32 @@ package io.rml.framework.engine.statement -import io.rml.framework.core.model.{TermMap, Uri} +import io.rml.framework.core.function.TransformationUtils +import io.rml.framework.core.model.{Literal, TermMap, Uri} import io.rml.framework.flink.item.Item class PredicateGeneratorAssembler extends TermMapGeneratorAssembler { override def assemble(termMap: TermMap): (Item) => Option[Iterable[Uri]] = { - super.assemble(termMap).asInstanceOf[(Item) => Option[Iterable[Uri]]] + + // Note: this code is very redundant to ObjectGeneratorAssembler. TODO: generalize? + if(termMap.hasFunctionMap){ + val fmap = termMap.functionMap.head + val assembledFunction = FunctionMapGeneratorAssembler().assemble(fmap) + assembledFunction.andThen(item => { + if(item.isDefined) { + item.map(iter => iter.flatMap(elem => { + val castedResult = TransformationUtils.typeCastDataType(elem, termMap.datatype) + castedResult.map(v => Uri(v.toString)) + })) + }else { + None + } + }) + } + else { + super.assemble(termMap).asInstanceOf[(Item) => Option[Iterable[Uri]]] + } } } diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl index fe1c29b7..7ee60664 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl @@ -8,6 +8,7 @@ @prefix ql: . @prefix fnml: . @prefix fno: . +#@prefix idlab-fn: . @prefix grel: . @base . From 5697029e8c67ff96c69b2ef87df7982ba97d5f24 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 4 Jun 2020 10:12:03 +0200 Subject: [PATCH 022/169] wip: feature function #25: RMLFNOTC0006-CSV working Testcase that creates multiple graphs --- .../core/extractors/std/StdGraphMapExtractor.scala | 7 ++++--- .../scala/io/rml/framework/core/model/GraphMap.scala | 3 ++- .../io/rml/framework/core/model/std/StdGraphMap.scala | 1 + .../engine/statement/GraphGeneratorAssembler.scala | 9 +++++++++ .../framework/engine/statement/StatementsAssembler.scala | 3 ++- .../fno-testcases/RMLFNOTC0006-CSV/mapping.ttl | 0 .../resources/fno-testcases/RMLFNOTC0006-CSV/output.nq | 1 + 7 files changed, 19 insertions(+), 5 deletions(-) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl (100%) create mode 100644 src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdGraphMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdGraphMapExtractor.scala index 1be7a108..b082888f 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdGraphMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdGraphMapExtractor.scala @@ -24,7 +24,7 @@ **/ package io.rml.framework.core.extractors.std -import io.rml.framework.core.extractors.GraphMapExtractor +import io.rml.framework.core.extractors.{FunctionMapExtractor, GraphMapExtractor} import io.rml.framework.core.model.rdf.{RDFNode, RDFResource} import io.rml.framework.core.model.{GraphMap, Literal, Uri} import io.rml.framework.core.vocabulary.RMLVoc @@ -77,7 +77,7 @@ class StdGraphMapExtractor extends GraphMapExtractor { def extractGraph(resource: RDFResource): Option[GraphMap] = { - Some(GraphMap(resource.uri.toString, Some(resource.uri), None, None, extractTermType(resource))) + Some(GraphMap(resource.uri.toString, List(), Some(resource.uri), None, None, extractTermType(resource))) } @@ -86,7 +86,8 @@ class StdGraphMapExtractor extends GraphMapExtractor { val template = extractTemplate(resource) val constant = extractConstant(resource) val reference = extractReference(resource) - Some(GraphMap(constant.getOrElse(resource.uri).toString, constant, reference, template, termType)) + val functionMap = FunctionMapExtractor().extract(resource) + Some(GraphMap(constant.getOrElse(resource.uri).toString, functionMap, constant, reference, template, termType)) } } diff --git a/src/main/scala/io/rml/framework/core/model/GraphMap.scala b/src/main/scala/io/rml/framework/core/model/GraphMap.scala index 25ce4c96..a992a342 100644 --- a/src/main/scala/io/rml/framework/core/model/GraphMap.scala +++ b/src/main/scala/io/rml/framework/core/model/GraphMap.scala @@ -41,8 +41,9 @@ trait GraphMap extends TermMap object GraphMap { def apply(identifier: String, + functionMap: List[FunctionMap], constant: Option[Entity], reference: Option[Literal], template: Option[Literal], - termType: Option[Uri]): GraphMap = StdGraphMap(identifier, constant, reference, template) + termType: Option[Uri]): GraphMap = StdGraphMap(identifier, functionMap, constant, reference, template) } diff --git a/src/main/scala/io/rml/framework/core/model/std/StdGraphMap.scala b/src/main/scala/io/rml/framework/core/model/std/StdGraphMap.scala index 74cbfc2e..b323e6fa 100644 --- a/src/main/scala/io/rml/framework/core/model/std/StdGraphMap.scala +++ b/src/main/scala/io/rml/framework/core/model/std/StdGraphMap.scala @@ -28,6 +28,7 @@ import io.rml.framework.core.model._ import io.rml.framework.core.vocabulary.RMLVoc case class StdGraphMap(identifier: String, + override val functionMap:List[FunctionMap], constant: Option[Entity], reference: Option[Literal], template: Option[Literal]) extends GraphMap { diff --git a/src/main/scala/io/rml/framework/engine/statement/GraphGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/GraphGeneratorAssembler.scala index 7a8d0441..ca720a5f 100644 --- a/src/main/scala/io/rml/framework/engine/statement/GraphGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/GraphGeneratorAssembler.scala @@ -25,6 +25,7 @@ package io.rml.framework.engine.statement import io.rml.framework.core.model.{GraphMap, TermMap, Uri} +import io.rml.framework.core.util.Util import io.rml.framework.flink.item.Item class GraphGeneratorAssembler extends TermMapGeneratorAssembler { @@ -38,8 +39,16 @@ class GraphGeneratorAssembler extends TermMapGeneratorAssembler { override def assemble(termMap: TermMap): Item => Option[Iterable[Uri]] = + if (termMap.hasFunctionMap) { + val assembled = FunctionMapGeneratorAssembler().assemble(termMap.functionMap.head) + + assembled.andThen(result => { + result.map(iter => iter.map(elem => Uri(elem.toString))) + }) + } else { super.assemble(termMap).asInstanceOf[(Item) => Option[Iterable[Uri]]] + } } diff --git a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala index d829d572..763e18ec 100644 --- a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala @@ -58,7 +58,8 @@ extends Logging{ }) // create the statements predicateObjects.map(predicateObject => { - (subjectGenerator, predicateObject._1, predicateObject._2, subjectGraphGenerator) + val graphGenerator = if(triplesMap.subjectMap.graphMap.isDefined) subjectGraphGenerator else predicateObject._3 + (subjectGenerator, predicateObject._1, predicateObject._2, graphGenerator) }) ++ classMappings // add class mappings } diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0006-CSV/mapping.ttl diff --git a/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq new file mode 100644 index 00000000..2456fe11 --- /dev/null +++ b/src/test/resources/fno-testcases/RMLFNOTC0006-CSV/output.nq @@ -0,0 +1 @@ + "Venus" . From 5b49eadd6d9fc1afdf0d96f47d442f5455b195d1 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 4 Jun 2020 10:30:24 +0200 Subject: [PATCH 023/169] wip: feature function #25 - RMLFNOTC0004-CSV moved testcase Moved RMLFNOTC0004-CSV from failing to the working directory --- .../{failing => }/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl | 0 .../{failing => }/fno-testcases/RMLFNOTC0004-CSV/output.ttl | 0 .../{failing => }/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0004-CSV/output.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak (100%) diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0004-CSV/mapping.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak rename to src/test/resources/fno-testcases/RMLFNOTC0004-CSV/output.ttl.bak From c8fe6051760aa5726e56b11feefa0b61de175e4c Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 4 Jun 2020 15:13:40 +0200 Subject: [PATCH 024/169] wip: feature function #25 - RMLFNOTC0011-CSV working ObjectGeneratorAssembler: - removed type cast of object value test: moved testcase from failing to working directory --- .../engine/statement/ObjectGeneratorAssembler.scala | 6 +++--- .../fno-testcases/RMLFNOTC0011-CSV/mapping.ttl | 0 .../{failing => }/fno-testcases/RMLFNOTC0011-CSV/output.ttl | 0 .../fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0011-CSV/output.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak (100%) diff --git a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala index 2a0413a4..0973fc5a 100644 --- a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala @@ -45,9 +45,9 @@ class ObjectGeneratorAssembler extends TermMapGeneratorAssembler { termTypeString match { case RMLVoc.Class.IRI => item.map(iter => iter.map(elem => Uri(elem.toString))) case _ => item.map(iter => iter.flatMap(elem => { - - val castedResult = TransformationUtils.typeCastDataType(elem, objectMap.datatype) - castedResult.map(v => Literal(v.toString, objectMap.datatype, objectMap.language)) + //val castedResult = TransformationUtils.typeCastDataType(elem, objectMap.datatype) + //castedResult.map(v => Literal(v.toString, objectMap.datatype, objectMap.language)) + Some(Literal(elem.identifier, objectMap.datatype, objectMap.language)) })) } diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0011-CSV/mapping.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak rename to src/test/resources/fno-testcases/RMLFNOTC0011-CSV/output.ttl.bak From c5cc3ccca13b908fedd0e7d2f82753103c3a8228 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 4 Jun 2020 16:01:48 +0200 Subject: [PATCH 025/169] wip: feature function #25 - added RMLException FunctionMapGeneratorAssembler - Throw RMLException when no fno:executes-property could be found. This might be the case when the namespaces in the mapping files differ from the ones defined in RMLVoc.Property. For example, the Grel-function's namespace in the RMLVoc is defined as a plain HTTP url, while some mapping files use HTTPS. --- .../statement/FunctionMapGeneratorAssembler.scala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index ab00cc7c..7af215e0 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -31,6 +31,7 @@ import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item import io.rml.framework.flink.sink.FlinkRDFQuad import io.rml.framework.flink.source.EmptyItem +import io.rml.framework.shared.RMLException case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { @@ -58,8 +59,14 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { this.logInfo("parseFunction (assembledPom)") val placeHolder: List[FlinkRDFQuad] = generateFunctionTriples(new EmptyItem(), assembledPom) - val functionName = Uri(placeHolder - .filter( quad => quad.predicate.value == Uri(RMLVoc.Property.EXECUTES)) + + val executeProperties = placeHolder.filter( quad => quad.predicate.value == Uri(RMLVoc.Property.EXECUTES)) + if(executeProperties.isEmpty) + throw new RMLException(s"Couldn't find ${RMLVoc.Property.EXECUTES} property." + + s"Is the namespace correct? (e.g. HTTP vs. HTTPS)") + + val functionName = Uri( + executeProperties .head .`object` .value From b517d221743915f1439d9885d11bfb3c0fda20d9 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 5 Jun 2020 11:00:20 +0200 Subject: [PATCH 026/169] wip: feature function #25 - removed RMLFNOTC0006-CSV from failing RMLFNOTC0006-CSV was already working, but was still in the failing directory. Removed it from the failing dir to avoid confusion. --- .../resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq b/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq deleted file mode 100644 index 2258872a..00000000 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0006-CSV/output.nq +++ /dev/null @@ -1 +0,0 @@ - "Venus" . From a40acadb9fc413b6a47d2fc74443165a3092eb51 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 5 Jun 2020 15:28:39 +0200 Subject: [PATCH 027/169] wip: feature function #25 - RMLFNOTC0005-CSV working There were some issues with finding the logical source. Also a `student.csv` is used, however, this file differs from the others regarding the use of a url-column. To make the distinction clear, I added a `student_url.csv` to the `fno-testcases` in the working testcases dir, as it appears to look for its logical sources in that dir. engine.statement.SubjectGeneratorAssembler - invokes FunctionMapGeneratorAssembler when the subjectmap has a FunctionMap test: - moved test from failing to working dir - created `student_url.csv` in the working `fno-testcases` dir. - updated RMLFNOTC0005-CSV/mapping.ttl's logical source to point at `fno-testcases/student_url.csv` --- .../statement/SubjectGeneratorAssembler.scala | 43 +++++++++++++------ .../RMLFNOTC0005-CSV/mapping.ttl | 2 +- .../fno-testcases/RMLFNOTC0005-CSV/output.ttl | 0 .../RMLFNOTC0005-CSV/output.ttl.bak | 0 .../resources/fno-testcases/student_url.csv | 2 + 5 files changed, 34 insertions(+), 13 deletions(-) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl (94%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0005-CSV/output.ttl (100%) rename src/test/resources/{failing => }/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak (100%) create mode 100644 src/test/resources/fno-testcases/student_url.csv diff --git a/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala index 588254ad..004b33e6 100644 --- a/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala @@ -25,7 +25,8 @@ package io.rml.framework.engine.statement -import io.rml.framework.core.model.{TermMap, TermNode} +import io.rml.framework.core.function.TransformationUtils +import io.rml.framework.core.model.{TermMap, TermNode, Uri} import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item import io.rml.framework.shared.TermTypeException @@ -34,19 +35,37 @@ import io.rml.framework.shared.TermTypeException class SubjectGeneratorAssembler extends TermMapGeneratorAssembler { override def assemble(termMap: TermMap): (Item) => Option[Iterable[TermNode]] = { - /** - * Tried implementing literal check in subject map extractor but it was assumed - * that the extractor would just extract subject maps even if it is typed to be literal. - * - * Maybe move this check to subject map extractor for early checking during the reading process? - */ - termMap.termType.get.toString match { - case RMLVoc.Class.LITERAL => throw new TermTypeException("Subject cannot be of type Literal!") - case _ => + if(termMap.hasFunctionMap){ + val fmap = termMap.functionMap.head + val assembledFunction = FunctionMapGeneratorAssembler().assemble(fmap) + assembledFunction.andThen(item => { + + if(item.isDefined) { + item.map(iter => iter.flatMap(elem => { + val castedResult = TransformationUtils.typeCastDataType(elem, termMap.datatype) + castedResult.map(v => Uri(v.toString)) + })) + }else { + None + } + }) + + }else { - } - super.assemble(termMap).asInstanceOf[(Item) => Option[Iterable[TermNode]]] + /** + * Tried implementing literal check in subject map extractor but it was assumed + * that the extractor would just extract subject maps even if it is typed to be literal. + * + * Maybe move this check to subject map extractor for early checking during the reading process? + */ + termMap.termType.get.toString match { + case RMLVoc.Class.LITERAL => throw new TermTypeException("Subject cannot be of type Literal!") + case _ => + + } + super.assemble(termMap).asInstanceOf[(Item) => Option[Iterable[TermNode]]] + } } } diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl similarity index 94% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl index e5714b73..f7fac9b7 100644 --- a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/mapping.ttl @@ -16,7 +16,7 @@ a rr:TriplesMap; rml:logicalSource [ - rml:source "fno-testcases/RMLFNOTC0005-CSV/student.csv"; + rml:source "fno-testcases/student_url.csv"; rml:referenceFormulation ql:CSV ]; diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl rename to src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak b/src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak similarity index 100% rename from src/test/resources/failing/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak rename to src/test/resources/fno-testcases/RMLFNOTC0005-CSV/output.ttl.bak diff --git a/src/test/resources/fno-testcases/student_url.csv b/src/test/resources/fno-testcases/student_url.csv new file mode 100644 index 00000000..c33048c8 --- /dev/null +++ b/src/test/resources/fno-testcases/student_url.csv @@ -0,0 +1,2 @@ +Id,Name,url +1,Venus,www.example.com From 871bf740a9ed81d2e7289072d683b817e1ebd1a9 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 9 Jun 2020 10:25:14 +0200 Subject: [PATCH 028/169] wip: feature function #25: RMLFNOTC0021-CSV working --- .../fno-testcases/RMLFNOTC0021-JSON/mapping.ttl | 4 ++-- .../fno-testcases/RMLFNOTC0021-JSON/output.ttl | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl index 79dc1b02..0932eb85 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/mapping.ttl @@ -5,8 +5,8 @@ @prefix rml: . @prefix ql: . @prefix fnml: . -@prefix fno: . -@prefix grel: . +@prefix fno: . +@prefix grel: . @prefix idlab-fn: . @base . diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl index f90ed809..445fac6f 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl +++ b/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl @@ -1,7 +1,7 @@ - . - "John". - . - "Edward". - "Steve". - . - . + . + "John" . + . + "Edward" . + "Steve" . + . + . From c3e8dc7cf174a7a1e53be309caa1f70738083225 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Tue, 9 Jun 2020 11:14:34 +0200 Subject: [PATCH 029/169] wip: feature function #25: RMLFNOTC00{20, 22, 23}-* to failing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RMLFNOTC0020-JSON: requires joins -- currently not supported RMLFNOTC0022-CSV: uses rml:languageMap → not implemented yet RMLFNOTC0023-CSV: term maps with multiple term map types (subjectmap + functionmap) → I don't think that's been implemented yet either --- .../RMLFNOTC0020-JSON/authors.json | 7 ++ .../RMLFNOTC0020-JSON/books.json | 8 ++ .../RMLFNOTC0020-JSON/mapping.ttl | 63 ++++++++++++ .../RMLFNOTC0020-JSON/output.ttl} | 9 +- .../RMLFNOTC0022-CSV/mapping.ttl | 39 ++++++++ .../fno-testcases/RMLFNOTC0022-CSV/output.nq | 3 + .../RMLFNOTC0022-CSV/student.csv | 4 + .../RMLFNOTC0023-CSV/mapping.ttl | 99 +++++++++++++++++++ .../fno-testcases/RMLFNOTC0023-CSV/output.nq | 3 + .../RMLFNOTC0023-CSV/student.csv | 3 + 10 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/authors.json create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/books.json create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/mapping.ttl rename src/test/resources/{fno-testcases/RMLFNOTC0021-JSON/output.ttl.bak => failing/fno-testcases/RMLFNOTC0020-JSON/output.ttl} (59%) create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/mapping.ttl create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/output.nq create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/student.csv create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/output.nq create mode 100644 src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/student.csv diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/authors.json b/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/authors.json new file mode 100644 index 00000000..e2149b02 --- /dev/null +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/authors.json @@ -0,0 +1,7 @@ +{ + "authors": [ + {"name": "John"}, + {"name": "Edward"}, + {"name": "Steve"} + ] +} diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/books.json b/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/books.json new file mode 100644 index 00000000..9856321f --- /dev/null +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/books.json @@ -0,0 +1,8 @@ +{ + "books": [ + {"title": "The adventure of young turtle", "authors": ["John"]}, + {"title": "The big rabbit's trip", "authors": ["Edward", "Steve"]}, + {"title": "A new horizon at the end of the night", "authors": []}, + {"title": "The past comes back in the future"} + ] +} diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/mapping.ttl new file mode 100644 index 00000000..cc73f05e --- /dev/null +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/mapping.ttl @@ -0,0 +1,63 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix idlab-fn: . + +@base . + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "authors.json"; + rml:referenceFormulation ql:JSONPath; + rml:iterator "$.authors[*]" + ]; + + rr:subjectMap [ + rr:template "http://example.com/author/{name}"; + rr:class ex:Author + ]. + + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "books.json"; + rml:referenceFormulation ql:JSONPath; + rml:iterator "$.books[*]" + ]; + + rr:subjectMap [ + rr:template "http://example.com/book/{title}"; + rr:class ex:Book + ]; + + rr:predicateObjectMap [ + rr:predicate ex:writtenBy; + rr:objectMap [ + rr:parentTriplesMap ; + rml:joinCondition [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant idlab-fn:listContainsElement ] + ] ; + rr:predicateObjectMap [ + rr:predicate idlab-fn:list ; + rr:objectMap [ rml:reference "authors"] + ] ; + rr:predicateObjectMap [ + rr:predicate idlab-fn:str ; + rr:objectMap [ rml:parentTermMap [ rml:reference "name"] ] + ] + ] + ] + ] + ]. diff --git a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl.bak b/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/output.ttl similarity index 59% rename from src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl.bak rename to src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/output.ttl index 445fac6f..9056ebab 100644 --- a/src/test/resources/fno-testcases/RMLFNOTC0021-JSON/output.ttl.bak +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0020-JSON/output.ttl @@ -1,7 +1,10 @@ + . + . + . . - "John" . + . . - "Edward" . - "Steve" . + . + . . . diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/mapping.ttl new file mode 100644 index 00000000..682712dc --- /dev/null +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/mapping.ttl @@ -0,0 +1,39 @@ +@prefix rr: . +@prefix foaf: . +@prefix ex: . +@prefix xsd: . +@prefix rml: . +@prefix ql: . +@prefix fnml: . +@prefix grel: . +@prefix fno: . +@base . + + a rr:TriplesMap; + + rml:logicalSource [ + rml:source "fno-testcases/RMLFNOTC0022-CSV/student.csv"; + rml:referenceFormulation ql:CSV + ]; + + rr:subjectMap [ + rr:template "http://example.com/{ID}"; + ]; + + rr:predicateObjectMap [ + rr:predicate ex:name ; + rr:objectMap [ + rml:reference "Name"; + rml:languageMap [ + fnml:functionValue [ + rr:predicateObjectMap [ + rr:predicate fno:executes ; + rr:objectMap [ rr:constant grel:toLowerCase ] ] ; + rr:predicateObjectMap [ + rr:predicate grel:valueParameter ; + rr:objectMap [ rml:reference "lang" ] ] + ] + ] + ] + ]. + diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/output.nq b/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/output.nq new file mode 100644 index 00000000..9b168eab --- /dev/null +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/output.nq @@ -0,0 +1,3 @@ + "Venus"@en . + "Athina"@el . + "Bob"@nl . \ No newline at end of file diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/student.csv b/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/student.csv new file mode 100644 index 00000000..5de0934b --- /dev/null +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0022-CSV/student.csv @@ -0,0 +1,4 @@ +ID,Name,lang +10,Venus,En +20,Athina,EL +30,Bob,nl \ No newline at end of file diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl new file mode 100644 index 00000000..eb3b9f21 --- /dev/null +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/mapping.ttl @@ -0,0 +1,99 @@ +@prefix ex: . +@prefix fnml: . +@prefix fno: . +@prefix grel: . +@prefix idlab-fn: . +@prefix rr: . +@prefix rml: . +@prefix rdf: . +@prefix rdfs: . +@prefix ql: . +@prefix map: . + +map:map_person_0 + rml:logicalSource map:source_0 ; + a rr:TriplesMap ; + rdfs:label "person" ; + rr:subjectMap map:s_0 ; + rr:predicateObjectMap map:pom_2 . + +map:source_0 + a rml:LogicalSource ; + rml:source "fno-testcases/RMLFNOTC0023-CSV/student.csv" ; + rml:referenceFormulation ql:CSV . + +map:s_0 + a rr:SubjectMap, fnml:FunctionTermMap ; + rr:termType rr:IRI ; + fnml:functionValue map:fn_0 . + +map:fn_0 + rml:logicalSource map:source_0 ; + rr:predicateObjectMap map:pomexec_0, map:pom_0, map:pom_1 . + +map:pomexec_0 + rr:predicateMap map:pmexec_0 ; + rr:objectMap map:omexec_0 . + +map:pmexec_0 + rr:constant fno:executes . + +map:omexec_0 + rr:constant "http://users.ugent.be/~bjdmeest/function/grel.ttl#array_join" ; + rr:termType rr:IRI . + +map:pom_0 + a rr:PredicateObjectMap ; + rr:predicateMap map:pm_0 ; + rr:objectMap map:om_0 . + +map:pm_0 + a rr:PredicateMap ; + rr:constant grel:p_array_a . + +map:om_0 + a rr:ObjectMap ; + rr:constant "http://example.com/person/" ; + rr:termType rr:Literal . + +map:pom_1 + a rr:PredicateObjectMap ; + rr:predicateMap map:pm_1 ; + rr:objectMap map:om_1 . + +map:pm_1 + a rr:PredicateMap ; + rr:constant grel:p_array_a . + +map:om_1 + a rr:ObjectMap, fnml:FunctionTermMap ; + fnml:functionValue map:fn_1 . + +map:fn_1 + rml:logicalSource map:source_0 ; + rr:predicateObjectMap map:pomexec_1 . + +map:pomexec_1 + rr:predicateMap map:pmexec_1 ; + rr:objectMap map:omexec_1 . + +map:pmexec_1 + rr:constant fno:executes . + +map:omexec_1 + rr:constant "http://example.com/idlab/function/random" ; + rr:termType rr:IRI . + +map:pom_2 + a rr:PredicateObjectMap ; + rr:predicateMap map:pm_2 ; + rr:objectMap map:om_2 . + +map:pm_2 + a rr:PredicateMap ; + rr:constant rdf:type . + +map:om_2 + a rr:ObjectMap ; + rr:constant "http://xmlns.com/foaf/0.1/Person" ; + rr:termType rr:IRI . diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/output.nq b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/output.nq new file mode 100644 index 00000000..346dc619 --- /dev/null +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/output.nq @@ -0,0 +1,3 @@ + . + + . diff --git a/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/student.csv b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/student.csv new file mode 100644 index 00000000..0e947809 --- /dev/null +++ b/src/test/resources/failing/fno-testcases/RMLFNOTC0023-CSV/student.csv @@ -0,0 +1,3 @@ +name,role +Sven,1 +Ben ,2 From 1c497e3d6b4dabac52170595646646059a377d8a Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Tue, 9 Jun 2020 20:33:44 +0200 Subject: [PATCH 030/169] Perpare for next dev version --- pom.xml | 2 +- src/main/scala/io/rml/framework/flink/util/ParameterUtil.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f75757b2..97427906 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ SOFTWARE. io.rml RMLStreamer - 2.0.0-RELEASE + 2.0.1-SNAPSHOT jar RMLStreamer diff --git a/src/main/scala/io/rml/framework/flink/util/ParameterUtil.scala b/src/main/scala/io/rml/framework/flink/util/ParameterUtil.scala index b782fd0b..6723a55c 100644 --- a/src/main/scala/io/rml/framework/flink/util/ParameterUtil.scala +++ b/src/main/scala/io/rml/framework/flink/util/ParameterUtil.scala @@ -78,7 +78,7 @@ object ParameterUtil { val parser = new scopt.OptionParser[ParameterConfig]("RMLStreamer") { override def showUsageOnError = true - head("RMLStreamer", "1.2.4-SNAPSHOT") + head("RMLStreamer", "2.0.1-SNAPSHOT") opt[String]('j', "job-name").valueName("") .optional() From 41583176786eef6ea9a83f062a69d51f698a7a39 Mon Sep 17 00:00:00 2001 From: Gerald Haesendonck Date: Wed, 10 Jun 2020 08:54:44 +0200 Subject: [PATCH 031/169] Added DOI --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6f790892..aa6842f4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ ## RMLStreamer +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3887065.svg)](https://doi.org/10.5281/zenodo.3887065) The RMLStreamer generates [RDF](https://www.w3.org/2001/sw/wiki/RDF) from files or data streams using [RML](http://rml.io/). The difference with other RML implementations is that it can handle From 2af46141a680b32588c7dd5fc8e31c16899b3475 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 11 Jun 2020 14:31:01 +0200 Subject: [PATCH 032/169] wip: feature function #25 cleaning up code and some renaming because we are about to integrate the new version of FnO. - Replaced "transformation" with "function" - Deleted code that was commented out - replaced some of the logInfo's to logDebugs --- src/main/scala/io/rml/framework/Main.scala | 4 +- .../extractors/FunctionMapExtractor.scala | 69 +------------------ .../core/extractors/MappingExtractor.scala | 4 +- .../std/StdFunctionMapExtractor.scala | 4 +- .../std/StdObjectMapExtractor.scala | 17 +---- .../std/StdPredicateObjectMapExtractor.scala | 12 ++-- .../StdTransformationMappingExtractor.scala | 15 ++-- ...ationLoader.scala => FunctionLoader.scala} | 44 ++++++------ ...rmationUtils.scala => FunctionUtils.scala} | 6 +- ...tion.scala => DynamicMethodFunction.scala} | 16 ++--- .../{Transformation.scala => Function.scala} | 14 ++-- ...nMetaData.scala => FunctionMetaData.scala} | 13 ++-- ...ormation.scala => StdRandomFunction.scala} | 4 +- ...ation.scala => StdUpperCaseFunction.scala} | 4 +- ...onLoader.scala => StdFunctionLoader.scala} | 24 +++---- ...ionMapping.scala => FunctionMapping.scala} | 21 +++--- .../core/model/std/StdFunctionMapping.scala | 7 ++ .../model/std/StdTransformationMapping.scala | 7 -- .../FunctionMapGeneratorAssembler.scala | 18 ++--- .../statement/ObjectGeneratorAssembler.scala | 4 +- .../PredicateGeneratorAssembler.scala | 4 +- .../PredicateObjectGeneratorAssembler.scala | 2 +- .../engine/statement/StatementEngine.scala | 2 +- .../statement/StatementsAssembler.scala | 2 +- .../statement/SubjectGeneratorAssembler.scala | 4 +- .../rml/framework/OutputGenerationTest.scala | 4 +- .../scala/io/rml/framework/SandboxTests.scala | 6 +- .../model/function/FunctionLoaderTest.scala | 22 +++--- 28 files changed, 138 insertions(+), 215 deletions(-) rename src/main/scala/io/rml/framework/core/function/{TransformationLoader.scala => FunctionLoader.scala} (56%) rename src/main/scala/io/rml/framework/core/function/{TransformationUtils.scala => FunctionUtils.scala} (93%) rename src/main/scala/io/rml/framework/core/function/model/{DynamicMethodTransformation.scala => DynamicMethodFunction.scala} (79%) rename src/main/scala/io/rml/framework/core/function/model/{Transformation.scala => Function.scala} (52%) rename src/main/scala/io/rml/framework/core/function/model/{TransformationMetaData.scala => FunctionMetaData.scala} (61%) rename src/main/scala/io/rml/framework/core/function/model/std/{StdRandomTransformation.scala => StdRandomFunction.scala} (72%) rename src/main/scala/io/rml/framework/core/function/model/std/{StdUpperCaseTransformation.scala => StdUpperCaseFunction.scala} (73%) rename src/main/scala/io/rml/framework/core/function/std/{StdTransformationLoader.scala => StdFunctionLoader.scala} (67%) rename src/main/scala/io/rml/framework/core/model/{TransformationMapping.scala => FunctionMapping.scala} (50%) create mode 100644 src/main/scala/io/rml/framework/core/model/std/StdFunctionMapping.scala delete mode 100644 src/main/scala/io/rml/framework/core/model/std/StdTransformationMapping.scala diff --git a/src/main/scala/io/rml/framework/Main.scala b/src/main/scala/io/rml/framework/Main.scala index 20008055..ac8d931b 100644 --- a/src/main/scala/io/rml/framework/Main.scala +++ b/src/main/scala/io/rml/framework/Main.scala @@ -374,7 +374,7 @@ object Main extends Logging { senv: StreamExecutionEnvironment, postProcessor: PostProcessor): DataSet[String] = { - this.logInfo("createDataSetFromFormattedMapping(...)") + this.logDebug("createDataSetFromFormattedMapping(...)") require(!postProcessor.isInstanceOf[AtMostOneProcessor], "Bulk output and JSON-LD output are not supported in the static version") /** @@ -420,7 +420,7 @@ object Main extends Logging { (implicit env: ExecutionEnvironment, senv: StreamExecutionEnvironment, postProcessor: PostProcessor): DataSet[String] = { - this.logInfo("createStandardTriplesMapPipeline(standard triples maps..)") + this.logDebug("createStandardTriplesMapPipeline(standard triples maps..)") // group triple maps by logical sources val grouped = standardTriplesMaps.groupBy(triplesMap => triplesMap.logicalSource) diff --git a/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala index 28cd98ff..126922cb 100644 --- a/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/FunctionMapExtractor.scala @@ -25,10 +25,8 @@ package io.rml.framework.core.extractors import io.rml.framework.core.extractors.std.{StdFunctionMapExtractor, TermMapExtractor} -import io.rml.framework.core.model.rdf.{RDFLiteral, RDFResource} -import io.rml.framework.core.model.{FunctionMap, Uri} -import io.rml.framework.core.vocabulary.RMLVoc -import io.rml.framework.shared.RMLException +import io.rml.framework.core.model.FunctionMap +import io.rml.framework.core.model.rdf.RDFResource trait FunctionMapExtractor extends TermMapExtractor[List[FunctionMap]] { /** @@ -56,66 +54,3 @@ object FunctionMapExtractor { } } -//case class FunctionMapExtractor() extends ResourceExtractor[List[FunctionMap]] { -// -// lazy val triplesMapExtractor: TriplesMapExtractor = TriplesMapExtractor() -// -// /** -// * Extract. -// * -// * @param node Node to extract from. -// * @return -// */ -// override def extract(node: RDFResource): List[FunctionMap] = { -// -// -// val properties = node.listProperties(RMLVoc.Property.OBJECTMAP) // : Seq[RDFNode] -// -// -// /** -// * Note: object-maps pointing to a resource with type fnml:FunctionTermMap are matched as FunctionTermMaps. -// * However, it's not always the case that resource are explicitely defined as " a fnml:FunctionTermMap". -// * Therefore, a resource should also be considered a FunctionTermMap when it points to a -// * resource with a fnml:functionValue property. -// * -// * TODO: what's the type of properties element when not explicitly defining functiontermmap type -// * --> it turns out that resource.getType is None when not explicitely defining the function term map type -// */ -// -// properties.flatMap { -// case literal: RDFLiteral => -// throw new RMLException(literal.toString + -// ": A literal cannot be converted to a predicate object map") -// -// case resource: RDFResource => -// resource.getType match { -// case Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)) => Some(extractFunctionMap(resource)) -// case _ => { -// // if resource hasn't a type specified, check whether it has the function value property -// val functionValueProperties = resource.listProperties(Uri(RMLVoc.Property.FUNCTIONVALUE).toString) -// if(functionValueProperties.nonEmpty) -// Some(extractFunctionMap(resource)) -// else -// None -// } -// } -// } -// } -// -// private def extractFunctionMap(resource: RDFResource): FunctionMap = { -// logInfo("%s extractFunctionMap ".format(this.getClass.getName)) -// val functionValues = resource.listProperties(RMLVoc.Property.FUNCTIONVALUE) -// -// // TODO: [SUGGESTION] extract function map requirement checking into private method to separate extraction from -// // validating the spec-rules -- thoughts? -// require(functionValues.size == 1, "Only 1 function value allowed.") -// require(functionValues.head.isInstanceOf[RDFResource], "FunctionValue must be a resource.") -// -// val functionValue = functionValues.head.asInstanceOf[RDFResource] -// val triplesMap = triplesMapExtractor.extractTriplesMapProperties(functionValue) -// require(triplesMap.isDefined) -// //FunctionMap(functionValue.uri.toString, triplesMap.get) -// throw new NotImplementedError() -// } -// -//} diff --git a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala index aa397189..d19d5471 100644 --- a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala @@ -26,7 +26,7 @@ package io.rml.framework.core.extractors import io.rml.framework.core.extractors.std.{StdFunctionMapExtractor, StdMappingExtractor, StdTransformationMappingExtractor} -import io.rml.framework.core.model.{Graph, RMLMapping, TransformationMapping} +import io.rml.framework.core.model.{Graph, RMLMapping, FunctionMapping} trait MappingExtractor [+T<: Graph]extends GraphExtractor[T] @@ -38,7 +38,7 @@ object MappingExtractor { def apply [T<:Graph](cls: Any): MappingExtractor[Graph] = { cls match{ case RMLMapping => new StdMappingExtractor() - case TransformationMapping => new StdTransformationMappingExtractor() + case FunctionMapping => new StdTransformationMappingExtractor() case _ => throw new IllegalArgumentException("Given args can only be subclasses of Mapping") } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala index a2df75ad..dd569fbf 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMapExtractor.scala @@ -21,7 +21,7 @@ class StdFunctionMapExtractor(subjectMapExtractor: SubjectMapExtractor, * @return */ override def extract(node: RDFResource): List[FunctionMap] = { - this.logInfo("%s extract(node)".format(this.getClass.getName)) + this.logDebug("%s extract(node)".format(this.getClass.getName)) extractFunctionMap("", node) } @@ -43,7 +43,7 @@ class StdFunctionMapExtractor(subjectMapExtractor: SubjectMapExtractor, val poms = pomExtractor.extract(functionValue) FunctionMap(fnParentMap, functionValue.uri.toString, poms) - //throw new NotImplementedError() + }) result diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala index f1922640..be3c2fb5 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdObjectMapExtractor.scala @@ -69,7 +69,7 @@ class StdObjectMapExtractor(stdFunctionMapExtractor: FunctionMapExtractor) exten * @return */ private def extractObjectMaps(resource: RDFResource): List[ObjectMap] = { - this.logInfo("%s extractObjectMaps(resource)".format(this.getClass.getName)) + this.logDebug("%s extractObjectMaps(resource)".format(this.getClass.getName)) val property = RMLVoc.Property.OBJECTMAP val properties = resource.listProperties(property) @@ -80,21 +80,6 @@ class StdObjectMapExtractor(stdFunctionMapExtractor: FunctionMapExtractor) exten case resource: RDFResource => Some(extractObjectMap(resource)) } - // TODO: safe to delete? - // //case resource: RDFResource => Some(extractObjectMap(resource)) - // case resource: RDFResource => { - // // if resource hasn't a type specified, check whether it has the function value property - // val functionValueProperties = resource.listProperties(Uri(RMLVoc.Property.FUNCTIONVALUE).toString) - // if(functionValueProperties.nonEmpty | resource.getType.eq(Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)))) - // None - // else - // Some(extractObjectMap(resource)) - // } - // // case resource.getType match { - // // case Some(Uri(RMLVoc.Class.FUNCTIONTERMMAP)) => None // TODO: rethink this - // // case _ => Some(extractObjectMap(resource)) - // // } - // } } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala index aa88ae4b..1d1f2f7f 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdPredicateObjectMapExtractor.scala @@ -73,19 +73,19 @@ class StdPredicateObjectMapExtractor(predicateMapExtractor: PredicateMapExtracto * @return */ private def extractPredicateObjectMap(resource: RDFResource): PredicateObjectMap = { - this.logInfo("%s extractPredicateObjectMap : extracting object maps".format(this.getClass.getName)) + this.logDebug("%s extractPredicateObjectMap : extracting object maps".format(this.getClass.getName)) val objectMaps = objectMapExtractor.extract(resource) - this.logInfo("%s extractPredicateObjectMap : extracting function maps".format(this.getClass.getName)) - val functionMaps = functionMapExtractor.extract(resource) + this.logDebug("%s extractPredicateObjectMap : extracting function maps".format(this.getClass.getName)) + val functionMaps = functionMapExtractor.extract(resource) // TODO: not used. can be removed? - this.logInfo("%s extractPredicateObjectMap : extracting predicate maps".format(this.getClass.getName)) + this.logDebug("%s extractPredicateObjectMap : extracting predicate maps".format(this.getClass.getName)) val predicateMaps = predicateMapExtractor.extract(resource) - this.logInfo("%s extractPredicateObjectMap : extracting graph map".format(this.getClass.getName)) + this.logDebug("%s extractPredicateObjectMap : extracting graph map".format(this.getClass.getName)) val graphMap = graphMapExtractor.extract(resource) - this.logInfo("%s extractPredicateObjectMap : returning resulting PredicateObjectMap".format(this.getClass.getName)) + this.logDebug("%s extractPredicateObjectMap : returning resulting PredicateObjectMap".format(this.getClass.getName)) PredicateObjectMap(resource.uri.toString, objectMaps, predicateMaps, graphMap) } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala index 3d4915ef..750bc4b5 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala @@ -1,22 +1,23 @@ package io.rml.framework.core.extractors.std import io.rml.framework.core.extractors.MappingExtractor -import io.rml.framework.core.function.TransformationLoader -import io.rml.framework.core.model.TransformationMapping +import io.rml.framework.core.function.FunctionLoader +import io.rml.framework.core.model.FunctionMapping import io.rml.framework.core.model.rdf.RDFGraph -class StdTransformationMappingExtractor extends MappingExtractor[TransformationMapping] { +//TODO: to be consistent with the terminology, Function should be replaced with Function +class StdTransformationMappingExtractor extends MappingExtractor[FunctionMapping] { /** * Extract. * * @param node Node to extract from. * @return */ - override def extract(node: RDFGraph): TransformationMapping = { - val loader = TransformationLoader() + override def extract(node: RDFGraph): FunctionMapping = { + val loader = FunctionLoader() - loader.parseTransformations(node) + loader.parseFunctions(node) - TransformationMapping("defaulty", loader) + FunctionMapping("defaulty", loader) } } diff --git a/src/main/scala/io/rml/framework/core/function/TransformationLoader.scala b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala similarity index 56% rename from src/main/scala/io/rml/framework/core/function/TransformationLoader.scala rename to src/main/scala/io/rml/framework/core/function/FunctionLoader.scala index abf66ab8..cca2e899 100644 --- a/src/main/scala/io/rml/framework/core/function/TransformationLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionLoader.scala @@ -3,8 +3,8 @@ package io.rml.framework.core.function import java.io.File import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.model.{DynamicMethodTransformation, Parameter, Transformation, TransformationMetaData} -import io.rml.framework.core.function.std.StdTransformationLoader +import io.rml.framework.core.function.model.{DynamicMethodFunction, Parameter, Function, FunctionMetaData} +import io.rml.framework.core.function.std.StdFunctionLoader import io.rml.framework.core.internal.Logging import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode} @@ -13,7 +13,7 @@ import io.rml.framework.core.util.Turtle import scala.collection.immutable.{Map => ImmutableMap} import scala.collection.mutable.{Map => MutableMap} -abstract class TransformationLoader extends Logging { +abstract class FunctionLoader extends Logging { /** * Map string value of classes to library path */ @@ -21,54 +21,54 @@ abstract class TransformationLoader extends Logging { /** - * Map names of [[Transformation]] to concrete [[Transformation]] object + * Map names of [[Function]] to concrete [[Function]] object */ - protected val transformationMap: MutableMap[Uri, TransformationMetaData] = MutableMap() + protected val functionMap: MutableMap[Uri, FunctionMetaData] = MutableMap() def getClassLibraryMap: ImmutableMap[String, String] = classLibraryMap.toMap - def getTransformationMap = transformationMap.toMap + def getFunctionMap = functionMap.toMap - def parseTransformations(file: File): TransformationLoader = { + def parseFunctions(file: File): FunctionLoader = { //TODO: passing hardcoding Turtle-format. // HELP: shouldn't we derive the format from the file itself? val graph = RDFGraph.fromFile(file, RMLEnvironment.getGeneratorBaseIRI(),Turtle) - parseTransformations(graph) + parseFunctions(graph) this } /** - * Given the [[Uri]] representation of the transformation, the [[TransformationLoader]] - * will search for the transformation in the [[transformationMap]] and dynamically load + * Given the [[Uri]] representation of the transformation, the [[FunctionLoader]] + * will search for the transformation in the [[functionMap]] and dynamically load * the transformation. * * @param uri Uri representing a transformation * @return [[Option]] of dynamically loaded transformation */ - def loadTransformation(uri: Uri): Option[Transformation] = { - logInfo(s"loadTransformation: ${uri.uri}") + def loadFunction(uri: Uri): Option[Function] = { + logDebug(s"loadFunction: ${uri.uri}") - val optTransformation = transformationMap.get(uri) + val optTransformation = functionMap.get(uri) if (optTransformation.isDefined) { val trans = optTransformation.get - logInfo(s"Dynamically loading transformation: $uri, ${trans.toString}" ) + logDebug(s"Dynamically loading function: $uri, ${trans.toString}" ) trans match { - case transformationMetaData: TransformationMetaData => { + case transformationMetaData: FunctionMetaData => { // val loadedTrans = transient.initialize() - // transformationMap.put(uri, loadedTrans) + // functionMap.put(uri, loadedTrans) // Some(loadedTrans) - Some(Transformation(transformationMetaData.identifier, transformationMetaData)) + Some(Function(transformationMetaData.identifier, transformationMetaData)) } - case loadedTrans: DynamicMethodTransformation => Some(loadedTrans) + case loadedFunction: DynamicMethodFunction => Some(loadedFunction) case _ => None } @@ -81,9 +81,9 @@ abstract class TransformationLoader extends Logging { * Parse transformations from the [[RDFGraph]] of the whole function mapping file. * * @param graph [[RDFGraph]] representing the whole function mapping file - * @return [[TransformationLoader]] + * @return [[FunctionLoader]] */ - def parseTransformations(graph: RDFGraph): TransformationLoader + def parseFunctions(graph: RDFGraph): FunctionLoader /** @@ -97,9 +97,9 @@ abstract class TransformationLoader extends Logging { } -object TransformationLoader { +object FunctionLoader { - def apply(): TransformationLoader = StdTransformationLoader() + def apply(): FunctionLoader = StdFunctionLoader() } diff --git a/src/main/scala/io/rml/framework/core/function/TransformationUtils.scala b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala similarity index 93% rename from src/main/scala/io/rml/framework/core/function/TransformationUtils.scala rename to src/main/scala/io/rml/framework/core/function/FunctionUtils.scala index 036fb452..507afec1 100644 --- a/src/main/scala/io/rml/framework/core/function/TransformationUtils.scala +++ b/src/main/scala/io/rml/framework/core/function/FunctionUtils.scala @@ -12,7 +12,7 @@ import io.rml.framework.shared.RMLException import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader -object TransformationUtils extends Logging { +object FunctionUtils extends Logging { /** * @@ -34,10 +34,10 @@ object TransformationUtils extends Logging { * @return */ def loadClassFromJar(jarFile: File, className: String): Class[_] = { - logInfo(s"Loading $className from jar file $jarFile") + logDebug(s"Loading $className from jar file $jarFile") try { val classloader = new URLClassLoader(List(jarFile.toURI.toURL), RMLEnvironment.getClass.getClassLoader) - logInfo(s"Class loader ${classloader.getParent}") + logDebug(s"Class loader ${classloader.getParent}") Class.forName(className, true, classloader) } catch { case e@(_: MalformedURLException | _: ClassNotFoundException) => diff --git a/src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala b/src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala similarity index 79% rename from src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala rename to src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala index 0783d002..4f656d5c 100644 --- a/src/main/scala/io/rml/framework/core/function/model/DynamicMethodTransformation.scala +++ b/src/main/scala/io/rml/framework/core/function/model/DynamicMethodFunction.scala @@ -3,18 +3,18 @@ package io.rml.framework.core.function.model import java.io.{File, IOException, ObjectInputStream, ObjectOutputStream} import java.lang.reflect.Method -import io.rml.framework.core.function.TransformationUtils +import io.rml.framework.core.function.FunctionUtils import io.rml.framework.core.model.{Entity, Literal, Uri} /** * A dynamic transformer which will use the functions of a class specified in an external jar - * The information needed to do reflection is contained inside the variable 'transientTransformation' of type [[TransformationMetaData]] + * The information needed to do reflection is contained inside the variable 'transientTransformation' of type [[FunctionMetaData]] * * @param identifier [[String]] used to identify this DynamicTransformation * @param metaData contains information required for method reflection */ -case class DynamicMethodTransformation(identifier: String, metaData: TransformationMetaData) extends Transformation { +case class DynamicMethodFunction(identifier: String, metaData: FunctionMetaData) extends Function { @transient private var optMethod: Option[Method] = None @@ -24,14 +24,14 @@ case class DynamicMethodTransformation(identifier: String, metaData: Transformat out.defaultWriteObject() } - override def initialize(): Transformation = { - logInfo("intializing transformation (identifier: %s)".format(this.identifier)) + override def initialize(): Function = { + logDebug("intializing function (identifier: %s)".format(this.identifier)) if(optMethod.isEmpty) { - logInfo("optMethod is empty -> loading method from jar %s".format(metaData.source)) + logDebug("optMethod is empty -> loading method from jar %s".format(metaData.source)) val jarFile = getClass.getClassLoader.getResource(metaData.source.toString).getFile - val classOfMethod = TransformationUtils.loadClassFromJar(new File(jarFile), metaData.className) + val classOfMethod = FunctionUtils.loadClassFromJar(new File(jarFile), metaData.className) val method = classOfMethod.getDeclaredMethod(metaData.methodName, metaData.inputParam.map(_.paramType): _*) optMethod = Some(method) } @@ -48,7 +48,7 @@ case class DynamicMethodTransformation(identifier: String, metaData: Transformat } override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { - logInfo("execute") + logDebug("execute") if (optMethod.isEmpty) { throw new IllegalStateException(s"DynamicTransformation doesn't have the reflected method yet: ${this.identifier}") } diff --git a/src/main/scala/io/rml/framework/core/function/model/Transformation.scala b/src/main/scala/io/rml/framework/core/function/model/Function.scala similarity index 52% rename from src/main/scala/io/rml/framework/core/function/model/Transformation.scala rename to src/main/scala/io/rml/framework/core/function/model/Function.scala index aabc3083..6373dea3 100644 --- a/src/main/scala/io/rml/framework/core/function/model/Transformation.scala +++ b/src/main/scala/io/rml/framework/core/function/model/Function.scala @@ -4,7 +4,7 @@ import java.lang.reflect.Method import io.rml.framework.core.model.{Entity, Node, Uri} import io.rml.framework.core.internal.Logging -trait Transformation extends Node with Logging{ +trait Function extends Node with Logging{ def name: Uri = Uri(identifier) @@ -15,17 +15,17 @@ trait Transformation extends Node with Logging{ // it currently only support string representable outputs! def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] - def initialize(): Transformation = { - logInfo("initializing transformation") + def initialize(): Function = { + logDebug("initializing Function") this } } -object Transformation extends Logging{ +object Function extends Logging{ - def apply(identifier:String, transformationMetaData: TransformationMetaData): Transformation={ - logInfo("Companion: Transformation - apply(identifier, transformationMetaData)") - DynamicMethodTransformation(identifier, transformationMetaData) + def apply(identifier:String, functionMetaData: FunctionMetaData): Function={ + logDebug("Companion: Function - apply(identifier, functionMetaData)") + DynamicMethodFunction(identifier, functionMetaData) } } diff --git a/src/main/scala/io/rml/framework/core/function/model/TransformationMetaData.scala b/src/main/scala/io/rml/framework/core/function/model/FunctionMetaData.scala similarity index 61% rename from src/main/scala/io/rml/framework/core/function/model/TransformationMetaData.scala rename to src/main/scala/io/rml/framework/core/function/model/FunctionMetaData.scala index fa906305..dbf0e779 100644 --- a/src/main/scala/io/rml/framework/core/function/model/TransformationMetaData.scala +++ b/src/main/scala/io/rml/framework/core/function/model/FunctionMetaData.scala @@ -6,15 +6,16 @@ import io.rml.framework.core.model.{Entity, Uri} /** * A case class which is made to hold the string values of class and method names - * of a [[Transformation]] so that it can be initialized lazily later when needed in the rml mapping file + * of a [[Function]] so that it can be initialized lazily later when needed in the rml mapping file * [Dev note ~ SMO] Only contains string data like, function name, class name, source jar file name + * * @param source string path of the source - * @param className class name containing the [[Transformation]] - * @param methodName method name of the [[Transformation]] - * @param inputParam [[List]] of input parameters for the [[Transformation]] - * @param outputParam [[List]] of expected output parameters from the [[Transformation]] + * @param className class name containing the [[Function]] + * @param methodName method name of the [[Function]] + * @param inputParam [[List]] of input parameters for the [[Function]] + * @param outputParam [[List]] of expected output parameters from the [[Function]] */ -case class TransformationMetaData(source: String, className: String, methodName: String, inputParam: List[Parameter], outputParam: List[Parameter]) extends { +case class FunctionMetaData(source: String, className: String, methodName: String, inputParam: List[Parameter], outputParam: List[Parameter]) extends { /** * Used as an id for each inheriting objects for debugging ( maybe equivalence checking? e.g. in TermMap and TripleMap). diff --git a/src/main/scala/io/rml/framework/core/function/model/std/StdRandomTransformation.scala b/src/main/scala/io/rml/framework/core/function/model/std/StdRandomFunction.scala similarity index 72% rename from src/main/scala/io/rml/framework/core/function/model/std/StdRandomTransformation.scala rename to src/main/scala/io/rml/framework/core/function/model/std/StdRandomFunction.scala index 38ba6e31..76c4dd24 100644 --- a/src/main/scala/io/rml/framework/core/function/model/std/StdRandomTransformation.scala +++ b/src/main/scala/io/rml/framework/core/function/model/std/StdRandomFunction.scala @@ -2,13 +2,13 @@ package io.rml.framework.core.function.model.std import java.lang.reflect.Method -import io.rml.framework.core.function.model.Transformation +import io.rml.framework.core.function.model.Function import io.rml.framework.core.model.{Entity, Literal, Uri} import io.rml.framework.core.vocabulary.RMLVoc import scala.util.Random -case class StdRandomTransformation(identifier:String = RMLVoc.Property.GREL_RANDOM) extends Transformation{ +case class StdRandomFunction(identifier:String = RMLVoc.Property.GREL_RANDOM) extends Function{ private val random = new Random() override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { diff --git a/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseTransformation.scala b/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseFunction.scala similarity index 73% rename from src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseTransformation.scala rename to src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseFunction.scala index e2d1bd87..e21ca4d1 100644 --- a/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseTransformation.scala +++ b/src/main/scala/io/rml/framework/core/function/model/std/StdUpperCaseFunction.scala @@ -2,11 +2,11 @@ package io.rml.framework.core.function.model.std import java.lang.reflect.Method -import io.rml.framework.core.function.model.Transformation +import io.rml.framework.core.function.model.Function import io.rml.framework.core.model.{Entity, Literal, Uri} import io.rml.framework.core.vocabulary.{Namespaces, RMLVoc} -case class StdUpperCaseTransformation(identifier: String = RMLVoc.Property.GREL_UPPERCASE) extends Transformation { +case class StdUpperCaseFunction(identifier: String = RMLVoc.Property.GREL_UPPERCASE) extends Function { override def execute(arguments: Map[Uri, String]): Option[Iterable[Entity]] = { val parameter = arguments.get(Uri(Namespaces("grel", "valueParameter"))) diff --git a/src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala similarity index 67% rename from src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala rename to src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala index 6956a3c1..e0ef2151 100644 --- a/src/main/scala/io/rml/framework/core/function/std/StdTransformationLoader.scala +++ b/src/main/scala/io/rml/framework/core/function/std/StdFunctionLoader.scala @@ -1,21 +1,21 @@ package io.rml.framework.core.function.std -import io.rml.framework.core.function.model.{Parameter, TransformationMetaData} -import io.rml.framework.core.function.{TransformationLoader, TransformationUtils} +import io.rml.framework.core.function.model.{Parameter, FunctionMetaData} +import io.rml.framework.core.function.{FunctionLoader, FunctionUtils} import io.rml.framework.core.model.Uri import io.rml.framework.core.model.rdf.jena.JenaResource import io.rml.framework.core.model.rdf.{RDFGraph, RDFNode, RDFResource} import io.rml.framework.core.util.{JenaUtil, Util} import io.rml.framework.core.vocabulary.RMLVoc -case class StdTransformationLoader() extends TransformationLoader { +case class StdFunctionLoader() extends FunctionLoader { - override def parseTransformations(graph: RDFGraph): TransformationLoader = { - val transformationMaps = graph.filterProperties(Uri(RMLVoc.Property.LIB_PROVIDED_BY)) - logInfo("found %d transformation maps".format( transformationMaps.length)) + override def parseFunctions(graph: RDFGraph): FunctionLoader = { + val functionMaps = graph.filterProperties(Uri(RMLVoc.Property.LIB_PROVIDED_BY)) + logDebug("found %d transformation maps".format( functionMaps.length)) - for (map <- transformationMaps) { + for (map <- functionMaps) { val providedByTermMap = map.listProperties(RMLVoc.Property.LIB_PROVIDED_BY).head.asInstanceOf[RDFResource] @@ -23,26 +23,26 @@ case class StdTransformationLoader() extends TransformationLoader { val classNames = providedByTermMap.listProperties(RMLVoc.Property.LIB_CLASS).flatMap(Util.getLiteral) val methodNames = providedByTermMap.listProperties(RMLVoc.Property.LIB_METHOD).flatMap(Util.getLiteral) - logInfo("\t" + "lib path: %s".format(libPath)) + logDebug("\t" + "lib path: %s".format(libPath)) if (libPath.nonEmpty && classNames.nonEmpty && methodNames.nonEmpty) { val classNameLit = classNames.head val methodNameLit = methodNames.head classLibraryMap.put(classNameLit.toString.trim, libPath.get.toString.trim) - logInfo("\t\t" + "class: %s - method: %s".format(classNameLit, methodNameLit)) + logDebug("\t\t" + "class: %s - method: %s".format(classNameLit, methodNameLit)) val inputParams = parseParameterList(map, RMLVoc.Property.FNO_EXPECTS).sorted val outputParams = parseParameterList(map, RMLVoc.Property.FNO_RETURNS).sorted - val transformationMetaData = TransformationMetaData(libPath.get.toString.trim, classNameLit.toString.trim, + val functionMetaData = FunctionMetaData(libPath.get.toString.trim, classNameLit.toString.trim, methodNameLit.toString.trim, inputParams, outputParams ) - transformationMap.put(map.uri, transformationMetaData) + functionMap.put(map.uri, functionMetaData) } } @@ -60,7 +60,7 @@ case class StdTransformationLoader() extends TransformationLoader { val inputResource = inputNode.asInstanceOf[JenaResource] val paramType = inputResource.listProperties(RMLVoc.Property.FNO_TYPE).head.toString val paramUri = inputResource.listProperties(RMLVoc.Property.FNO_PREDICATE).head.toString - val typeClass = TransformationUtils.getTypeClass(Uri(paramType)) + val typeClass = FunctionUtils.getTypeClass(Uri(paramType)) Parameter(typeClass, Uri(paramUri), pos) } } diff --git a/src/main/scala/io/rml/framework/core/model/TransformationMapping.scala b/src/main/scala/io/rml/framework/core/model/FunctionMapping.scala similarity index 50% rename from src/main/scala/io/rml/framework/core/model/TransformationMapping.scala rename to src/main/scala/io/rml/framework/core/model/FunctionMapping.scala index ec693b4b..73c4eb02 100644 --- a/src/main/scala/io/rml/framework/core/model/TransformationMapping.scala +++ b/src/main/scala/io/rml/framework/core/model/FunctionMapping.scala @@ -1,16 +1,17 @@ package io.rml.framework.core.model -import io.rml.framework.core.function.TransformationLoader -import io.rml.framework.core.model.std.StdTransformationMapping +import io.rml.framework.core.function.FunctionLoader +import io.rml.framework.core.model.std.StdFunctionMapping -trait TransformationMapping extends Graph { + +trait FunctionMapping extends Graph { /** * A transformation loader object which contains information * in the mapping document to load function dynamically. * * Note: Functions are not loaded from the libraries - * at the moment of initialization of the [[TransformationLoader]]. + * at the moment of initialization of the [[FunctionLoader]]. * It only has information on library path and classes containing * the function. * Functions will be loaded on demand when reading through the @@ -18,24 +19,24 @@ trait TransformationMapping extends Graph { * * @return */ - def transformationLoader: TransformationLoader + def functionLoader: FunctionLoader } -object TransformationMapping { +object FunctionMapping { //TODO: Temporary solution to passing the mapping object to function map extractors! // Need refactoring! - private var mapping: Option[TransformationMapping] = None + private var mapping: Option[FunctionMapping] = None - def getOpt: Option[TransformationMapping] = { + def getOpt: Option[FunctionMapping] = { mapping } - def apply(identifier: String, transformationLoader: TransformationLoader): TransformationMapping = { - val defMapping = StdTransformationMapping(identifier, transformationLoader) + def apply(identifier: String, functionLoader: FunctionLoader): FunctionMapping = { + val defMapping = StdFunctionMapping(identifier, functionLoader) mapping = Some(defMapping) defMapping diff --git a/src/main/scala/io/rml/framework/core/model/std/StdFunctionMapping.scala b/src/main/scala/io/rml/framework/core/model/std/StdFunctionMapping.scala new file mode 100644 index 00000000..7a21f235 --- /dev/null +++ b/src/main/scala/io/rml/framework/core/model/std/StdFunctionMapping.scala @@ -0,0 +1,7 @@ +package io.rml.framework.core.model.std + +import io.rml.framework.core.function.FunctionLoader +import io.rml.framework.core.model.FunctionMapping + +case class StdFunctionMapping(identifier: String, functionLoader: FunctionLoader) extends FunctionMapping { +} diff --git a/src/main/scala/io/rml/framework/core/model/std/StdTransformationMapping.scala b/src/main/scala/io/rml/framework/core/model/std/StdTransformationMapping.scala deleted file mode 100644 index 0d1109cb..00000000 --- a/src/main/scala/io/rml/framework/core/model/std/StdTransformationMapping.scala +++ /dev/null @@ -1,7 +0,0 @@ -package io.rml.framework.core.model.std - -import io.rml.framework.core.function.TransformationLoader -import io.rml.framework.core.model.TransformationMapping - -case class StdTransformationMapping(identifier: String, transformationLoader: TransformationLoader) extends TransformationMapping { -} diff --git a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala index 7af215e0..48792dbe 100644 --- a/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/FunctionMapGeneratorAssembler.scala @@ -25,7 +25,7 @@ package io.rml.framework.engine.statement import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.model.Transformation +import io.rml.framework.core.function.model.Function import io.rml.framework.core.model._ import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item @@ -55,9 +55,9 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { private def parseFunction(assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): - Transformation = { + Function = { - this.logInfo("parseFunction (assembledPom)") + this.logDebug("parseFunction (assembledPom)") val placeHolder: List[FlinkRDFQuad] = generateFunctionTriples(new EmptyItem(), assembledPom) val executeProperties = placeHolder.filter( quad => quad.predicate.value == Uri(RMLVoc.Property.EXECUTES)) @@ -73,13 +73,13 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { .toString) //throw new NotImplementedError() - val transformationMapping = TransformationMapping + val functionMapping = FunctionMapping .getOpt - .getOrElse( throw new IllegalStateException("Transformation mapping hasn't been read/init yet")) + .getOrElse( throw new IllegalStateException("Function mapping hasn't been read/init yet")) - transformationMapping - .transformationLoader - .loadTransformation(functionName) + functionMapping + .functionLoader + .loadFunction(functionName) .getOrElse(throw new IllegalStateException(s"Function $functionName doesn't exist")) } @@ -90,7 +90,7 @@ case class FunctionMapGeneratorAssembler() extends TermMapGeneratorAssembler { * @param assembledPom List of predicate object generator functions * @return anon function taking in [[Item]] and returns entities using the function */ - private def createAssemblerFunction(function: Transformation, assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Item => Option[Iterable[Entity]] = { + private def createAssemblerFunction(function: Function, assembledPom: List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]])]): Item => Option[Iterable[Entity]] = { (item: Item) => { val triples: List[FlinkRDFQuad] = generateFunctionTriples(item, assembledPom) val args: Map[Uri, String] = triples.filter(triple => triple.predicate.uri != Uri(RMLVoc.Property.EXECUTES)) diff --git a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala index 0973fc5a..adeb2487 100644 --- a/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/ObjectGeneratorAssembler.scala @@ -25,7 +25,7 @@ package io.rml.framework.engine.statement -import io.rml.framework.core.function.TransformationUtils +import io.rml.framework.core.function.FunctionUtils import io.rml.framework.core.model.{Entity, Literal, ObjectMap, Uri} import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item @@ -45,7 +45,7 @@ class ObjectGeneratorAssembler extends TermMapGeneratorAssembler { termTypeString match { case RMLVoc.Class.IRI => item.map(iter => iter.map(elem => Uri(elem.toString))) case _ => item.map(iter => iter.flatMap(elem => { - //val castedResult = TransformationUtils.typeCastDataType(elem, objectMap.datatype) + //val castedResult = FunctionUtils.typeCastDataType(elem, objectMap.datatype) //castedResult.map(v => Literal(v.toString, objectMap.datatype, objectMap.language)) Some(Literal(elem.identifier, objectMap.datatype, objectMap.language)) })) diff --git a/src/main/scala/io/rml/framework/engine/statement/PredicateGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/PredicateGeneratorAssembler.scala index 4ec05927..e20f27e9 100644 --- a/src/main/scala/io/rml/framework/engine/statement/PredicateGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/PredicateGeneratorAssembler.scala @@ -25,7 +25,7 @@ package io.rml.framework.engine.statement -import io.rml.framework.core.function.TransformationUtils +import io.rml.framework.core.function.FunctionUtils import io.rml.framework.core.model.{Literal, TermMap, Uri} import io.rml.framework.flink.item.Item @@ -40,7 +40,7 @@ class PredicateGeneratorAssembler extends TermMapGeneratorAssembler { assembledFunction.andThen(item => { if(item.isDefined) { item.map(iter => iter.flatMap(elem => { - val castedResult = TransformationUtils.typeCastDataType(elem, termMap.datatype) + val castedResult = FunctionUtils.typeCastDataType(elem, termMap.datatype) castedResult.map(v => Uri(v.toString)) })) }else { diff --git a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala index fb39a2d9..ad84b908 100644 --- a/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/PredicateObjectGeneratorAssembler.scala @@ -37,7 +37,7 @@ class PredicateObjectGeneratorAssembler(predicateGeneratorAssembler: PredicateGe def assemble(predicateObjectMap: PredicateObjectMap) : List[(Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]], Item => Option[Iterable[Uri]])] = { - this.logInfo("%s assemble (predicateObjectMap)".format(this.getClass.getName)) + this.logDebug("%s assemble (predicateObjectMap)".format(this.getClass.getName)) val graphStatement = graphGeneratorAssembler.assemble(predicateObjectMap.graphMap) predicateObjectMap.predicateMaps.flatMap(predicateMap => { diff --git a/src/main/scala/io/rml/framework/engine/statement/StatementEngine.scala b/src/main/scala/io/rml/framework/engine/statement/StatementEngine.scala index f18ff881..9f613ac7 100644 --- a/src/main/scala/io/rml/framework/engine/statement/StatementEngine.scala +++ b/src/main/scala/io/rml/framework/engine/statement/StatementEngine.scala @@ -76,7 +76,7 @@ object StatementEngine extends Logging { */ def fromTriplesMaps(triplesMaps: List[TriplesMap]): StatementEngine[Item] = { // assemble the statements - this.logInfo("fromTriplesMaps(triplesMaps) - creating statement engine") + this.logDebug("fromTriplesMaps(triplesMaps) - creating statement engine") //Group the triple maps with their iterator as the key val iteratorGroup = triplesMaps.groupBy(tm => { // here we require the triples map to have only one iterator diff --git a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala index 763e18ec..97b0e544 100644 --- a/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/StatementsAssembler.scala @@ -44,7 +44,7 @@ extends Logging{ * @return */ def assembleStatements(triplesMap: TriplesMap): List[(Item => Option[Iterable[TermNode]], Item => Option[Iterable[Uri]], Item => Option[Iterable[Entity]], Item => Option[Iterable[Uri]])] = { - this.logInfo("%s assembleStatements(triplesmaps)".format(this.getClass.getName)) + this.logDebug("%s assembleStatements(triplesmaps)".format(this.getClass.getName)) val subjectGraphGenerator = graphAssembler.assemble(triplesMap.subjectMap.graphMap) diff --git a/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala b/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala index 004b33e6..ef9a028f 100644 --- a/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala +++ b/src/main/scala/io/rml/framework/engine/statement/SubjectGeneratorAssembler.scala @@ -25,7 +25,7 @@ package io.rml.framework.engine.statement -import io.rml.framework.core.function.TransformationUtils +import io.rml.framework.core.function.FunctionUtils import io.rml.framework.core.model.{TermMap, TermNode, Uri} import io.rml.framework.core.vocabulary.RMLVoc import io.rml.framework.flink.item.Item @@ -42,7 +42,7 @@ class SubjectGeneratorAssembler extends TermMapGeneratorAssembler { if(item.isDefined) { item.map(iter => iter.flatMap(elem => { - val castedResult = TransformationUtils.typeCastDataType(elem, termMap.datatype) + val castedResult = FunctionUtils.typeCastDataType(elem, termMap.datatype) castedResult.map(v => Uri(v.toString)) })) }else { diff --git a/src/test/scala/io/rml/framework/OutputGenerationTest.scala b/src/test/scala/io/rml/framework/OutputGenerationTest.scala index 8ab84d3d..bfa05390 100644 --- a/src/test/scala/io/rml/framework/OutputGenerationTest.scala +++ b/src/test/scala/io/rml/framework/OutputGenerationTest.scala @@ -28,7 +28,7 @@ import java.io.File import io.rml.framework.api.RMLEnvironment import io.rml.framework.core.extractors.{MappingExtractor, MappingReader} -import io.rml.framework.core.model.TransformationMapping +import io.rml.framework.core.model.FunctionMapping import io.rml.framework.engine.PostProcessor import io.rml.framework.util.TestUtil import io.rml.framework.util.fileprocessing.{ExpectedOutputTestUtil, TripleGeneratorTestUtil} @@ -63,7 +63,7 @@ class OutputGenerationTest extends StaticTestSpec with ReadMappingBehaviour { "Valid mapping output generation" should "match the output from output.ttl" in { // load functions - MappingReader(MappingExtractor(TransformationMapping)).read(functionFile) + MappingReader(MappingExtractor(FunctionMapping)).read(functionFile) passing.foreach(test => { RMLEnvironment.setGeneratorBaseIRI(Some("http://example.com/base/")) diff --git a/src/test/scala/io/rml/framework/SandboxTests.scala b/src/test/scala/io/rml/framework/SandboxTests.scala index 973bda33..f43082c5 100644 --- a/src/test/scala/io/rml/framework/SandboxTests.scala +++ b/src/test/scala/io/rml/framework/SandboxTests.scala @@ -29,8 +29,8 @@ import java.io.File import io.rml.framework.Main import io.rml.framework.api.RMLEnvironment import io.rml.framework.core.extractors.{MappingExtractor, MappingReader} -import io.rml.framework.core.function.TransformationLoader -import io.rml.framework.core.model.TransformationMapping +import io.rml.framework.core.function.FunctionLoader +import io.rml.framework.core.model.FunctionMapping import io.rml.framework.core.util.Util import io.rml.framework.engine.NopPostProcessor import io.rml.framework.util.TestUtil @@ -56,7 +56,7 @@ class SandboxTests extends FunSuite with Matchers { val mappingFileAbs = new File(testDir, new File(mappingFile).getName) // load functions - MappingReader(MappingExtractor(TransformationMapping)).read(functionFile) + MappingReader(MappingExtractor(FunctionMapping)).read(functionFile) // read the mapping val formattedMapping = Util.readMappingFile(mappingFileAbs.getAbsolutePath) diff --git a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala index 9949f8e6..f22f6d4d 100644 --- a/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala +++ b/src/test/scala/io/rml/framework/model/function/FunctionLoaderTest.scala @@ -4,8 +4,8 @@ import java.io.File import io.rml.framework.StaticTestSpec import io.rml.framework.api.RMLEnvironment -import io.rml.framework.core.function.model.{DynamicMethodTransformation, Transformation} -import io.rml.framework.core.function.{TransformationLoader, TransformationUtils} +import io.rml.framework.core.function.model.{DynamicMethodFunction, Function} +import io.rml.framework.core.function.{FunctionLoader, FunctionUtils} import io.rml.framework.core.model.Uri import io.rml.framework.core.vocabulary.{Namespaces, RMLVoc} @@ -15,28 +15,28 @@ class FunctionLoaderTest extends StaticTestSpec { "Loading default grel functions classes" should "succeed without error" in { val filePath = RMLEnvironment.getClass.getClassLoader.getResource("GrelFunctions.jar").getFile - val cls = TransformationUtils.loadClassFromJar(new File(filePath), "GrelFunctions") + val cls = FunctionUtils.loadClassFromJar(new File(filePath), "GrelFunctions") println(cls) assert(cls.getDeclaredMethods.length > 0, "Declared methods must be more than 0 for now") } "FunctionLoader" should "initialize the transformation lazily and correctly" in { - val loader = TransformationLoader().parseTransformations(functionFile) + val loader = FunctionLoader().parseFunctions(functionFile) val test = Uri("http://users.ugent.be/~bjdmeest/function/grel.ttl#toUpperCase") - val transformation = loader.loadTransformation(test) + val transformation = loader.loadFunction(test) - assume(transformation.isInstanceOf[Option[DynamicMethodTransformation]]) + assume(transformation.isInstanceOf[Option[DynamicMethodFunction]]) } "Dynamic Function" should "be loaded and executable" in { - val loader = TransformationLoader().parseTransformations(functionFile) + val loader = FunctionLoader().parseFunctions(functionFile) val testValue = "qmlsdkfje sdfesdfFJ" val functionUri = Uri(Namespaces("grel", "toUpperCase")) // map: uri -> trans. metadata - val transformationMap = loader.getTransformationMap + val transformationMap = loader.getFunctionMap // transformation meta data for given function uri val transformationMetaData = transformationMap.getOrElse( @@ -44,9 +44,9 @@ class FunctionLoaderTest extends StaticTestSpec { throw new Exception("Unable to find transformation meta data in transformation map")) - val transformation = Transformation(functionUri.identifier,transformationMetaData) - // initializedTransformation is a DynamicMethodTransformation - val initializedTransformation: Transformation = transformation.initialize() + val transformation = Function(functionUri.identifier,transformationMetaData) + // initializedTransformation is a DynamicMethodFunction + val initializedTransformation: Function = transformation.initialize() // bind value parameter to its actual value val paramMap = Map(Uri(Namespaces("grel", "valueParameter")) -> testValue) From 32271e57dd695f854cec89cd59b2e23d9a1972e5 Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Thu, 11 Jun 2020 14:35:04 +0200 Subject: [PATCH 033/169] wip: feature function #25 - Replaced "transformation" with "function" --- .../io/rml/framework/core/extractors/MappingExtractor.scala | 4 ++-- ...ppingExtractor.scala => StdFunctionMappingExtractor.scala} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/main/scala/io/rml/framework/core/extractors/std/{StdTransformationMappingExtractor.scala => StdFunctionMappingExtractor.scala} (74%) diff --git a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala index d19d5471..2d83f708 100644 --- a/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/MappingExtractor.scala @@ -25,7 +25,7 @@ package io.rml.framework.core.extractors -import io.rml.framework.core.extractors.std.{StdFunctionMapExtractor, StdMappingExtractor, StdTransformationMappingExtractor} +import io.rml.framework.core.extractors.std.{StdFunctionMapExtractor, StdMappingExtractor, StdFunctionMappingExtractor} import io.rml.framework.core.model.{Graph, RMLMapping, FunctionMapping} trait MappingExtractor [+T<: Graph]extends GraphExtractor[T] @@ -38,7 +38,7 @@ object MappingExtractor { def apply [T<:Graph](cls: Any): MappingExtractor[Graph] = { cls match{ case RMLMapping => new StdMappingExtractor() - case FunctionMapping => new StdTransformationMappingExtractor() + case FunctionMapping => new StdFunctionMappingExtractor() case _ => throw new IllegalArgumentException("Given args can only be subclasses of Mapping") } diff --git a/src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala similarity index 74% rename from src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala rename to src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala index 750bc4b5..4c254c00 100644 --- a/src/main/scala/io/rml/framework/core/extractors/std/StdTransformationMappingExtractor.scala +++ b/src/main/scala/io/rml/framework/core/extractors/std/StdFunctionMappingExtractor.scala @@ -5,8 +5,8 @@ import io.rml.framework.core.function.FunctionLoader import io.rml.framework.core.model.FunctionMapping import io.rml.framework.core.model.rdf.RDFGraph -//TODO: to be consistent with the terminology, Function should be replaced with Function -class StdTransformationMappingExtractor extends MappingExtractor[FunctionMapping] { + +class StdFunctionMappingExtractor extends MappingExtractor[FunctionMapping] { /** * Extract. * From 245038acd37c5821dd39e156b137931ffe02f60d Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 12 Jun 2020 16:08:17 +0200 Subject: [PATCH 034/169] wip: feature function #25 Added resources - `functions_grel.ttl`: contains the function descriptions. These are the abstract definitions of functions, problems, parameters, etc... - `grel_java_mapping.ttl`: as the name implies, this file contains mappings between function and implementation. It also specifies the class names and corresponding jars to be used. REMARKS: these files may still contain some small errors. --- src/main/resources/functions_grel.ttl | 1437 ++++++++++++++++++++++ src/main/resources/grel_java_mapping.ttl | 322 +++++ 2 files changed, 1759 insertions(+) create mode 100644 src/main/resources/functions_grel.ttl create mode 100644 src/main/resources/grel_java_mapping.ttl diff --git a/src/main/resources/functions_grel.ttl b/src/main/resources/functions_grel.ttl new file mode 100644 index 00000000..15ec66e8 --- /dev/null +++ b/src/main/resources/functions_grel.ttl @@ -0,0 +1,1437 @@ +@prefix cc: . +@prefix dcterms: . +@prefix fno: . +@prefix foaf: . +@prefix grel: . +@prefix rdf: . +@prefix rdfs: . +@prefix void: . +@prefix xsd: . + +grel:void + a void:DatasetDescription ; + dcterms:title "A VoID Description of the GREL Fno Descriptions Dataset" ; + dcterms:creator ; + foaf:primaryTopic grel:dataset ; +. + + + rdf:type foaf:Person ; + foaf:mbox "mailto:Ben.DeMeester@UGent.be" ; + foaf:name "Ben De Meester"@en . + +grel:dataset + a void:Dataset ; + foaf:homepage ; + foaf:homepage ; + dcterms:title "GREL Fno Descriptions"@en ; + dcterms:description "The FnO descriptions of the GREL functions" ; + dcterms:contributor ; + dcterms:modified "2020-01-20"^^xsd:date ; + cc:license ; + dcterms:issued "2016-12-15"^^xsd:date ; + dcterms:rights "Copyright © Ghent University – imec – IDLab"@en ; + dcterms:subject ; + dcterms:subject ; + void:feature ; + void:exampleResource grel:boolean_and ; + void:vocabulary . + +# Contents: +# - Parameters (per java) param_{var} with predicate p_{type}_{var} +# - Outputs (per java) output_{type} with predicate o_{type} +# - Problems (per java) prob_{var} +# - Functions (per java) + +grel:prob_array + a fno:Problem ; + fno:name "The array problem"^^xsd:string ; + dcterms:description ""^^xsd:string . + +grel:prob_array_join + a fno:Problem ; + fno:name "The array join problem"^^xsd:string ; + dcterms:description "Joining an array into a string."^^xsd:string . + +grel:array_join + a fno:Function ; + fno:name "join" ; + dcterms:description "join" ; + fno:solves grel:prob_array_join ; + fno:expects ( grel:param_a grel:param_string_sep ) ; + fno:returns ( grel:stringOut ) . + +grel:param_a + a fno:Parameter ; + fno:name "a" ; + rdfs:label "a" ; + fno:predicate grel:p_array_a ; + fno:type rdf:List ; + fno:required "true"^^xsd:boolean . + +grel:param_string_sep + a fno:Parameter ; + fno:name "sep" ; + rdfs:label "sep" ; + fno:predicate grel:p_string_sep ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +grel:stringOut + a fno:Output ; + fno:name "output string" ; + rdfs:label "output string" ; + fno:predicate grel:stringOutput ; + fno:type xsd:string . + +grel:prob_bool + a fno:Problem ; + fno:name "The bool problem"^^xsd:string ; + dcterms:description ""^^xsd:string . + +#AND + +grel:prob_and + a fno:Problem ; + fno:name "The and problem"^^xsd:string ; + dcterms:description "Returning the logical AND between two (boolean) operands."^^xsd:string . + +grel:boolean_and + a fno:Function ; + fno:name "and" ; + dcterms:description "and" ; + fno:solves grel:prob_and ; + fno:expects ( grel:bool_array_b ) ; + fno:returns ( grel:output_bool ) . + +grel:bool_array_b + a fno:Parameter ; + fno:name "b" ; + rdfs:label "b" ; + fno:predicate grel:param_rep_b ; + fno:type rdf:List ; + fno:required "true"^^xsd:boolean . + +grel:output_bool + a fno:Output ; + fno:name "bool" ; + rdfs:label "bool" ; + fno:predicate grel:o_bool ; + fno:type xsd:boolean . + +#OR + +grel:prob_or + a fno:Problem ; + fno:name "The or problem"^^xsd:string ; + dcterms:description "Returning the logical OR between two (boolean) operands."^^xsd:string . + +grel:boolean_or + a fno:Function ; + fno:name "or" ; + dcterms:description "or" ; + fno:solves grel:prob_or ; + fno:expects ( grel:bool_array_b ) ; + fno:returns ( grel:output_bool ) . + +#NOT + +grel:prob_not + a fno:Problem ; + fno:name "The not problem"^^xsd:string ; + dcterms:description "Returning the boolean negation of the argument."^^xsd:string . + +grel:boolean_not + a fno:Function ; + fno:name "not" ; + dcterms:description "not" ; + fno:solves grel:prob_not ; + fno:expects ( grel:param_b ) ; + fno:returns ( grel:output_bool ) . + +grel:param_b + a fno:Parameter ; + fno:name "b" ; + rdfs:label "b" ; + fno:predicate grel:bool_b ; + fno:type xsd:boolean ; + fno:required "true"^^xsd:boolean . + +#XOR + +grel:boolean_xor + a fno:Function ; + fno:name "xor" ; + dcterms:description "xor" ; + fno:expects ( grel:bool_array_b ) ; + fno:returns ( grel:output_bool ) . + +#IFTHENELSE + +grel:prob_if + a fno:Problem ; + fno:name "The if problem"^^xsd:string ; + dcterms:description "Doing an if-statement."^^xsd:string . + +grel:controls_if + a fno:Function ; + fno:name "if" ; + dcterms:description "if" ; + fno:solves grel:prob_if ; + fno:expects ( grel:param_b grel:param_true grel:param_false ) ; + fno:returns ( grel:output_any ) . + +grel:param_true + a fno:Parameter ; + fno:name "eTrue" ; + rdfs:label "eTrue" ; + fno:predicate grel:any_true ; + fno:type xsd:any ; + fno:required "true"^^xsd:boolean . + +grel:param_false + a fno:Parameter ; + fno:name "eFalse" ; + rdfs:label "eFalse" ; + fno:predicate grel:any_false ; + fno:type xsd:any ; + fno:required "true"^^xsd:boolean . + +grel:prob_string + a fno:Problem ; + fno:name "The string problem"^^xsd:string ; + dcterms:description ""^^xsd:string . + +#STRING_LENGTH + +grel:prob_strlen + a fno:Problem ; + fno:name "The strlen problem"^^xsd:string ; + dcterms:description "Computing the length of a given input string."^^xsd:string . + +grel:string_length + a fno:Function ; + fno:name "length" ; + dcterms:description "length" ; + fno:solves grel:prob_strlen ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:output_number ) . + +grel:valueParam + a fno:Parameter ; + fno:name "input value" ; + rdfs:label "input value" ; + fno:predicate grel:valueParameter ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +grel:output_number + a fno:Output ; + fno:name "number" ; + rdfs:label "number" ; + fno:predicate grel:o_number ; + fno:type xsd:number . + +#TODO toStringValue + +#STARTSWITH + +grel:prob_strstarts + a fno:Problem ; + fno:name "The strstarts problem"^^xsd:string ; + dcterms:description "Whether a string starts another string"^^xsd:string . + +grel:string_startsWith + a fno:Function ; + fno:name "startsWith" ; + dcterms:description "startsWith" ; + fno:solves grel:prob_strstarts ; + fno:expects ( grel:valueParam grel:param_string_sub ) ; + fno:returns ( grel:output_bool ) . + +grel:param_string_sub + a fno:Parameter ; + fno:name "sub" ; + rdfs:label "sub" ; + fno:predicate grel:string_sub ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +#ENDSWITH + +grel:prob_strends + a fno:Problem ; + fno:name "The strends problem"^^xsd:string ; + dcterms:description "Whether a string ends another string"^^xsd:string . + +grel:string_endsWith + a fno:Function ; + fno:name "endsWith" ; + dcterms:description "endsWith" ; + fno:solves grel:prob_strends ; + fno:expects ( grel:valueParam grel:param_string_sub ) ; + fno:returns ( grel:output_bool ) . + +#CONTAINS + +grel:prob_contains + a fno:Problem ; + fno:name "The contains problem"^^xsd:string ; + dcterms:description "Whether a string contains another string"^^xsd:string . + +grel:string_contains + a fno:Function ; + fno:name "contains" ; + dcterms:description "contains" ; + fno:solves grel:prob_contains ; + fno:expects ( grel:valueParam grel:param_string_sub ) ; + fno:returns ( grel:output_bool ) . + +#TODO indexOf + +grel:string_indexOf + a fno:Function ; + fno:name "indexOf" ; + dcterms:description "indexOf" ; + fno:expects ( grel:valueParam grel:param_string_sub ) ; + fno:returns ( grel:output_number ) . + +#grel:string_indexOf +# a fno:Function ; +# fno:name "indexOf" ; +# dcterms:description "indexOf" ; +# fno:expects ( ) ; +# fno:returns ( grel:output_number ) . + +#TOLOWERCASE + +grel:prob_lcase + a fno:Problem ; + fno:name "The lcase problem"^^xsd:string ; + dcterms:description "Converting a string to lower case characters."^^xsd:string . + +grel:toLowerCase + a fno:Function ; + fno:name "to Lowercase" ; + rdfs:label "to Lowercase" ; + dcterms:description "Returns the input with all letters in lower case." ; + fno:solves grel:prob_lcase ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:stringOut ) . + +#TOUPPERCASE + +grel:prob_ucase + a fno:Problem ; + fno:name "The ucase problem"^^xsd:string ; + dcterms:description "Converting a string to upper case characters."^^xsd:string . + +grel:toUpperCase + a fno:Function ; + fno:name "to Uppercase" ; + rdfs:label "to Uppercase" ; + dcterms:description "Returns the input with all letters in upper case." ; + fno:solves grel:prob_ucase ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:stringOut ) . + +#TODO toTitleCase + +grel:string_toTitlecase + a fno:Function ; + fno:name "toTitlecase" ; + dcterms:description "toTitlecase" ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:stringOut ) . + +#TRIM + +#TODO Problem trim + +grel:string_trim + a fno:Function ; + fno:name "trim" ; + dcterms:description "trim" ; + fno:expects ( grel:valueParam ) ; + fno:returns ( grel:stringOut ) . + +#TODO strip sameAs trim + +#grel:valueParamtrip +# a fno:Function ; +# fno:name "strip" ; +# dcterms:description "strip" ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:stringOut ) . + +#TODO chomp + +grel:string_chomp + a fno:Function ; + fno:name "chomp" ; + dcterms:description "chomp" ; + fno:expects ( grel:valueParam grel:param_string_sep ) ; + fno:returns ( grel:stringOut ) . + +#SUBSTRING + +grel:prob_substr + a fno:Problem ; + fno:name "The substr problem"^^xsd:string ; + dcterms:description "Getting the sub-string of a given string"^^xsd:string . + +grel:string_substring + a fno:Function ; + fno:name "substring" ; + dcterms:description "substring" ; + fno:solves grel:prob_substr ; + fno:expects ( grel:valueParam grel:p_int_i_from grel:p_int_i_opt_to ) ; + fno:returns ( grel:stringOut ) . + +grel:p_int_i_from + a fno:Parameter ; + fno:name "from" ; + rdfs:label "from" ; + fno:predicate grel:param_int_i_from ; + fno:type xsd:int ; + fno:required "true"^^xsd:boolean . + +grel:p_int_i_opt_to + a fno:Parameter ; + fno:name "to" ; + rdfs:label "to" ; + fno:predicate grel:param_int_i_opt_to ; + fno:type xsd:string ; + fno:required "false"^^xsd:boolean . + +# TODO slice sameAs substring + +#grel:valueParamlice +# a fno:Function ; +# fno:name "slice" ; +# dcterms:description "slice" ; +# fno:expects ( grel:valueParam grel:p_int_i_from grel:p_int_i_opt_to ) ; +# fno:returns ( grel:stringOut ) . + +# TODO get sameAs substring + +#grel:string_get +# a fno:Function ; +# fno:name "get" ; +# dcterms:description "get" ; +# fno:expects ( grel:valueParam grel:p_int_i_from grel:p_int_i_opt_to ) ; +# fno:returns ( grel:stringOut ) . + +# TODO lastIndexOf + +#grel:string_lastIndexOf +# a fno:Function ; +# fno:name "lastIndexOf" ; +# dcterms:description "lastIndexOf" ; +# fno:expects ( grel:valueParam grel:param_string_sub ) ; +# fno:returns ( grel:output_number ) . + +# TODO replace + +grel:prob_replace + a fno:Problem ; + fno:name "The replace problem"^^xsd:string ; + dcterms:description + "Replacing each non-overlapping occurrence of a regular expression pattern with a replacement string. Regular expession matching may involve modifier flags."^^xsd:string . + +#grel:string_replace +# a fno:Function ; +# fno:name "replace" ; +# dcterms:description "replace" ; +# fno:solves grel:prob_replace ; +# fno:expects ( grel:valueParam grel:param_find grel:param_replace ) ; +# fno:returns ( grel:stringOut ) . + +grel:param_find + a fno:Parameter ; + fno:name "f" ; + rdfs:label "f" ; + fno:predicate grel:p_string_find ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +grel:param_replace + a fno:Parameter ; + fno:name "r" ; + rdfs:label "r" ; + fno:predicate grel:p_string_replace ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +#TODO replaceChars + +#grel:string_replaceChars +# a fno:Function ; +# fno:name "replaceChars" ; +# dcterms:description "replaceChars" ; +# fno:expects ( grel:valueParam grel:param_find grel:param_replace ) ; +# fno:returns ( grel:stringOut ) . + +#TODO match + +grel:prob_regex + a fno:Problem ; + fno:name "The regex problem"^^xsd:string ; + dcterms:description + "Returning true if a string (?arg1) matches the regular expression supplied as a pattern (?arg2) as influenced by the value of flags (?arg3), otherwise returns false."^^xsd:string . + +#grel:string_match +# a fno:Function ; +# fno:name "match" ; +# dcterms:description "match" ; +# fno:expects ( grel:valueParam grel:param_regex ) ; +# fno:returns ( grel:output_array ) . + +grel:output_array + a fno:Output ; + fno:name "array" ; + rdfs:label "array" ; + fno:predicate grel:o_array ; + fno:type rdf:List . + +grel:param_regex + a fno:Parameter ; + fno:name "p" ; + rdfs:label "p" ; + fno:predicate grel:p_string_regex ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +#TODO find + +#grel:string_find +# a fno:Function ; +# fno:name "find" ; +# dcterms:description "find" ; +# fno:expects ( grel:valueParam grel:param_regex ) ; +# fno:returns ( grel:output_array ) . + +#TODO toNumber + +#grel:string_toNumber +# a fno:Function ; +# fno:name "toNumber" ; +# dcterms:description "toNumber" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:output_number ) . + +grel:param_any_e + a fno:Parameter ; + fno:name "e" ; + rdfs:label "e" ; + fno:predicate grel:p_any_e ; + fno:type xsd:any ; + fno:required "true"^^xsd:boolean . + +#SPLIT + +grel:string_split + a fno:Function ; + fno:name "split" ; + dcterms:description "split" ; + fno:expects ( grel:valueParam grel:param_string_sep ) ; + fno:returns ( grel:output_array ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#splitbylengthsstring-s-number-n1-number-n2- + +#grel:string_splitByLengths +# a fno:Function ; +# fno:name "splitByLengths" ; +# dcterms:description "splitByLengths" ; +# fno:expects ( grel:valueParam grel:param_int_i grel:param_int_i2 grel:param_int_rep_i ) ; +# fno:returns ( grel:output_array ) . + +grel:param_int_i + a fno:Parameter ; + fno:name "d1" ; + rdfs:label "d1" ; + fno:predicate grel:p_int_i ; + fno:type xsd:int ; + fno:required "true"^^xsd:boolean . + +grel:param_int_i2 + a fno:Parameter ; + fno:name "d2" ; + rdfs:label "d2" ; + fno:predicate grel:p_int_i2 ; + fno:type xsd:int ; + fno:required "true"^^xsd:boolean . + +grel:param_int_rep_i + a fno:Parameter ; + fno:name "n3" ; + rdfs:label "n3" ; + fno:predicate grel:p_rep_i ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#smartsplitstring-s-optional-string-sep + +#grel:valueParammartSplit +# a fno:Function ; +# fno:name "smartSplit" ; +# dcterms:description "smartSplit" ; +# fno:expects ( grel:valueParam grel:param_opt_sep ) ; +# fno:returns ( grel:output_array ) . + +grel:param_opt_sep + a fno:Parameter ; + fno:name "sep" ; + rdfs:label "sep" ; + fno:predicate grel:p_opt_sep ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#splitbychartypes + +#grel:valueParamplitByCharType +# a fno:Function ; +# fno:name "splitByCharType" ; +# dcterms:description "splitByCharType" ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:output_array ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#partitionstring-s-string-or-regex-frag-optional-boolean-omitfragment + +#grel:string_partition +# a fno:Function ; +# fno:name "partition" ; +# dcterms:description "partition" ; +# fno:expects ( grel:valueParam grel:param_fragment grel:param_bool_opt_b ) ; +# fno:returns ( grel:output_array ) . + +grel:param_fragment + a fno:Parameter ; + fno:name "frag" ; + rdfs:label "frag" ; + fno:predicate grel:p_fragment ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +grel:param_bool_opt_b + a fno:Parameter ; + fno:name "b?" ; + rdfs:label "b?" ; + fno:predicate grel:p_bool_opt_b ; + fno:type xsd:boolean ; + fno:required "false"^^xsd:boolean . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#rpartitionstring-s-string-or-regex-frag-optional-boolean-omitfragment + +#grel:string_rpartition +# a fno:Function ; +# fno:name "rpartition" ; +# dcterms:description "rpartition" ; +# fno:expects ( grel:valueParam grel:param_fragment grel:param_bool_opt_b ) ; +# fno:returns ( grel:output_array ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#diffo1-o2-optional-string-timeunit + +#grel:string_diff +# a fno:Function ; +# fno:name "diff" ; +# dcterms:description "diff" ; +# fno:expects ( grel:valueParam grel:valueParam2 ) ; +# fno:returns ( grel:stringOut ) . + +grel:valueParam2 + a fno:Parameter ; + fno:name "input value 2" ; + rdfs:label "input value 2" ; + fno:predicate grel:valueParameter2 ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +#ESCAPE + +grel:prob_encode_for_uri + a fno:Problem ; + fno:name "The encode_for_uri problem"^^xsd:string ; + dcterms:description "encoding for a URI"^^xsd:string . + +grel:escape + a fno:Function ; + fno:name "escape" ; + rdfs:label "escape" ; + dcterms:description "Escapes a string, with a mode parameter." ; + fno:solves grel:prob_encode_for_uri ; + fno:expects ( grel:valueParam grel:modeParam ) ; + fno:returns ( grel:stringOut ) . + +grel:modeParam + a fno:Parameter ; + fno:name "mode value" ; + rdfs:label "mode value" ; + fno:type xsd:string ; + fno:predicate grel:modeParameter ; + fno:required "true"^^xsd:boolean . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#unescapestring-s-string-mode + +#grel:string_unescape +# a fno:Function ; +# fno:name "unescape" ; +# dcterms:description "unescape" ; +# fno:expects ( grel:valueParam grel:modeParam ) ; +# fno:returns ( grel:stringOut ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#md5string-s + +grel:prob_crypto + a fno:Problem ; + fno:name "The crypto problem"^^xsd:string ; + dcterms:description ""^^xsd:string . + +grel:prob_md5 + a fno:Problem ; + fno:name "The md5 problem"^^xsd:string ; + dcterms:description "Calculating the md5 checksum."^^xsd:string . + +#grel:string_md5 +# a fno:Function ; +# fno:name "md5" ; +# dcterms:description "md5" ; +# fno:solves grel:prob_md5 ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:stringOut ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#sha1string-s + +grel:prob_sha1 + a fno:Problem ; + fno:name "The sha1 problem"^^xsd:string ; + dcterms:description "Calculating the SHA1 checksum."^^xsd:string . + +#grel:string_sha1 +# a fno:Function ; +# fno:name "sha1" ; +# dcterms:description "sha1" ; +# fno:solves grel:prob_sha1 ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:stringOut ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#phoneticstring-s-string-encoding + +#grel:string_phonetic +# a fno:Function ; +# fno:name "phonetic" ; +# dcterms:description "phonetic" ; +# fno:expects ( grel:valueParam grel:valueParamtring_encoding ) ; +# fno:returns ( grel:stringOut ) . + +grel:valueParamtring_encoding + a fno:Parameter ; + fno:name "encoding" ; + rdfs:label "encoding" ; + fno:predicate grel:p_encoding ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#reinterpretstring-s-string-encoder + +#grel:string_reinterpret +# a fno:Function ; +# fno:name "reinterpret" ; +# dcterms:description "reinterpret" ; +# fno:expects ( grel:valueParam grel:valueParamtring_encoder ) ; +# fno:returns ( grel:stringOut ) . + +grel:valueParamtring_encoder + a fno:Parameter ; + fno:name "encoder" ; + rdfs:label "encoder" ; + fno:predicate grel:p_encoder ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#fingerprintstring-s + +#grel:string_fingerprint +# a fno:Function ; +# fno:name "fingerprint" ; +# dcterms:description "fingerprint" ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:stringOut ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#ngramstring-s-number-n + +#grel:string_ngram +# a fno:Function ; +# fno:name "ngram" ; +# dcterms:description "ngram" ; +# fno:expects ( grel:valueParam grel:param_int_i ) ; +# fno:returns ( grel:output_array ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#ngramfingerprintstring-s-number-n + +#grel:string_ngramFingerprint +# a fno:Function ; +# fno:name "ngramFingerprint" ; +# dcterms:description "ngramFingerprint" ; +# fno:expects ( grel:valueParam grel:param_int_i ) ; +# fno:returns ( grel:output_array ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#unicodestring-s + +#grel:string_unicode +# a fno:Function ; +# fno:name "unicode" ; +# dcterms:description "unicode" ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:output_array ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#unicodetypestring-s + +#grel:string_unicodeType +# a fno:Function ; +# fno:name "unicodeType" ; +# dcterms:description "unicodeType" ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:output_array ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#mqlkeyquotestring-s + +#grel:string_mqlKeyQuote +# a fno:Function ; +# fno:name "mqlKeyQuote" ; +# dcterms:description "mqlKeyQuote" ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:stringOut ) . + +#TODO https://github.com/OpenRefine/OpenRefine/wiki/GREL-String-Functions#mqlkeyunquotestring-key + +grel:string_mqlKeyUnquote + a fno:Function ; + fno:name "mqlKeyUnquote" ; + dcterms:description "mqlKeyUnquote" ; + fno:expects ( grel:valueParamtring_key ) ; + fno:returns ( grel:stringOut ) . + +grel:valueParamtring_key + a fno:Parameter ; + fno:name "key" ; + rdfs:label "key" ; + fno:predicate grel:p_key ; + fno:type xsd:string ; + fno:required "true"^^xsd:boolean . + +grel:prob_date + a fno:Problem ; + fno:name "The date problem"^^xsd:string ; + dcterms:description ""^^xsd:string . + +grel:prob_timezone + a fno:Problem ; + fno:name "The timezone problem"^^xsd:string ; + dcterms:description "Getting the timezone of a string."^^xsd:string . + +grel:prob_day + a fno:Problem ; + fno:name "The day problem"^^xsd:string ; + dcterms:description "Extracting the day from a date/time literal."^^xsd:string . + +grel:prob_month + a fno:Problem ; + fno:name "The month problem"^^xsd:string ; + dcterms:description "Extracting the month from a date/time literal."^^xsd:string . + +grel:prob_hours + a fno:Problem ; + fno:name "The hours problem"^^xsd:string ; + dcterms:description "Extracting the hours from a date/time literal."^^xsd:string . + +grel:prob_seconds + a fno:Problem ; + fno:name "The seconds problem"^^xsd:string ; + dcterms:description "Extracting the seconds from a date/time literal."^^xsd:string . + +grel:prob_minutes + a fno:Problem ; + fno:name "The minutes problem"^^xsd:string ; + dcterms:description "Extracting the minutes from a date/time literal."^^xsd:string . + +grel:prob_year + a fno:Problem ; + fno:name "The year problem"^^xsd:string ; + dcterms:description "Extracting the year from a date/time literal."^^xsd:string . + +#grel:date_datePart +# a fno:Function ; +# fno:name "datePart" ; +# dcterms:description "datePart" ; +# fno:expects ( grel:date_d grel:string_unit ) ; +# fno:returns ( grel:output_any ) . + +#grel:date_d +# a fno:Parameter ; +# fno:name "d" ; +# rdfs:label "d" ; +# fno:predicate grel:param_d ; +# fno:type xsd:date ; +# fno:required "true"^^xsd:boolean . + +#grel:string_unit +# a fno:Parameter ; +# fno:name "unit" ; +# rdfs:label "unit" ; +# fno:predicate grel:param_unit ; +# fno:type xsd:string ; +# fno:required "true"^^xsd:boolean . + +grel:prob_now + a fno:Problem ; + fno:name "The now problem"^^xsd:string ; + dcterms:description "Getting the current date and time."^^xsd:string . + +#grel:date_now +# a fno:Function ; +# fno:name "now" ; +# dcterms:description "now" ; +# fno:expects ( ) ; +# fno:returns ( grel:output_datetime ) . + +#TODO output_datetime + +grel:prob_mathematical + a fno:Problem ; + fno:name "The mathematical problem"^^xsd:string ; + dcterms:description ""^^xsd:string . + +grel:prob_floor + a fno:Problem ; + fno:name "The floor problem"^^xsd:string ; + dcterms:description + "Returning the largest (closest to positive infinity) number with no fractional part that is not greater than the given value."^^xsd:string . + +#grel:math_floor +# a fno:Function ; +# fno:name "floor" ; +# dcterms:description "floor" ; +# fno:solves grel:prob_floor ; +# fno:expects ( grel:dec_n ) ; +# fno:returns ( grel:output_number ) . + +#grel:dec_n +# a fno:Parameter ; +# fno:name "d" ; +# rdfs:label "d" ; +# fno:predicate grel:param_n ; +# fno:type xsd:decimal ; +# fno:required "true"^^xsd:boolean . + +# +# skos:broader grel:math_floor . + +grel:prob_max + a fno:Problem ; + fno:name "The max problem"^^xsd:string ; + dcterms:description "Returning the largest value of the input."^^xsd:string . + +#grel:math_max +# a fno:Function ; +# fno:name "max" ; +# dcterms:description "max" ; +# fno:solves grel:prob_max ; +# fno:expects ( grel:dec_n grel:dec_n2 ) ; +# fno:returns ( grel:output_number ) . + +#grel:dec_n2 +# a fno:Parameter ; +# fno:name "d2" ; +# rdfs:label "d2" ; +# fno:predicate grel:param_n2 ; +# fno:type xsd:decimal ; +# fno:required "true"^^xsd:boolean . + +grel:prob_min + a fno:Problem ; + fno:name "The min problem"^^xsd:string ; + dcterms:description "Returning the smallest value of the input."^^xsd:string . + +#grel:math_min +# a fno:Function ; +# fno:name "min" ; +# dcterms:description "min" ; +# fno:solves grel:prob_min ; +# fno:expects ( grel:dec_n grel:dec_n2 ) ; +# fno:returns ( grel:output_number ) . + +grel:prob_round + a fno:Problem ; + fno:name "The round problem"^^xsd:string ; + dcterms:description + "Returning the number with no fractional part that is closest to the argument. If there are two such numbers, then the one that is closest to positive infinity is returned."^^xsd:string . + +#grel:math_round +# a fno:Function ; +# fno:name "round" ; +# dcterms:description "round" ; +# fno:solves grel:prob_round ; +# fno:expects ( grel:dec_n ) ; +# fno:returns ( grel:output_number ) . + +# +# skos:broader grel:math_round . + +grel:prob_ceil + a fno:Problem ; + fno:name "The ceil problem"^^xsd:string ; + dcterms:description + "Returning the smallest (closest to negative infinity) number with no fractional part that is not less than the value of arg."^^xsd:string . + +#grel:math_ceil +# a fno:Function ; +# fno:name "ceil" ; +# dcterms:description "ceil" ; +# fno:solves grel:prob_ceil ; +# fno:expects ( grel:dec_n ) ; +# fno:returns ( grel:output_number ) . + +grel:prob_coalesce + a fno:Problem ; + fno:name "The coalesce problem"^^xsd:string ; + dcterms:description "Returning the first bound argument."^^xsd:string . + +#grel:other_coalesce +# a fno:Function ; +# fno:name "coalesce" ; +# dcterms:description "coalesce" ; +# fno:solves grel:prob_coalesce ; +# fno:expects ( grel:any_rep_e ) ; +# fno:returns ( grel:output_any ) . + +# HERE + +#grel:param_b2 +# a fno:Parameter ; +# fno:name "b2" ; +# rdfs:label "b2" ; +# fno:predicate grel:bool_b2 ; +# fno:type xsd:boolean ; +# fno:required "true"^^xsd:boolean . + +#grel:bool_rep_b +# a fno:Parameter ; +# fno:name "b3" ; +# rdfs:label "b3" ; +# fno:predicate grel:param_rep_b ; +# fno:type xsd:string ; +# fno:required "true"^^xsd:boolean . + +#grel:date_d2 +# a fno:Parameter ; +# fno:name "d2" ; +# rdfs:label "d2" ; +# fno:predicate grel:param_d2 ; +# fno:type xsd:date ; +# fno:required "true"^^xsd:boolean . + +#grel:dec_n_exp +# a fno:Parameter ; +# fno:name "e" ; +# rdfs:label "e" ; +# fno:predicate grel:p_any_exp ; +# fno:type xsd:decimal ; +# fno:required "true"^^xsd:boolean . + +#grel:string_field +# a fno:Parameter ; +# fno:name "field" ; +# rdfs:label "field" ; +# fno:predicate grel:param_field ; +# fno:type xsd:string ; +# fno:required "true"^^xsd:boolean . + +#grel:string_format +# a fno:Parameter ; +# fno:name "format" ; +# rdfs:label "format" ; +# fno:predicate grel:param_format ; +# fno:type xsd:string ; +# fno:required "true"^^xsd:boolean . + +#grel:string_rep_format +# a fno:Parameter ; +# fno:name "format1" ; +# rdfs:label "format1" ; +# fno:predicate grel:param_rep_format ; +# fno:type xsd:string ; +# fno:required "true"^^xsd:boolean . + +#grel:uri_index +# a fno:Parameter ; +# fno:name "i" ; +# rdfs:label "i" ; +# fno:predicate grel:p_int_index ; +# fno:type xsd:string ; +# fno:required "true"^^xsd:boolean . + +#grel:any_rep_e +# a fno:Parameter ; +# fno:name "o1" ; +# rdfs:label "o1" ; +# fno:predicate grel:param_rep_e ; +# fno:type xsd:any ; +# fno:required "true"^^xsd:boolean . + +#grel:bool_opt_omit +# a fno:Parameter ; +# fno:name "omitFragment" ; +# rdfs:label "omitFragment" ; +# fno:predicate grel:param_omit ; +# fno:type xsd:string ; +# fno:required "false"^^xsd:boolean . + +#grel:param_int_i_step +# a fno:Parameter ; +# fno:name "step" ; +# rdfs:label "step" ; +# fno:predicate grel:string_step ; +# fno:type xsd:int ; +# fno:required "true"^^xsd:boolean . + +#grel:string_time_unit +# a fno:Parameter ; +# fno:name "timeUnit" ; +# rdfs:label "timeUnit" ; +# fno:predicate grel:param_time_unit ; +# fno:type xsd:string ; +# fno:required "true"^^xsd:boolean . + +#grel:param_int_i_to +# a fno:Parameter ; +# fno:name "to" ; +# rdfs:label "to" ; +# fno:predicate grel:param_to ; +# fno:type xsd:int ; +# fno:required "true"^^xsd:boolean . + +#grel:uri_value +# a fno:Parameter ; +# fno:name "v" ; +# rdfs:label "v" ; +# fno:predicate grel:param_value ; +# fno:type xsd:string ; +# fno:required "true"^^xsd:boolean . + +#grel:controls_forEachIndex +# a fno:Function ; +# fno:name "forEachIndex" ; +# dcterms:description "forEachIndex" ; +# fno:expects ( grel:param_a grel:uri_index grel:uri_value grel:param_any_e ) ; +# fno:returns ( grel:output_array ) . + +#grel:controls_forNonBlank +# a fno:Function ; +# fno:name "forNonBlank" ; +# dcterms:description "forNonBlank" ; +# fno:expects ( grel:param_any_e grel:uri_value grel:param_false grel:param_true ) ; +# fno:returns ( grel:output_any ) . + +#grel:date_toDate +# a fno:Function ; +# fno:name "toDate" ; +# dcterms:description "toDate" ; +# fno:expects ( grel:param_any_e grel:string_rep_format ) ; +# fno:returns ( grel:output_date ) . + +#grel:array_sum +# a fno:Function ; +# fno:name "sum" ; +# dcterms:description "sum" ; +# fno:expects ( ) ; +# fno:returns ( grel:output_number ) . + +#grel:controls_forRange +# a fno:Function ; +# fno:name "forRange" ; +# dcterms:description "forRange" ; +# fno:expects ( grel:p_int_i_from grel:inti_i_to grel:param_int_i_step grel:uri_value grel:param_any_e ) ; +# fno:returns ( grel:output_array ) . + +#grel:other_facetCount +# a fno:Function ; +# fno:name "facetCount" ; +# dcterms:description "facetCount" ; +# fno:expects ( ) ; +# fno:returns ( grel:output_number ) . + +#grel:other_cross +# a fno:Function ; +# fno:name "cross" ; +# dcterms:description "cross" ; +# fno:expects ( ) ; +# fno:returns ( grel:output_array ) . + +#grel:controls_filter +# a fno:Function ; +# fno:name "filter" ; +# dcterms:description "filter" ; +# fno:expects ( grel:param_a grel:uri_value grel:param_any_e ) ; +# fno:returns ( grel:output_array ) . + +#grel:controls_forEach +# a fno:Function ; +# fno:name "forEach" ; +# dcterms:description "forEach" ; +# fno:expects ( grel:param_a grel:uri_value grel:param_any_e ) ; +# fno:returns ( grel:output_array ) . + +#grel:controls_with +# a fno:Function ; +# fno:name "with" ; +# dcterms:description "with" ; +# fno:expects ( grel:param_any_e grel:uri_value grel:param_any_e ) ; +# fno:returns ( grel:output_any ) . + +#grel:date_diff +# a fno:Function ; +# fno:name "diff" ; +# dcterms:description "diff" ; +# fno:expects ( grel:date_d grel:date_d2 grel:string_time_unit ) ; +# fno:returns ( grel:output_number ) . + +#grel:array_get +# a fno:Function ; +# fno:name "get" ; +# dcterms:description "get" ; +# fno:expects ( grel:param_a grel:p_int_i_from grel:p_int_i_opt_to ) ; +# fno:returns ( grel:output_array ) . + +#grel:array_slice +# a fno:Function ; +# fno:name "slice" ; +# dcterms:description "slice" ; +# fno:expects ( grel:param_a grel:p_int_i_from grel:p_int_i_opt_to ) ; +# fno:returns ( grel:output_number ) . + + +#grel:date_inc +# a fno:Function ; +# fno:name "inc" ; +# dcterms:description "inc" ; +# fno:expects ( grel:date_d grel:dec_n grel:string_unit ) ; +# fno:returns ( grel:output_date ) . + +#grel:date_toDate +# a fno:Function ; +# fno:name "toDate" ; +# dcterms:description "toDate" ; +# fno:expects ( ) ; +# fno:returns ( grel:output_date ) . + +#grel:math_mod +# a fno:Function ; +# fno:name "mod" ; +# dcterms:description "mod" ; +# fno:expects ( grel:param_int_i grel:param_int_i2 ) ; +# fno:returns ( grel:output_number ) . + +#grel:math_pow +# a fno:Function ; +# fno:name "pow" ; +# dcterms:description "pow" ; +# fno:expects ( grel:dec_n grel:dec_n_exp ) ; +# fno:returns ( grel:output_number ) . + +#grel:other_get +# a fno:Function ; +# fno:name "get" ; +# dcterms:description "get" ; +# fno:expects ( grel:param_any_e grel:string_field ) ; +# fno:returns ( grel:output_any ) . + +#grel:date_toString +# a fno:Function ; +# fno:name "toString" ; +# dcterms:description "toString" ; +# fno:expects ( grel:date_d grel:string_format ) ; +# fno:returns ( grel:stringOut ) . + +#grel:other_hasField +# a fno:Function ; +# fno:name "hasField" ; +# dcterms:description "hasField" ; +# fno:expects ( grel:param_any_e grel:string_field ) ; +# fno:returns ( grel:output_bool ) . + +#grel:other_htmlAttr +# a fno:Function ; +# fno:name "htmlAttr" ; +# dcterms:description "htmlAttr" ; +# fno:expects ( ) ; +# fno:returns ( grel:output_any ) . + +#grel:other_select +# a fno:Function ; +# fno:name "select" ; +# dcterms:description "select" ; +# fno:expects ( ) ; +# fno:returns ( grel:output_element ) . + +#grel:array_length +# a fno:Function ; +# fno:name "length" ; +# dcterms:description "length" ; +# fno:expects ( grel:param_a ) ; +# fno:returns ( grel:output_number ) . + +#grel:array_reverse +# a fno:Function ; +# fno:name "reverse" ; +# dcterms:description "reverse" ; +# fno:expects ( grel:param_a ) ; +# fno:returns ( grel:output_array ) . + +#grel:math_sum +# a fno:Function ; +# fno:name "sum" ; +# dcterms:description "sum" ; +# fno:expects ( grel:param_a ) ; +# fno:returns ( grel:output_number ) . + +#grel:array_uniques +# a fno:Function ; +# fno:name "uniques" ; +# dcterms:description "uniques" ; +# fno:expects ( grel:param_a ) ; +# fno:returns ( grel:output_array ) . + +#grel:array_sort +# a fno:Function ; +# fno:name "sort" ; +# dcterms:description "sort" ; +# fno:expects ( grel:param_a ) ; +# fno:returns ( grel:output_array ) . + +#grel:math_exp +# a fno:Function ; +# fno:name "exp" ; +# dcterms:description "exp" ; +# fno:expects ( grel:dec_n ) ; +# fno:returns ( grel:output_number ) . + +#grel:math_ln +# a fno:Function ; +# fno:name "ln" ; +# dcterms:description "ln" ; +# fno:expects ( grel:dec_n ) ; +# fno:returns ( grel:output_number ) . + +#grel:math_log +# a fno:Function ; +# fno:name "log" ; +# dcterms:description "log" ; +# fno:expects ( grel:dec_n ) ; +# fno:returns ( grel:output_number ) . + +#grel:controls_isBlank +# a fno:Function ; +# fno:name "isBlank" ; +# dcterms:description "isBlank" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:output_bool ) . + +#grel:controls_isError +# a fno:Function ; +# fno:name "isError" ; +# dcterms:description "isError" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:output_bool ) . + +#grel:controls_isNonBlank +# a fno:Function ; +# fno:name "isNonBlank" ; +# dcterms:description "isNonBlank" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:output_bool ) . + +#grel:controls_isNotNull +# a fno:Function ; +# fno:name "isNotNull" ; +# dcterms:description "isNotNull" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:output_bool ) . + +#grel:controls_isNull +# a fno:Function ; +# fno:name "isNull" ; +# dcterms:description "isNull" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:output_bool ) . + +#grel:controls_isNumeric +# a fno:Function ; +# fno:name "isNumeric" ; +# dcterms:description "isNumeric" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:output_bool ) . + +#grel:other_htmlText +# a fno:Function ; +# fno:name "htmlText" ; +# dcterms:description "htmlText" ; +# fno:expects ( ) ; +# fno:returns ( grel:stringOut ) . + +#grel:other_innerHtml +# a fno:Function ; +# fno:name "innerHtml" ; +# dcterms:description "innerHtml" ; +# fno:expects ( ) ; +# fno:returns ( grel:stringOut ) . + +#grel:other_outerHtml +# a fno:Function ; +# fno:name "outerHtml" ; +# dcterms:description "outerHtml" ; +# fno:expects ( ) ; +# fno:returns ( grel:stringOut ) . + +#grel:other_ownText +# a fno:Function ; +# fno:name "ownText" ; +# dcterms:description "ownText" ; +# fno:expects ( ) ; +# fno:returns ( grel:stringOut ) . + +#grel:other_type +# a fno:Function ; +# fno:name "type" ; +# dcterms:description "type" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:stringOut ) . + +#grel:other_parseHtml +# a fno:Function ; +# fno:name "parseHtml" ; +# dcterms:description "parseHtml" ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:output_element ) . + +#grel:other_parseJson +# a fno:Function ; +# fno:name "parseJson" ; +# dcterms:description "parseJson" ; +# fno:expects ( grel:valueParam ) ; +# fno:returns ( grel:output_any ) . + +#grel:other_jsonize +# a fno:Function ; +# fno:name "jsonize" ; +# dcterms:description "jsonize" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:stringOut ) . + +#grel:string_toString +# a fno:Function ; +# fno:name "toString" ; +# dcterms:description "toString" ; +# fno:expects ( grel:param_any_e ) ; +# fno:returns ( grel:stringOut ) . + diff --git a/src/main/resources/grel_java_mapping.ttl b/src/main/resources/grel_java_mapping.ttl new file mode 100644 index 00000000..e1c7970c --- /dev/null +++ b/src/main/resources/grel_java_mapping.ttl @@ -0,0 +1,322 @@ +@prefix cc: . +@prefix dcterms: . +@prefix doap: . +@prefix fno: . +@prefix fnoi: . +@prefix fnom: . +@prefix foaf: . +@prefix grel: . +@prefix grelm: . +@prefix rdf: . +@prefix rdfs: . +@prefix void: . +@prefix xsd: . + +grelm:void + a void:DatasetDescription ; + dcterms:title "A VoID Description of the GREL Fno JAVA Mapping Descriptions Dataset" ; + dcterms:creator ; + foaf:primaryTopic grelm:dataset ; +. + + + rdf:type foaf:Person ; + foaf:mbox "mailto:Ben.DeMeester@UGent.be" ; + foaf:name "Ben De Meester"@en . + +grelm:dataset + a void:Dataset ; + foaf:homepage ; + foaf:homepage ; + dcterms:title "GREL Fno JAVA Mapping Descriptions"@en ; + dcterms:description "The FnO JAVA mapping descriptions of the GREL functions" ; + dcterms:contributor ; + dcterms:modified "2020-01-21"^^xsd:date ; + cc:license ; + dcterms:issued "2020-01-21"^^xsd:date ; + dcterms:rights "Copyright © Ghent University – imec – IDLab"@en ; + dcterms:subject ; + dcterms:subject ; + void:feature ; + void:exampleResource grelm:boolean_and ; + void:vocabulary , , + . + +# Contents: +# - Parameters (per java) param_{var} with predicate p_{type}_{var} +# - Outputs (per java) output_{type} with predicate o_{type} +# - Problems (per java) prob_{var} +# - Functions (per java) + +grelm:javaArray + a fnoi:JavaClass ; + doap:download-page "GrelFunctions.jar" ; + fnoi:class-name "io.fno.grel.ArrayFunctions" . + +#CONCAT + +grelm:getMapping + a fno:Mapping ; + fno:function grel:array_get ; + fno:implementation grelm:javaArray ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "get" ] ; +. + +#CONCAT + +grelm:joinMapping + a fno:Mapping ; + fno:function grel:array_join ; + fno:implementation grelm:javaArray ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "join" ] ; +. + +grelm:javaBoolean + a fnoi:JavaClass ; + doap:download-page "GrelFunctions.jar" ; + fnoi:class-name "io.fno.grel.BooleanFunctions" . + +#AND + +grelm:andMapping + a fno:Mapping ; + fno:function grel:boolean_and ; + fno:implementation grelm:javaBoolean ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "and" ] ; +. + +#OR + +grelm:orMapping + a fno:Mapping ; + fno:function grel:boolean_or ; + fno:implementation grelm:javaBoolean ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "or" ] ; +. + +#NOT + +grelm:notMapping + a fno:Mapping ; + fno:function grel:boolean_not ; + fno:implementation grelm:javaBoolean ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "not" ] ; +. + +#XOR + +grelm:xorMapping + a fno:Mapping ; + fno:function grel:boolean_xor ; + fno:implementation grelm:javaBoolean ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "xor" ] ; +. + +grelm:javaControls + a fnoi:JavaClass ; + doap:download-page "GrelFunctions.jar" ; + fnoi:class-name "io.fno.grel.ControlsFunctions" . + +#IFTHENELSE + +grelm:ifthenelseMapping + a fno:Mapping ; + fno:function grel:controls_if ; + fno:implementation grelm:javaBoolean ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "xor" ] ; +. + +grelm:javaString + a fnoi:JavaClass ; + doap:download-page "GrelFunctions.jar" ; + fnoi:class-name "io.fno.grel.StringFunctions" . + +#STRING_LENGTH + +grelm:lengthMapping + a fno:Mapping ; + fno:function grel:string_length ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "length" ] ; +. + +#STARTSWITH + +grelm:startsWithMapping + a fno:Mapping ; + fno:function grel:string_startsWith ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "startsWith" ] ; +. + +#ENDSWITH + +grelm:endsWithMapping + a fno:Mapping ; + fno:function grel:string_endsWith ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "endsWith" ] ; +. + +#CONTAINS + +grelm:containsMapping + a fno:Mapping ; + fno:function grel:string_contains ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "contains" ] ; +. + +#TOLOWERCASE + +grelm:lowercaseMapping + a fno:Mapping ; + fno:function grel:toLowerCase ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "toLowercase" ] ; +. + +#TOUPPERCASE + +grelm:uppercaseMapping + a fno:Mapping ; + fno:function grel:toUpperCase ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "toUppercase" ] ; +. + +#TRIM + +grelm:trimMapping + a fno:Mapping ; + fno:function grel:string_trim ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "trim" ] ; +. + +#CHOMP + +grelm:trimMapping + a fno:Mapping ; + fno:function grel:string_chomp ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "chomp" ] ; +. + +#SUBSTRING + +grelm:substringMapping + a fno:Mapping ; + fno:function grel:string_substring ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "substring" ] ; +. + +#SPLIT + +grelm:splitMapping + a fno:Mapping ; + fno:function grel:string_split ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "split" ] ; +. + +#ESCAPE + +grelm:escapeMapping + a fno:Mapping ; + fno:function grel:escape ; + fno:implementation grelm:javaString ; +# TODO if not clear + fno:parameterMapping [ ] ; +# TODO if not clear + fno:returnMapping [ ] ; + fno:methodMapping [ a fnom:StringMethodMapping ; + fnom:method-name "escape" ] ; +. + From 2fb9377a5029a284c4e67a8acbd2c32de6f4824e Mon Sep 17 00:00:00 2001 From: Gertjan De Mulder Date: Fri, 12 Jun 2020 16:10:53 +0200 Subject: [PATCH 035/169] wip: feature function #25 - added most recent GrelFunctions.jar The "old" GrelFunctions.jar is renamed to GrelFunctions.jar.bak The GrelFunctions.jar is the most recent version of the best practices example https://github.com/FnOio/grel-functions-java --- src/main/resources/GrelFunctions.jar | Bin 287602 -> 291954 bytes src/main/resources/GrelFunctions.jar.bak | Bin 0 -> 287602 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/GrelFunctions.jar.bak diff --git a/src/main/resources/GrelFunctions.jar b/src/main/resources/GrelFunctions.jar index 9094cba8d5c1814ba09f143a5542fe5d30b9a497..ef7c392b8c4b231b8c86d70e4912d694d2f2c736 100644 GIT binary patch delta 11058 zcmb7q1z43$w>CRy*nl*MgmiaGcXxM*C=C)48&DBxsfQ8-5$P}xlukiPcqIiS1q755 zkounuzKWjjobUSgb-|u>&sz7)np}HkHamzmmxvHL>M%GC8tS8*-mdciaT#9;{J!<6 z(>DghN*_pFMD|wU+~y?=osmrNdy6|?Nh)4bG$4!Rvl5b~KUCmUt5D=_?aXF*;=V`Y zMZxMA$fRn!*nRQQKyhja4o8=?HA8)>L&zgTjyvgfuGQWDXs@#HBaH3zTd>v2GML&9 z-#=iSPB@yQu3tM0K1tST(&e}p=1R@?r27sfMz$?Uln!3>Cts_Y{sU>}Cm*PjJYiH} zn|C)McQ>JTH(@U~;XYJIG&Dxj7dod-{QL(4zn$HAemnQK0_K^*Rk#033GcU(lb55* zFFGu=_c84{qd_*hYFKD!f=D7XH2S|(^?kgY-JFzey4m|UySsUF+q>9$dp|VVM;aKD zo=o*@GAEHgONI;yntXRiB*YSQ#1_O2gEM0@F+%k20$u8h%{_swJ=DS+*IivLR~mHv z6q=2$dr;byj1KFu50A$;?i&~8#D`q33ZFi>icGv3z>(1JJFp?1&l)KdD24#6l}n zj*t}?8$v;r<%bbL`H=GLqHhKxcv$`uWkh|c z3V8ZoyBH&O{<-8TTCUE^QQVICBALE(U$p{BBQOXxBx=1*AygJom3*n+{Uw*ZlI!h2 zPi>@yNat!=Q};?O^9PO06@J%X4Q*XTLSYpNecxLH3B}YF2JQsIS4}-F1+W)Yog&bo zuf-BEaTU0RhVhazNyd!Y#0#G0nPni#YHo+=3+k0gr)L>#d5P11itZ>?(6c!@sJ@AV z97!6+)={}V)b|e!O-_CfX|F`avuh)g*dghcV68POvWyvQ!Ovo+I z)NS}OJ^7(;?uEu=zH&H`fv})to!01UJfwjg)@^O_$1J-UT?6g~0$uqj&vqUlu$4H( za0IkCW3$4rHBG#54F4tHa3+>LP_n8z0QR(!*2pG>w{`scUL6A7GXYP<^y1 z?5Jw)m+ot$)%DMBboQzEX@4!h=eN7I zOiS_cjr+-pQ0$En$${-pKk#=jjku&ptxPRj=XypT?|d<=i!mlSv}!M@$+LsMjvDbW zZ2wY2SGnpYC*Mvxk8Pp9p0exiFKIlerc`H0RWQ}5Z{-rNOam$n>-ca!Mq`v-eG~B*+6Pqj=c(4l3E;b+n_KT) zXj63Rf+dGIJ;TyWzU~IO)OM@-Zs`l^t?t->1sT!kaBTk$r{(^f0@^0#4EmkSDzS>j z^b*{8iyC3vukfJfkW^7LT(9U&G~}~a?Hh#&PbNvbzd~QGAauCab)s

HL3n$rs6x%=&$Cwg?;qMEZZtUD+?zS^_NXzQDx( z%Rm4Bn8#{WwB^x+&_5y5+^FDEq9Qy*gy=9dRJt)4Af%O=0u13`utmx)L1bFHrms>$ zIQ*0D6i{W~zkR~j$A5wyWTr*y_z*fK^O+y(^m6UwG`+n%h0B8g0Herb0dWIZ+>U%v zI7}8;79+BxOIDH+(r4Ned^N)naf+qWYSOsT`)=s&So?+0xL5R%gf2ezOdQkwdW_BT zFM5<66zT2S7<3lAF+|LJ9&tVsvpKk0Mzdw_Nd~9Qxbjn~lMpC}o&#hugLl#3lQ21t zUE;EJJVYYDY?e~vq=9d(@VNHVY1$L^hrIIO%JfJgLXIqH1T~r6gV7g*w690ZOD3J0 z+AMHiDK#Sdc~b;Dm~FBO>5#jd359pIN|Za3MV29V4iPF|2E!<&VWZak*eIiZl`rh2FyX{*3{KS5k`4KUL6DmhI?VOp55XhOwnDT6N=)+BX7S=xMl+uxUPS*s9rSLC8&r52u= zJz2N9mYx|3@beRr?Pp@eCeW*dt{-OfnKv8*#L|@V>Rze&H~YSg>kgZbqSyg3G4LJE zpx}GPY%=*8weC{)m;D^zG*#7n+~y`u)Ub8#Ce_jgc(>5Yn8XP*b$sbgMZTk!{F<$U z*}4}-K+*KFe88M;1|?VKF{l((MwqUQpG|Y0ZH$#fm2$WD zwcZd!4%>;u&~{7t)oFX~CxRqbpm+rny1%+8rdr?xKRr@&G_po`9hQm|HT zon2L&z!eGlKJDiwGxv1J%qwx`gxC~5amrJw+8T{;WycZ)Cml;t$daJt4><}EOK+nL z2NM!TCS!=9wLV1dwMc20?7}n3%ot&&L_RcAwKK;Q-9y;=>XznO(UMA&qwN0G28J0? zAL5TMEDfF1d}zMMaOKpPk_Y?4zUS{A@jp#Uv3k-grDk68yqsw`F;0vid2sV4IE@wQ zn3ZuR2UQlD_zr7iHzNGKs8LFL-< zaAJkj@3a&PExsW)!+c(9b%g7Fs^1NuVN(_lE}PnaQ`H-P>rXW0zig7XvEJAb+98<@xw66oFZSQ;LG&Wx@zY;YLHZT4_P>`3Wea;J7X>F%GfR*EN&6+q+AsV=Dr`50 zne3E>smOfN@#iHMH>2A_L}41&spUv^m27it8&eO&E@Z|2!V_@B^%qLwK7V_s9IjDT zz3(qXP2)Yt^gX%#{rmIvK9(>45i8N9t z1JtrZ|c}Za; z6r$K|TA+}=H(dw%sxSH0XZuk}NiA`UHz*Sl0(rA0mH6@}pGKAA-j9`}PY zk<63#OGO!p^{lWtY|wujfb zoU*%hoqGpfoCc`YbKYL+wN8p2)$CRrgS#cHTOX*c{Qpgvupf;DL3}Baj4!c~_+Kj% zWlLKJoBv6Vlq&7WFDRgY($i>jz|J5jD15_c$!@&kH#RzsV8Mt9C3`ipTgkpmsw2C^ zgZZ2K8W4%}{7339#X(1{kfaY0`i z1#O+OVC8Zm!>8-~h`a=@eh1P&iQFx2dI&b>jGw)aSym(hew^pw5+txZst^|!mdClw zo{J?)audlb3rXQ|$b}&a>;@+~K;C))z_^Iw!{P)I4GB?CbUt1MI5*%~B6kO55=Zxl zS~A*juJ{EGxqija;o_wT6a;k=sCOw8ukXva>et zGV*?2NB&@^9~PP@7rrbdPPWaCZyA5I?#UeCorM!EDdF~-SWxV(w!&XcB8GPn%SxUd z#3=QOqKGma;3rYp{#mPO{@2W{I3Vr#A+OJ&%f5R{-7bBgV|9LgHKaGzrRitP52Y0D zSxZ>wd*MmBJZ#?=7jj_3@;k^fEv~V&h*0ocjVwWNhT)m6nl6Qo5DcTdK}Nm;yMXb` zdr;>KhRiWXP1X(*lF3H|8eDtU65SlSXCI~}9?SNSkN1S;BLAP0Os#|FN3F0G$55M4 zqt`ynhIgEQU7Rt+(l5*6fPlm)|7Vat|AQVX)rRs>QC$`|na)lE%KR#!AYEjXiV(D6 zMSw{(s3?TQ2sa6sOBkLK9ne!yR~KstvK8BkNHu~)9%-cSd~8uyQ2*F$sa<_@pYi5k zV6oo@*HgRe`pEkuaN>XE`_${n|L0Al>sx^mb`HqO0W*hA^ki=Pplqrj@#+mJMc!{n zs8*+6(sq^yCArCn9Gd~Pyw~V*+*~kDs7{98Ps%%QSZCBb9N13Eot+>l%sX#rXMVZu zapmMs0zGqbt_R^b^@o6=Ux=80qII7sW*8jzN^}0Mg{C|DaZ#v$fri?3qt@@6;8CbM zJ0ZC1T#R1ac+qe51HI(f9h^ugI2@f=kTl1Dbi9|C^ji~n{(Fb)a_mk{JQVH@PUUES z&xh?OwntiIb2cxBy*c|hP~ryO+Fb-FkbV|lIU5nHvpYAAL;`c{k4&=B7C8MAlJP0b zobZoLy3m@qzKkSt6vvLA$P`^U8sjfRIlTMBMl1&q!j)q zCh<7=gXL?z{tgd6pVoJb)-!3xq*;w znfjOWmW88ci8`O>7LKE4fm)yYmL_gkjpB19QlH0BKzRASZdsv#X!baNV;k!nzM0M* zzSi!6gz~}G_H!mnO`q`;iP(e{Qq8Ry8|sL)&f*$=`uv^&u7=rd+M*urSzFueSqM@%?Be%gK~3v-M0$ z=WA$BthDjRy(Yq|%1RE^*doVFZWA<7*BQ+=umxhup+XYL_| z4KdeZ8F$grK;^5Gh54tMFwmG=7VOeZ^I3rlF1c5vfF55~jX+xqVAUa*gV% z*TPa5HiBfWz#&|7QrDums*YB)xPz{`b@ld^cxuO|Dk%dM7Ux#|#PWHhPI;sj9nETs zQ)#{P!&E87OSTBg5OXp2{cYsrM(sI_E;WYSe?UV*1|w6{fYEb#N~$?Up1v1B%?cx1ObcVOZy_^7pMp(lBmRP-@Lg z#LyB|%7`Lc{`>aQGRHU*(JUsktnklNr+i#3lmcj(dsmm|4K3_0ZV!N%B_IKCrPVsM z!^O|;p%GzRxh`|Tvdw!OZu&$|f2_Z>x-ic+&l7^8WkkQaU%i~9* z$A+{%RH)~*u#!7Qh$3c)obr%WR*TdFFK{A6TvevHMJjnoD!Ep+N|9noBU`0fuBwH- zQZ84;+%^dt7>h|x%YRB{rB0yTOe|Zbp&dXDx~PE|@_x@bUM`XZy=%pGRi$Zv-RL-5 z*UT%rv0y?2TRzetr3FaTw3I@XZz}2HueRM~M>*{Q|V!EzqE^nc$yC;inos*{#=MDO*2h!fo#&;mx z^MC0i@Jhwl^*vqdtit?ymKMl^A5?6O9Zx1ZDiR2yQ|1Hs+3&{jJcFl zq!87kRBkCulr@pC{S6WAn8gMav_#&h*!DVoFM zVaMpF-|Co0&$RL7$a9n}*obfgx^lF-yRs`6{JG@jJ71cijH842gx!Mm3*JHPQ8f30 za2qOy^@H*!iGO^cy?K*6PA!e|K+IFW@%9iOAh?l$@E^>_c!#J)Z--;2a^RqNa&Tg> zDLObag18EPt90lFMXCsmgtZBK!&n^*ZmkNQz*sGN%q{E>-dq`y(zxW23B1(V7+@O% z_j_WJ3e4r*WD0yzPI^k<&dhSJ426N^ol?f%J5==mM)pxZ<9yZ`fPNNA3X;K)Nd@-& z{6)2f{w$eCV)UO%nBeSgizIqqd1v3@AeP_Loacs3KB({h* zR*pHY;gJ(C{`5I=%n`9`P3Do=60cG%Z#G6!Jr@i79EmqPf<@4M)|IEc=64Wytl#4d zxy$zTk>5$YtY0r{FWcJccDBp>yqey;hT-C*_gX@Zd}%X!ugVI37|!e2;}`qf%zdTt z)=-05a;NFMcte~=iD&T3?aUdXW?JN5>Z?k}jn5R2N^Vr~-ke_9zDA0Z=*1?desY4* zLE@O5>BawwXK6D7nc#?ecT3zMy5m{mjgMzZk?{dl{L>}o7e9WD!Idkz`2H=?9`glr zu21!FL-Z|}_!`AiHibLJr1`$AC(o&%y`}@JEb$ZMdJ76z1 z1=>LnraVN6Btd*)bxuE)u8AJx6WhxJk>oQ;n-fHlLchPMGW-!ztN0r>>Y$(Q&O@o! z0hPol^|2IncA$loW%Q#Q611&OHi61uM=!Tup zgRi3()hjaLbZLmy6EJD~dgBR0WPmo_j>YSN3qN>Zh@J-$et?=0LLrPmA8NS@&*GRF z<&XNc_{V+4Hf#xo8XdT}fh@!Y5AV-bNm@!>w%(%M>eLhsH{05{iTi1n>acFmSf}B- zslirj6ca9PKwuo9VMEc4w>zp#h`|Hnjtt8PPUfK%5)XAj3He1sUFcmg`+Rs}a7&&( zm{e11ggGNX!y}&E8~$lc6NX*S-Qhn%18fOl-;<7`iCN9gu$x?BHHC|(+{p@W!K#?5 zqa}eTXi~QLb6l0Xm>FswaEln|+mK6lhK-kuU1NIfDB@`t<8=7mGFWkkg`q{vS8D6h zh{d@yhOu~Ee?5js7C;$jC`;;YeGA4EraQmCx-yAFbl!F~ow7Qt{-TkvF<3UiH3l(uOoe;QD zkiq_QufjIw3l9Wu7JBP~WEYKXy?wYVRhI69z!r@8qZp?ga(cOpiAYuTcfk3Bg3c`` zU>l?(WyvPMWx|R>kk}Z0D20x-EG{cf6NzMXjrwtHH-iyyIT|l!N-?WQ48PEMi-Bzw zjc)}v)UfrOQ1P3z+*;(isBmFLgbHbT)~kF$AIr?;z%=n8bIXG~HW!1>4f7+^(2XMx zOEZ5Vw#mZA_ezLt|qGH*TrZdtDE2b>dXE2Fo>uJ>C5+>v@x5_BLie8SR&g~23UNM#jnhTrb%p&6IU8`6MVEcIkc%2*ipS_n z`xsf>hX%*JWH=`GnNcK_z#xaL}lg`oQWBn|OgsS=?tNh(X7mQ+%x)X55Gg4PTg|pHL2fmPWs0XqL52!F{Q^456?}v{$Y@W*kKKm?xu$?|UzS(dn_WQ*HO%cGSa89Mea#z@RO&=H%tbF` z8K7%jR>!8ik|m|p_dV`I&b>x<>716t7LO^eCk9>Dj*7MSyV*xUHktLTOB3vnLsW<6 z7xrGP$+E1;@^spimq^Bg2%tNmbq1^HidZb0HgoBX^lyVeQ_!(lsMLlVvo%y^%R-W- z08En~FK1I8shEG8$+G-lP5v7TjfvgzWXUB4^Mxw&1)Gf72l3SF%kGp{KDw^~utq;b zv+vPdExkiiKdH5TyykC`roJ}w1&85sy_s1qw()X($tlNIBl4+NzN<7Lo)yb7v$f6L zpJc*GvVrj0Nn}l*$Yvk-O{NL0s^U#HTqTq%Nt*r^W|j4O(`(q6VN1tm2o$y?<26dm z)+HECr!&=ArPi0m(apK|#%dT;+>23~RiNxL=M2!l7&)w&Evt!|tbjFCX{+m`Q%O@n zH&a+mW{E{>|13AcK;T&7hl{BG&Mi~u`gJNXj`51ZY{2Tx*bY4n6LKu-u;F9k#)7`8 zWzcTRrLrm))X7b8PPQO<>{d z>NJtY&HgJ9A@5y=qg%WW9Ob6=cu&V8bhJ`M!sIn-)M-+yc-hAB0`E`GR|`g1RA9!E z3k_c`JQtXgt+{aGB`uaA57dP1$zWkCTtU`rT!Sunlg;;wl_?!=9G)`+gYxQgkB32E z%G7dfZY>UvHiug)qndcSU&c!e>CHxsSZAb59k0x0G2fjyXXBvp&NuUTXOG{CW!y1k z++MOr(GU1&%1hcUmsZRV*pdypGG%&DWUUvGZ8!z3C_I0i*G=oI9AS!~+|gtH%s z9jU+3q8xKmo>D};wXD@<$@Co43v2RmmG-j&6!1v@*hdZCcp62LIiy^c;gm9MUPGl{ z21Yo@&!&={PN2G&!VI?IUfEsj@rximWghSKW)FTa!9I;qNq>s(eUf%uQo%l%Q*P$B zpkGBY?bShdXAiR&`Pj6li$ZaWJdCHhoT`9%*TZaJ|K^CeC8=O0KX*Q zF+sZ(Etw|*`1KV#qdP?zfZ5kPe7&~%6x0)hJfDm_pJeu~+149&wP zc?OOB+{qN@fLB0fb9(R)KkVkCw9}*o<dzAj?SW+(V!cgS}|0eA^fV--!COn4O-gBoO z*@cQ>q3T4`TlB+owHF2TvP~rF197}@M~c*K2?h-Ohwg zrS9P=)6F3jutj~?cJ9GpcqqP~crXe31yHRdOh&%P=djMMp&hTUQzOimU(g)5`W1QN zTu)@_d=T_X>P`$l+=O<%JDvM(DS|W>C%7O+?UHM*q{b9mNSN4B-y#z|NfNE-wSq0% zERR&?UvN#346nK}x#7kdt1uZiNJmtb=Et# zkVtXHofZSO6mh;h#Ql5Zt3!eb7mY^9ji=Y?CJ z4_2Mxf12_FlMsc~c!1}O>7i&EX>oQ%mF`Nhka>3Jxl+evrPzBqf)2~WOqY6w>xyN9 zNil+Tj1W%ETnVHk2^TQq2#x`pWC1GKpj1qt9b4$*CeDOp;)G8q32z4=YeWHy8K6|m zplgP(CCj*yi74X-;D?c%f`g#r=rt_glngde@>n38;N>uq%i##6nq|4>8EkIS9s~m& z)qRrPD%<+cJfP6Wx=`AaTy&()-6vwIx6#!bP*y0)+RGlIt5+ke1@>OU9DF6(d*g$x zyZT*gsOp5l=qWPxtxmtI7k*1u{tu@SNTAhO4XTQ?TOI6r3GQauM$t@0Scg&7 zaeeGhFz;It>qNt>+=g6)aJI9<>BN?`-^H}6W$b5dFx2sq)FJPk6YG?t)Tuf;*rK%` zXWD73g&|CKjH0jj{6V1E_-V+s613%MnuA~+z4{X~0~Gi*fk5LwqD48BOnI1%O%iLhgFthiu&4wR}sOk=0N7$w!tQq#! zCEEE3bqGcW9uoRpyQ%6>#C7yD_qhx8bx2~`{U~(&0~SIH+Dkaw-C%TN0FJS&yH2GU z``is*^$6`cVuW3gD0QfVY@CR7;SlusRP^;I>ZMe5r62ou*p9NqIua;flfuS@SSO*P zLvOSES3fy`8`5B(zTINZt=$9X-SWGRaH&k&K)(BcsY<60j!pyIveMavt-}(%hD2#~ z+W=eFt`@a!8$v>%!Hza~hM3F^_&DjF*epb;17b{Iw9p`CSd3pg$}_WRxXiBCs-W|- zq959kHC12c-6UmS=v_2rAI9A$!M}RvT%FNl`M&(XGhcq-|6g`=5eq{nF*{>>lP~;| z{|k7dtZk1fgvAF2N1LLhRoYVVphi=$fzbk9%=Aqd4Yj#U2maBJg%)QO(hb;%^?{b< z@dnp>Q^Y`?^=!2t&+ON}z4+c;g@E*gnEEG8S?si_X* z;>b!hY!KOwy|qP0Z?r7J<4s8{%qzqy#EvNhoO+zF=mu+)WOf8T3I!PT3SG_&{KDW3;JrmgD} z;&{r@ml=C4&f4Wi(peuvrsrrs{My+J^_!I$rPGVF`c`1<$GR5t+QLc zP<4N>e-%QgqdKhYuONiguZ!yc6O8Z=AyhK7GdCq=`Y#y_jnRc2WJC@z|A?*?;}sUm zN60HAd?sB*8~%A8&YoBTt2YgWv|BiAF`(|QxoT+Edvfs!LYN2*9hiZ9^0?1>T@?oN zr$*(f0x*!RrHer{VP8hmQQh1h^Ruxo;k?ELsI<}AGCD~bql zjqo31H8gfHb&~qJ3|;J<{_lBR)nCf!>d2p7?yH985(yAxYZ_uD+|4CjXw719=d!&8693dA9$<*gHjc7Jkd3vDL9{+qP}nw$rg~+qSKajgHZ= zlV7Zxd+vTX|9!_eXOH!?9@fh@#+)^4uKKF}F{K}Ei&4>Ab;Qh-bP$jFVtc-;>(f?r zR0$2|fa$3;R_ue-Rd*B?;0-N14XCP$F&>>7k2l zR;%;1>(|`sEzs(G@maCXtv9I|puHn^OZ}nctV7Wy$zf;-#NQ>PENdSg?2?J2QO8-a z+uv<(qp6ul=iRKb)$AjgYgC4wl+T?f@zZoC{4o2{3Oqppn607pX*Hg^4U)Uu#0%Ur zFieN9tJNJxXB|aHXmk-im`;44a;QF{jmap~@Xb+| ztU5suRCJUcvR|KSj$v@Cmz)k$4H^FF`^A}hP}RQEFeQVgbcE5;;t;L9=UEr`D+bwH zM@>44&LjoOq_!H;zE`Q*%b(DF)w&7glJHJ63PG&|kT>M#p{FE+vr>pifg* zXSP|SPmr0HW$gjPu2Yfuq+|}uMx!J>h`T#LsNj`Hpv$l*Il+F1LBgOjVI%FHyaspE zF=P8kl%G{dcAL5&I+?*KxS@zpfZ0#<$;0hGlxmso6(`)H@{r4rz_MryKsFJtQEl_* z6?`IlI|8rQyAumjs2|!RXv`6f8#ls-p(B*hSP+Zm6j^hMvo}nV)h!|0D&x^CMzdYi z^PSH4qU7@pauMvnG3Vw5x_28T{W3@9wS3{1dMCPRl3>|Rg)yUaud zpfs(J;4|qQq~*qQp?jrz;Nhyjl0l~=N>||mdywuip&B}$ z^3)R?j2s4%clpcVJ~xvnf>K`=t6OXxTj&Hv&@ZXrz z(w>fC*+TZS)SeRxp9uujOf`Esh$o+lw@o;nfCxHzO3%@FAn|qCqXkM1DR2}2WnmRZ zrNNG%6d*7V=;3+hyOyjOYpuWyPwANoDVZtKQzbeU5~OKsEIm0y>&zN^YzyRY@DZm# zHK(ON+EqsIRcATJGrXSPfj-)=dIK`eSkW;DAoequD2i})x~;6(kw$^iegl{7%w0_M zifcTDePv^dRZRHJCr{8FuEtGVxHqS4EQd^P(sE@jnu|F(CGd7C=3ZG4*jhdZ#~I{` zOVv0Vm0SNR(y$aImat8-rHX2iy}Uih^`yAlHRke|BMT+w$l(I%_FrJ0l}kw8Rb4N_ z?C}WU4!9(9Q;k<~G{6qw$HV_lOyQ^)2z@rh7Rkv&zl^a}?;;fOYzZ0F6hxBXPDm3s zAjxPKS-vHe8C7;AwpPNq{8JYUg73w`NA7Z`DldaBAks~U>sx@Pvyu{N=iyOW*|NmX$6>nPUE+Ai*l29bf>SuCS#yPh~ZW1N!h|)z#LLj&qP25H zmKu~8VbGvSMhe7Ln%(HHB?aKP?Cx-SmE$hWfru_Sla$=aa1`DlbhDOD%c@nN#wm^B zZbXKrby(byGM$$K_h4ID_V!$ea05VvR77;ohj62V$6ja>HBtB}ezRLdzj><~qp&BB zqkC`4L8;~`u_4YWniTsW?D!y4%G!nMMimEd{I&~=0IL;srGiqxis)-X(rKIt^o%3a z^@>pBLO&rJ!QPzaB94DaaD8a-qiS&W1yBS*C#@ksUJ{CB)%qqTlsrn|PcWP`1H@Wj z=6zGL=_8MmPg)k-xh=<`XRZp^QiXhy=Xa7U>Du(5vEw=O=_9+VQQIqVr#zsZx5*sW zPMlr=?AP{?&wSp`%DdQ^B4QP1=vBf#ymH&{d7p{%w7Q99S`m^Dv|G_Q_GP+21W1L5 zR)Ak*pWIbUBHy4KRHE&YWduv&?PQsHVE6?Vh<2CzcK0pX4=vhw+PnwB-BwRlyoX3J z6F{Ilf65)V=_c=cK~}u*ECYMZa>W`SEX;B%JyV_BF?a+hFScSo;~ogL9uhZ%r{5v0 zJ1{s3J+B82%||X~J1}22L2Cb3;Od$-2Lh+hhh(8~_0&SRCL5wz#VkkoBm>q5wRcg| z=D?-|Stz$T5}lz_x`D0titW%vJIv}IKRgBlk%aW~4;I*H*a8j=A%_&)@zn{Bl;;~M z0)c`+D2{y!>Df8V0S3-+11IQyG~8$Bua5MyIFE@#{1Kv)4vjxyrQ3M1TVZQ19B*vA zYkOo>27@k1RCc8n5HqroVaDQ3E=%)#DnoUNL+~F$6Yt4&vj!u#4q$hPjUVlM*ls6S zZpGo}q<*{+Q$|^bHm+b2c=qEZ)`7={0w`F})Uw2E#wSBNJ|&b(MMZ)lGhXlu9818x zhyU8+6|3+MPI*B@CUMmt#jlIss6Q6=LfBVkHIHRe> zwP{m-QR5@ADT*QqDMhyi@zWLI>xhDOjbLA**({K(?sq^PHKUf`Bo#QDVtj%xQp{f@ z?1;S{vwibghZ7qkxQUf&g}}yLc_8_6N;SFD1>CUnx!=f3o$!~>_Ws705==pjr4Y)Y zhgDMMP78A^G-w0Wg#BXfmSn_-)|2^Ex&21`PdGVPF^rA)nIg-7LO*^oKY$#ZEf|a( zjZ7@f7)%`O>>TV}7;Jw=WQPBDepE4Y{jaG}-9|CT0?mJ?w;}t81PNJE_%E1qV6R}r z!pIhO>E?*-RBZxIB>Sso-_V#@`Zay4P_1^c-637=V^S5Hs!r7+I}u%A0b3l47@k9M z95;7y@z-O#Ku#k!JO9ZxVj6gvSzF*X++T*Dm07I93gm#n=lXPa4Jay9APo zfFqcB>t>j}gzwMGp3p`(ZP>p((ECeJe%pay=9~v3_^{|ZAzw*#g0y`iEPmpqc<)=L zOoFGqL*{&jF^XF$Ec`^4c$g6rX5EB+6?|W9LjJ>13$w2r3=A{>t)FoFuO1AA$q#VE zzEcsxljZc0I|d)8iRg0PmncXBHOeW?vyMzo^HP>O)q6{TJh)rBuoP+PwCRlLQ${9c z(^f8qJ>UD>K3_NL7NibOoGZ<8TgjrI+;IWcMSGTUWgu{#gLKA3Uzuco=5PIj@C;1#@s)gg3xU9Tr=WXFv4|-dm)7ROYH;pCgs@UcZ)Tw%*m&Fk;K ztSPY+S=uu~Ae=1fZHo4w&su*go&?OPF5&(mSl)Csoq0An7&u~GcN16Y%S?|at8dN= z#;5WdKao;WIY^C4W=b7&w1eCD)h$bq^+%D)8Wc)4m~hR(@o=hHv$ zOnH3-3ymx1 zWXMc)KQ2m$qTjm&Z z*V_a#>p3c+aBp48B4-(Hl=Q7e>y?}2SrAV~{g4JMx2%124R>^lc6;<&bRyMo(^FNx zHQ{Fz@t%%<2cYtp9C;8hJ0xZUK+^&p4zxh$jFy8>#AHt$jFt!5@9;oPn0tV{HQv*B zaXf!9P}yq9OT+69sv(ZS>kdyr=nsYjqMWijir@N-*1ii8PoXzi8d9tqMoo|HACDzN z>`?uPY9ZV&O4F_vrmkXr;4V{-K-kwY;B?1J0;#qXfv%Kd#bJP4GA)=}Df5gs6UZ?M zX7!Geg7`%`_^nvnWL9RC*Sd)7@ukR+QJb2ZUZh!0k{Z8Usj&#!yt_wC%o${)0^PErEJl9oWG6wTTa6RV z45u350!Xs0<;!PWU;=~enWyHFnf22<{A5ZY!PEPCkD^OO4_9oP@u$yi#-cBz&*k=O zbAqW1b<3N6J9$NdVf3p)gj+g2|6EB_|5BP-yJkn%N9m~;a_@<~!25XK8`x~rx6ZkE zRNnU9v77U`^s3LRE|qYkPsf?*#H6{U@5xTf>hxjwh3jmMOU()%4obJbwg=C1cpBbn% zkL`XK)3^t6%tRugG+z2OEG`co{_E&6>B}se$B3sdPCQC@>DJXC+yj|LKac@6Pw;L9 zT)zL$!oN4N8Z(Uvo?ZmHEOM>Lcj@Am4N8m%;*G*l%6$z75BysVf#4>^_5R?9lU!@S zs=$2*&I=?$htZ*YF~}~N*zU0TtdOt4JJP{YtM5jbJD#8AY&H^A%wjZ*KljV>VDj^{ zc)e`LE3o+xi=&=dPuSJ8X=}endiBr|*5FP<00^1cv;Npq!>*tBYHWHV8GzaEx!aWB z31fmaGF64rZSTda+y*rhMq>f0?XQHWnTos^O@|ANSu@P6(w5S`b9{k6!i)f-5puP; z0=IZ(wU$USWqxXMi)CI5`zq=!3ByR%vF7W68WiJgLrjE3P6b z_Kb>RZY-E_$1VC`5ntj^O*-H|4lvbdZmY6|Lqa{${tuzLC39bX`oJ2S5z_hwZ8H*X z(t%+)y{#~{@G6?+j?iklH5x75Wwm#0(5iYtn{4df7Y?(HTrt!|K;OhV^~3Q2CNy8c z-XG~^4`aGUuUKnRImSPBDz|0*3K+h_x&ZhNjPkSCr02>jwJ?hkB%9&F6EL<9P|p0I zO)hf0LN#5xJqM6>I!Ce8d*$@O;>kwkTJcQd?JDUjX}Q@wTw6MCSC#2?+W8}S?@rB{4#2xwf9=felNIC=eNZZ-PN=c>zTFANh$7BK zWk<208cV{?e@(MtlQnMUbvw<;cIM`MOeud;Z-rDc!RN13=y<2%s@faGC3fB-l}a$qOsJGCKhlZ9owkWKJ;~&R z?X)1uqDSW9L!Q1<&bXLK&^{m%(BdF&?!K4H7({OUZ>U=j_Dz6s!n*t%m(Q$6-_7%9 z-_+T&2Y)|w0c1gixm+X)v9=mhe#}hl6#a0tI@n`0iW_ltU@}ao~F$+_o)aFm}0N*Ma0f)0l znaiI>$8RT-$v@EuTwFAKZIzGyT@_;%Qx{WFTj)?%jLlpu zLO4>uGyGguSr!q1#JOS;yHKc#cyH>nE2E0G2+SSE_Kn+hL<&pJ%xF`b8G6s z05?--*JaWQpX8&Ar8w66k&;yDEUrj4Ci=&8_;Idv3osC>VfPYckOZGdr$}O!O!D@b z(gm?CIx=~oz;zN?Zt@K(k4KZyNss>X|ij86l6NzY<*oH8}$>4Dj55bg; zWC`)aA^tMT2bDANlK*C8FJg<4TgMfT*ZoU)WFu4g4(|CJi|Y~GT4Z_E49w@rkm`k{ zP;CCU7ey<)vlt`NnTEw^rWas4cNDXfmlaBRzrMA3WKy=2-iAk#n-H1Byks)lu}NZv z-wu!}Ig%Iuamh)}u5D@piIm-7s%fF~I8aWtHf=V~QnERD{;pX2ojlP^($G_CDQ~UL zZ6$w$GedGNf|Bh6|4#u^m>hi^@})J9MFc7UKs{oin_`3}@u~@wtN60B?3GR#;$3r$ zD+-EDMTBM>KF3!b;}6^4;frS`Q90?+Sx^-OB1oWi6&Us9bxs{=4Sxcurz>=P#*MfF zcJoIEe!=F)Kd>Tp3Ea4+X6tuA!S)(Es$D;X+w310W6&g4^P(uOIu<7zqs}qxhbknY zW}AvY^K2{0@^m^d#p5jdnQU~t6a?kTJeJzdvQ8*CU5Q&u0F1DP68|5rt>R^B4wJ8{ zv5ZN984TD{;O%c<_GN1C0-mzgiw!i|&fnHQu}aTMb&&Ley%A9eod!;#YsTlYg1SBL zBI9U3I;>_C8LmD-kJ-iCbf`yMp?=x*lZ7~q2K@RW9G3N#d zvIiE)L%g-m^0V3EkJuu3;4{rYsLdk-H1l2_tnEKj2}gI4dep{9zwsp1uSs(!_rdeH}*v_lW=&*Yac;=zD95^m)I zths39)&+PCPMw82ip3HYpM-B8zz*0 zH2!_N1sz4hMRBV}c&kQ2oE9b4TdGWOt*AJ<{c&kEccO@Bdqsaab?01=OOBuaSNz~x zO_fn~=L6(ZQm6A84U~QzG-N??(rj@u zcuy8+o}Fv#Nua2Zn9z) z#m_fC(u(H{v?^yT<)okQ@_uOG<{8>)V*x&`4`MZ-pw15p83k5aJ%}C=qp@Tdg_NqP zc1L?%J>L*ZWPLs)xFEyWK4*xUDVE#``UA{f8(HoeS{ofEUH0=ig*YL*s$CGMPX{VZE z;Pr7N3?s}&4Z~%i8i}BcYy+9%9E8FQS1-i06Evb)Kun+#$Y*Lj7F(nq7In>;GYeI+ zrq}b5%5tsBbI)W9eEiM~=H<)lOZ%I(YuAjy8GP*fAGmfOc={hUAI85w?`?qmJa@zG zr@ih-={*Tw_l9~9nbCbMgAaA9J+rCEWx~Nf&$k&A3Av6WxYOTcJTNpYeK@zkcp!BQ`C~{O-SNZ=qznx_oIgU5O zws;>_R8g6Xj(U*^kj+@2(sR?uWMWa(-?#leTV1jaEVNMzW*9GO3f2OGKTS|22af-;G31>f~ zaONKxDAG%h%D#GP=Y%9`Rg3g9?Uq}htnPPNZ9<1_Nb(NKq*c&!D5<3}sm(W+s&$mW z_q7}pm&5#>U{_pL%_KIgAe7-U3mhy)HwM>IlgYBc3Njz(oSBzVLSpQu40`ls7wKc> zG0xQ0E(&hvD0kr^Gg#or>YaR_#Es%1tDi)@aVM$W+N?kqUsm;Q%9yiINso3LeKpcz*a$w3S1e)a!c5C8PP9I_wc=?IMvSPJI&@I-NVy<^|GGXV;Q+gyu9 z$&5)#Vs7+}BDH#(PpbLn%2v(fDqot~Fbczf4(qKsb-wRKR)fZZh47t5ush~~$=zW! zaf5T2GMeK*6VH-SU|7XlSUehy0k3d3(bO78usizva`H|}RD%weRu$^jG`VC;wza*B zw}W=gzkW4N^)Y}-Eg*c#DE>mRKdy3Gs#32y)b1QUJVqHahxY#d&gZ!nPjJ8&g}PJr zE(xx8=prUC*7>)(zjMY~_j-dne(!PR9S0U8k$w6byOkU>^fUT&_( zlbp-vX-nqhgkJK2S#L>IyVsSgxx&na;RM$EZgQp6W@^o$$N3?R;3uCItBsFc$8Oz` zOXCh!5UZ(r<1)!)`qkAT>_tj_0@XF~yyJ)Xa2S!2QSfNbOss-aMmjRV@{kfq{wF4~Ow2$SNJ>l#4FtlRz9{~Kqyq}aO zI61mto?wUn0eyoiLwA|jlity;e2|ggj<~3Lzs7O^L%$V1G|n7gRJ^{Kcvd1kZ*?PT zDC>s4=Y_)E3JB0Iv5<(k&4g{oh?F#h@Yx#2FVOO%N7WTRfi5@sD6PSqukKZn_Ca_H z&2Mqojv(bx5I7zD8j(FnplacIgJj(bPk{5%*nf9(1%LFQNw`_+6DW8KXE$YuL6Z$EjFN>Wn;SH5vQsc&b<`BE!QV^@yX~2}zCdLTC5w zVL5ce!RhMvJ}!4Dl{Jdtz=|jBoa-1swDpsSv}@;$BZpg``l$TIGI(MY?z^Dx1P?DD zgt6vB5crQ8TVxQ8HIfD@G^?^HNX{3-xFMj>c_m<>>bvaaE8Y&JS6x*xjctwF$evhH zJDPo8(8TSQ5wU05W>aLK?H> zI1>O-y3YPWU)W4)hhNBMJh!`H@YEF1qUA)XK_oPO@$Z9Z_XxQTJKavYu~ZwGuKp^y zu8}jfh#woVT*C64lIKgR>{EoP(Q?NPQvxOw;os3^Iu;!Ty-Dl}S!Rnh>z2S%;D>38 z4AV9_D8YmAL}`ab!Q-RYZD~aZdFvyFI9D~e@Ea2O>zvxx2o9HR0C#1}Ks~Zrnf1v! zBS@VwpzgThONgY)GP!`+`>~he-p1NR9FIRZH;XVgT;7M^vKcL)WgOVjC&x|!5bZX6 zxG^GT`J06BX(dvy%$lK&wzvPGtCfeg7w&Ep}n#fWrg=Dq#Tv zqWnK?rfrQ}T>dvG&(((ZRb5#TIO&x#XZHF_4h99L1&2gVWGLvKfFuYi1qCL=ew6?> zVaSYPP7Xz>vt8A?s#i#FsdFfdW`ZM#+CslvyV};KUfY(|<=W_WX8u0$Eb!c$>BWK- z@|6B@-96QLlJ}YCl8n*kdCB-Ib_r&SH87mZt0P&WL+Ws8yTru`eS4au*$Xv3O+Pc+ zexGU4a~m_QyF=JLHdUxJ8{&bJBHlxVKi=sMi@7ezJct!V&$p~bHfhjwkW(zHQa+EI zWvMiiXhxP|&Us0Z%bYTwY{u5A>L`Y5ahcPrE?XRW04y(k=Hb;glV2jNm06c?Mi{s< zS>KPH3$D*}sVn*h5i-#wC!|AaRUh zM%yZ@)M}rtX^r7Pi$boNae>?g*lHEF4>mN|{me}g#nmN(r}Qr&&k%jwA6M1A?vlT! z$I+h20QPP#SOePXbSMU$()O8&O}(DsQJ&Dq`YtQ9^sZOszUhhd?o%s{S4N0m8XYgv z7y)u6btN9DtQs;8ZkZ~KYf!+u3CG$L0ZVd3_$0v>y1u=>4vu%R_q`LN98=He7`xQF zo4P$RecgH=bgw(t2R#3L%A;>45BPe-U41;*cZVP8zuKbXCM$QH?mYBdr$?W=IyOh2 zJ74@U1ojRf^?KGucU|s8=>6A6-*sKHlL?%h5mmm&&a*;SEatiktn^JDe-cNd({vSG zx?EVp}|R%3>dqn*LIH9j7C#s!TsDBz0OzP+26)m--Buovx@cw8{D{;3O2&R zyaY8gwwF_a^c7Q?(Mm%NsW0Imxj_~N#J}$w>YJAc>Ym-0k21qu#XzqP83R#Z7?{&> zO!mlg9IiGR0!#)l;6s9}%LKx{97hatyBG^Pw=p79V0M&=`dsBHm#?3}2TNm%v4Mx2 zwB)jb7uW+>=ckwJ=VoV=1XP^PUFEVFE^Xr8hWFUrYAfkbySA2vn!a}>>I!-r~1`{WH=vin=OmKT7xwOJ?6JCSTeL)I3JF;JFH zoBAfNcv#G_l8ecg4>0(^gTBJ*;#$9MmGg_HR4}ZcS{WWfL7Cggn-8STnSG@s%x9s% zKo_)Ry)%b!>|lShIuh99Suius8V{5ajsmr)&Y#CqPgMPdFo3*OXnbg}yz&lkVZ}o{ ztKnoR8A!I<5*|$HRpKpn*Avn3;aU3A#IK%=UcN(Hgr6$jU^UpBg_2|XK4i3eJk}7P zXNax?XTk8 z=JMqY>S5|Akm=vKwn}usOA%3NNC!0umFq}k1A44r2{$ry3xu2lmfmW5avzI{`dC~A zIty@GMdUJeS}t;0DokuW4YoGU25LgYFwGLS$HqhMY9bYce-Pd|tpYD9Exgt*f!eO| z5+(CGGSPr&H|u`RCQ00EV)EFIMJ)+`W??h2Rla7{<%|fe&zgw{yVYf#+84E$ELPp$ zCKzx#K^cD`i|GHMq+j8{sF$Gt^-M>>W6gi0(cPMVmr-LnQ`?GAR`E{QSBuk9g6WKu zG-son92#>28%>T6)YtPhfRA?_LJiKusGN}Fv5+VrqnJ3J8Cz(dnF?hi!`hr9O>WYS z-ILDmPr|XTy%*aNjiiklSXZqATfzNd4^G&MlQGJPM3z8or(+Mv>dM-jChPui$@Uve z6O3j!Z?7R@;QvKpH=mxnf33);^4*#Hhm8?fWP6LMEo1W_TzL2^4YTg!-{HqE3V|q= z{l-2+O3VQ=JLAdd@JcSdi`B?KNr&-n-=&ZFaQRp^FiWEWpCHJFa1@hx>snS(~-ABpmomv}BlRHaa36Dit(am-z$< zf;s7u?9`zG!TkybjPN{}%}lxG9FX9wYyGoeFySIb!2tuk5LYLk5PsR$?)SjKi1#KC ze&N?+tayy4DEy}LMBYh}aQ?alhzp4D{y{%Bc;y+;gcB#sJw)pRjmBYZ|6c6F;1nd z{Go;=w_?t%v@5d7nTg9BjPj-H3pQ_JeAYH?MgYEdV*o!ScogbscW;(rNz4NZ*0$2ta$ z`L0)5h5cww6PKpK(hAM60m!}6tN>DANTl1Gg$1Jvkij&gKBHV}2m}_BKMih$w~U(O zjFhr2+-&KEW|3WEd4C#6Pihg`-Q8Y-7hZma9h5sDqv#oe3Dua@K?v1PU z!?kf$^>@FuHl4gyVx4j3~F0iXntx7BXdJHX2JOa*?miZ^$2}d|?J%2=5ji(ZfO0?L@ zUX*60VE0C?cnwM=Y+fd(DBlZnVW6J<6=Ex;>KkZiS{UF0bHxN4=#H0DZYp3v-e)Uy zqiWx7nLEJ{@(*r=oH+zD6Z)NJQ;8AUi;c}{qMEbRcqQhua?grV7T7~fL@o`&nN+AD zHLP=D6hm~+#)@h1@`xCYO^^8?N(yaDLbZ)rSd)CTUM&TB?g?g2y~gWpR#@GxPZD&w zN)`dz32cS%uhIbwXJK@Q|;;955t9VfV#GOuobZ`%0lE(MF|Va2v})mXWAVVroG%_0B% z3@i{c%{HAwQ?~48b#)yRH0&psst$*js5QmTMr1~aoKleb%!)br;r9S7e>mQStXENX zjZ}yMoGGs(fTE0{o?z-!@Zx2g`luJN`KxJH@`$PzdkRH^@%w|6T!o&ybR~%(1+31U zq03uj&sa#rwiDf#J1WoA=H6tYJX)V_#DY4&qbi*%(pl^*g`aN%B0UrYN#;28Yeo*) z05*vjq^yiW&n}~2-<4%sSQK1UwtdlVqy?5F*4-oq4D!>sYnVNNV$7rRRVazC>V|Li zd2{ud=lmiG73#e!a{08cWZ_e)7&1v5kv#T^Jhm^L)tk}^&|t?JwUyLlxD~8~a#oOQ zDTrw1J%yO0QhvnukNP=lTLRT4zG#NbYw@PYc0=;>jQEXT{Bx!j06N+R@Lmw1CmD@# z8vtV?pS-;;uL0w3-|)ucI`s~nWDGnd?n zUdJ17r7#n|haPf1gXXS*nkprUVjO%g32omXrbYB*;R_?2WQ|;%=oMdqPJte!Xx@h^Q0n_yLNb1I;6)sUj3}x|DonnF@JGdS`>Pe z_tnd4==FSuIFs7N=bEMQ#G`G>>4#|PIx+@|Ad59<$kE@FE^Y4p zAS2Vlr)a=omd4q)C?jI-wbE{xWfI|zafHruF9Qx}v5FI6MQwqnfxsJ{^05+S$j$qq z8fZm)P-FPPK=>N>v;$J30M^(7i;AGUQfluw^Z5r?dTIfJ&kXKUv<+c_(p&&bSEPQh zzCSR-3)#ps4cS0sS;Fr@K*9U(6RikGiW!KqV$N4`Y#9Mzh4CF_!#=zd3*h(k4H2uV zjh*4TXCp*{yb*kT&Pcu(S+Nf)qyPw~558Ky9;9YS&Vn<|sh%G-s}Y>jHcr`fclQvXw8{VlPiNMF2gsb&htg4h6-E)#6TQ@{5jjP!ys zZAEyx!YM?I znBzTpAf`GH%Nl|q0wGg@d>GjiQ+Ds1HF!dW+{?*}!|bJ`6@VUFobC z^oL}GQ&le)`I`!W=&jV$k#qHMGvW>@w>7gdD0K&n~e^`d@v&48j-qlbDD9#+kWyszC9BNtjCrztvW`c?M^II9X* zWLL+Y-t!Q4sRo=uz3iq4Zd|`L-6F%MaZ!Y&$J)*naR#+wJBezB*@uhIHLY`r8;_A3 zkiZa}X*Wc9Y4P{1dD_3N6_jP=cp9r5crR<}B80Z)1@K%Vo z!vMVehNZKmSxRMUvQBjY@CGM#O>8(vo=~bbnwk}gWf6Piv1Rg^tsM;Aa+z{3d-Cjx z`GT_@dv3j2vO%^;?S}3~!Ax;>t9F-+jv!>Kx3{)Ufkmshx0sG>y|o;mtS!aAoUT~F zX3DFfEla}Mrb9|+%BID*_w0lx_>|ghC>Z-f;VX5? z4|eL&wd$)lnF1&QhN>J`3S$3A3JhY3_hvMA{wNtkX2X&8!n;?evgcCIJCU{+N{YN+ zpGN^k_8XBIKFHI2;KzBuE^|Sh1c99=gIlnM*Itazi&QMn8gHC=idoa}EkVH7Q6G!? z-0wO}&GNHAY+GgjF5Z=Gz#PoPA0TY@nBDb-x@LjNxMB#Vw}(CGS*>p-5bpI+rJ}ZLcLO&3X4^;aXEV$^&6Ux z(~`a^a*c_Cy&?EZEWetvU*rg^#`{~n?wJ69M?HaI^_5R0_l|aeG?o;raFg#EI+DOc z_iuu-zdeOQxpyTrgxUh*Di3EQxS7VAXo{_cawb2O{|ZQ{TLVCp8!l~9aN%TKOI+R@ z;L4*_(`f&9S6q$r*VRMX&q`$DH|gn?zP9`Cw8J4R9GRlgb3@Y;yb?6Yc+~*2n)>@{ zE38p0^)NOGZ}TWNx@OKL(Xg(v_ZObg%<}}RS$k(W7dL`$r^Y3BUGqj4gXg<(goP?J zCP+;?^_*con|W2-f(NRvV3r;suB(%ewoUAfBMI@x#Ge%80s~R zMN>aEy7{$v=1<@IGYrM(9a+3L?(=0G%9{5|8HZAtNA@mZ0|kwI z>^ZE44cQ#6>CDTJ7z>qJ=_}IO9gI22r@}sFJ2!$VTB(^_SAp(Ek@7-UJ`0jN7fL(R zq%dq-H00_WPqCLgwC^IMI}Or@KU|`HXnC#gm9G&Rc|h9k3sEB`fm}+LE2Wgvim3se zA@E+5oaFUvja>%P%pxW6Xv^mK0rg$Q5T2_OsHR(8^VtopRt@Zn97KzDWwd^t3eX(Wdo0a0bQn7CuR+au#wF?a4y!9cp^-<%i%GP_jYHb`vd&wLGPTdt| z)mi}j6D{6d<2zomUk_wba&d2D)aN9ANA{?_WNHknjsPC3i3Ki_argxInQZ2j8f(5@@t5yJzR*f*%rMxIT&%?f9rL$cQji00$Yj z`EbXVVa|_VIyF=g{ZyzUJE*_krgl-^2>o#*@_)M#NIjPk1{k%@t7)C;HWUah>ZD>d z={H?@I2BgHFMm=Ty82NIIs7i*7(A<27_#b5cHDrxgB1KA;`}txmVeKUSW2wS`J#a@ zw|`}6dBo;Ga;La^$jYc6d;wrJVs!LOWthw{5Wu@{72hM>;nc+5a`zl?-SQ3l#+{Aj z2FGz4aySdR-jon~c`hAY$M*L{o_Iemh2EPpzTi*RGa5XqZa*^hG_wr`M_I(-qT+U@ z9Q`S_l>k2C3 z-cTMkptcO4Y_tJ$oPlZlE=?eMCSZDXAdF3*+4I6$kcJts z^(vsY4IuN!d3WG-BM@5+piMgcwAP2%mQ;@=_CA~^AA+mBa4U*uVK4Vuf&BndIdw_+gVm#lyn?u65sZhpHX=xixwHBa&nL zKm1V;vv;*}wK8)d6>@eq^7>zIUUEi`|D}~v(Nn-x!}LF%zFgx3QSO53CPW?C7SfD< z0WaOCtKAM;q)ZjfrVKX=8Qj+5?uOmA?x`Z*QA^hMw1|o1=>6IKjTr{~{vI0HE#$Xw z$3>T3%#fP(vY6$XTjM#2?+@?+EBGx#PAgk}iwa}yNfo$cou@QBMINq&QopB$Qorwp z0)cj9Z%M(+vVzR*S7&ZbE==kj4Jwt5kD3NW78rTk;3wc`qNq}{6haBinGh_zN3 zPas|(O`@Uf?b_K_N0jTcCD~w0SuVZB#BUO)Q03C&z2p%Um4AzkoY&lq3zllyx;#rg z>P!Ylt`+x`R}ynLz@|~l*Oz2ba_n4tmYy437j=5}O)FpBi!M)WR|vU{-ZfuactRNz zYB6uK5B5eIW5OB8LDv)N0-e*YII@XOzh?|`V@dfjCyVH$r?=@m2@n5-BE&sg&V617 zT0_&+I3ccfBxjySld1}q+ot^(rgCIe`7gz0Q+DNAwyxH!&vm-IVBG0MTt)p{;vS*> zpTIKXJt+$2K3>y+`RzTRa?k4uZY9*vd~a}inrpl>UhZIhuALc-X3y(g!?LXp(&)M7 zMyUPDpx_(91hKJTi{lyTI}-;y?}$?pGs43tLPj$3d7dtfiL%Z}w;i^asGyHA1~8Y%Ey=E_=qV{ilT5EMI^z&xF=)R`1mJ zcTW>>%nGDrLquizgjt-Enpyn@0a$g4t6;u(%n`ZlevyK$k*04{P6gQV&z?1cJ6NT%kHo$LKDlg1MF3Kz}Mn6 z0rWk4@JEu6e<<9A(w!S>iDCbxAaWqdTO*;Qm_XP>Lf@}N1yO*A-Qol!V?Qja;#9BT zVE)0*FK~~FJ)AHAosL)d_r*2>csVgRN@7rCLnR0UgrrIg9GvX!{#+Q z$bbH3M01Bpu={BWTR#EF?EjOdAZ%rCs^W%RdGbtU=W8=7WCcAY|taBmT!Xd+;F ziy^46v?G`NFukhL{^e*MJP=*BNgc-rp?W-2p{7n#)p(hTV^od;;nZ0hr2cp7uGiBS zXB0IV!@^C>od$*>R|^HHdAi%w@F6b>drA*VqBd^VlyDP##r#<;eqWuZXC%U`e^gM0 z4U0)Rr@Mf@%KrG3^gehsWr7HFg$euHg*Kt9Vx!tO<1TnTI%z3VFmLG^>M^+NIZ4o- zUpE$eN2Tw2;d&F90ss%$y=TdCxd$eWD|?^>8E^G$zm+_8h#+q~IY_0tv{#Ay*&mBS zxqCNxMyagh0B4K%XFVWOrajg*k0AGi9??^%2it2YD=QErSVy}7okCxNu$oncM0fvi zan(Lwr)!Tbsq!zLusH}7AMh-ztAF`e+_n_**o)jrK|gB9HPhzyCEkhJsihUl0ks1Z zsI5y+kbZc{)cSDW61WkPNRM^UKE6RIPg zN1yTBvD;Wx+D;f*c5Bc(ggok2m#>+!v*hv7h$(eGc5jTH7uCgz8(i~q*$vk=fBbhytuD6xT0S=nY~R zKqvEs@P6u(at0~881I?oKhz9h(JwHF*-~yF=xY)4XMN7>WH=~DWRGa>=%=uQJLI#9 z_BFoaE;0D6N7oaT(otkXqgn@m-Kd^8(^v=KU_A2Rz73P&UFcs?;4xRe{K!}#WtE45 z!;XlK=Xtw^#~m@4KStvAf0=&$H!p++Zk&OopTd>?NiAXgpA_(a1N6{@-l`!%q|iA_ zS=KKMZ5>U_=x#(qFC{2S^q^17bWADsq}U-pHdumzaOAZ=VuM3e$8b3gvje&gC$K<) zb-`i5?1j^tbcF(0H?Jea=4erBd1BN#FFRR=RPv;S9QVBnL5f^XzO)|-YY))Z)O_ZF zIX`|RSt_X#UZjt6!EWJ3HsFZ zvHu(n!H+Ks>;L3{B#m4w|Jxy@D#^(V3nKYtkCnwnwpxAis@*F3oO)}3QALHGicxuP zjg{(2aga%Y2c(q;1qlogkj;)o5u_i`PiJTPIheaYUwyu!0gcxMcfp1YjKW|eu;bb? z{}?W+ze0;t`Y{?d_)O%QR)k7VRsS`mT*6_Bp+X6fB0UI{OpU~l;vuMx8SF>;`yzWn z9ngcS0#RSzD(lnuhgoVo+$brof?gV#t2(H8J+tX|M&RTbR{#5<`R@GOv_fvbnZ(4)}ooA9PMfijV-Ax!a9(lv7 z0dx$`>WN8;__c02!y9&$HzOgG=-Q{;J(_)S2?S(Qu0b2#MZ?3l8X{5ivY!^d+1R_s z$bK~hKah>Z-_bKDZRu%auxy^t8gOje5tb0dN|Vfkq9+g+&%P}{>{Ib8EsG>q%D|0^ zet+DBTrY*H(4^&R>aFghL;^QVlgS6;anzY=2>gpj%3SoaFWbi&Kz`VY{f}-MS$lhH zSBHOHiH`#g?ZZOMtd%Y}*vYy{ugW4Hf}-Fsv#EqU4MjsnWKWnVgWB%!xLzhDxZm9` zoUwZWINJ|2kb9whgS{QA2au3OFPZF*Ejf3Ojy+zTjB7S{0qy6luNgQI>t#wO+<~9r(L7&~SFM)QIpd~FVqg22KGNUlih6_y_!*3ugt=$ct*{bivc$iP`sn~b znqt}m2yB?CbtHwY5ww!5McB9)s<`JbHS{6g*v*Z4&O+1uX(u0&epn0vBK{?m;(Y^0 zq>LE0fX~S}{72?0aI^9y)QMN2iZM_qWjTSqH!}5&;-(4q#1eHp^g@KG#FSy@)E0Kn zY(n~@Oq~*0Os(pI6;=mu+2gg!c|AKTiXN!c-8;tB3eOO-xVBGx%8gigL{Kv`^9pc& zp(2N|@?9RZm$$5Cm!D&MIxrp-TB()AG-a<5hvq?|9V&aC;T4bVycamnm(K^k zDl{oiHjz;eyunuziv?ZadvlK6P2DdRGOWw=eqG|2#2E55^?~eO={RSY{r_tGCAsSh zQT(wF)jlGg|IvZ@k^4y5x%^iK6s_`46FW2am9uCp1Tk9TJjt4R4+&vk;tU&zhfh71 zTuE|TGv^#D^x^N}uyVixiV#lp_pnsT+hNMvF_*Gpw)oKO|7Z=epWtTA{qgJh)9>Fq zINNE_fRHTBYaRq<3#vgS5iPnuu4C}A`8y#onLKvPWG9_xpYLC=IB*+H-6dw0W11Gq?RC~+Hmc((ySCLm zY!khkACR*$epz$k79`p72vi}#&pOiCw+&{>MT+cU{;9z0?4j*QQF1(S{bPy8ey$o# z8Dsz4JfC$$HoLVW@9uc@dd{QT-O$H`he5)<;5+G79$CWIMyhnw@KIX*BQq`?DZNwc zFm(8agdwdIKG*g_3p4k3oomaUT4ibTVefA#YG;V_-^Ax+Og~K^sL60c-u6_o)#tB2 z#KvO0;psMiKp+c61$J%2({1H{&Ct1eq30Wz6*%*}F1`}km*}uzXT;A;eI?*>)uLLo zK)n}vv+OvJI zlY3EA$(T@^#2WI&m64KNwQXBd72i)a55}T+Mb<_f>?$kp6*r&c`Y0FGUEr7rGL8Ol zlRDs;;g;R3Pns}HC=l_2nDuXzf~IOTmvUeB(`o z#V@oe^?<>TEHuHs=>?T!FV6?*>`MVGKmAJ}S6vB)7k0$5nnW{c;+NwvmHEV0=_Ld+ zvQc*3IKGe80m4G5q<;n$TKeqhh$Cm$hdP)Cr*8U^&S9G$p{a^rY zrvGyKX8)&wV@V7BnUf`IqZ4YK2qU;WtbjNVt{y%Q9;$a|#%?6Rt!2qh>P3Oi0)Wzw zqMy{?&&mFVx0Ak93{lndP|IsRv6p$FYu5epH14<*74F+d|2Vhk)eSh>8r`%dS!+u1xV@n;P3f6RyE#0c)O+zaeqB zCi85r-X$P48lK0fx8#^G<{RmH!r+I;CZC*q);$V3h!lbqCd8fcP3s7gom;bz&1N0C z5*C-DITzC07?|Idw|tuw(e(TWan2@7<;&c@6Ps?cBy2ww>LLXJG# zV;K;>NN$*t3lr(x;8-Lb!iW8(&Pyek@RqgyDS(GlPa&xtluMRJ+kl+H9c1rI^riOatIzJ^Wu*RMi%+K}}N9IL6^koPLohbgXibi<{2w%aF`WyZEqTh1)nTzu4 zMicBK&bYnx0}0_!H^Qp?pPCR_M7H*t#;;x$+}B&Blu+-GjSsb4E&+M==7%_2{Eg>x zc{`our}zb@yqNp2MyCh3PvOhV@UcIV6665nhb7R`A!q@I8u)~Tp@dspRSKe88~^=J z*<#sa{r?IURh>Tm)qeo9{{xZzSFlJCUDb3HN>qwKXoakI5kV}LkJ6=yK-l7FsWBrb zrQDOdSC+Sld?^v$P`5o)+=}?u%xohwea+X~?+5hnx{JJh|DO9=|MtL=KrGQKRm

5!0lndgdl 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 %UxyrTG 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