Skip to content
6 changes: 5 additions & 1 deletion src/main/scala/eu/neverblink/jelly/cli/JellyCommand.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package eu.neverblink.jelly.cli
import caseapp.*
import eu.neverblink.jelly.cli.JellyCommand.emptyRemainingArgs

import java.io.{ByteArrayOutputStream, PrintStream}
import java.io.{ByteArrayOutputStream, OutputStream, PrintStream}
import scala.compiletime.uninitialized

object JellyCommand:
Expand Down Expand Up @@ -39,6 +39,10 @@ abstract class JellyCommand[T: {Parser, Help}] extends Command[T]:
s
else throw new IllegalStateException("Not in test mode")

def getOutputStream: OutputStream =
if isTest then osOut
else System.out

def getErr: String =
if isTest then
err.flush()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,40 @@
package eu.neverblink.jelly.cli.command.rdf
import caseapp.*
import eu.neverblink.jelly.cli.JellyCommand
import eu.ostrzyciel.jelly.convert.jena.riot.JellyLanguage
import org.apache.jena.riot.system.StreamRDFWriter
import org.apache.jena.riot.{RDFLanguages, RDFParser}

case class FromJellyRdfOptions()
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, File, FileInputStream, InputStream}

case class RdfFromJellyOptions(
@ExtraName("input-file") inputFile: Option[String],
)

object RdfFromJelly extends JellyCommand[RdfFromJellyOptions]:
override def group = "rdf"

object RdfFromJelly extends JellyCommand[FromJellyRdfOptions]:
override def names: List[List[String]] = List(
List("rdf", "from-jelly"),
)

override def run(options: FromJellyRdfOptions, remainingArgs: RemainingArgs): Unit =
// This is a placeholder for the actual implementation
println("rdf from-jelly")
println(options)
println(remainingArgs)
override def run(options: RdfFromJellyOptions, remainingArgs: RemainingArgs): Unit =
val inputStream = options.inputFile match {
case Some(fileName: String) =>
FileInputStream(File(fileName))
case None => System.in
}
rewriteFormats(inputStream)

/*
This method reads the Jelly file, rewrite it to NQuads and writes it to the output stream
* @param inputStream InputStream
*/
private def rewriteFormats(inputStream: InputStream): Unit =
// TODO: Add error handling; return success/failure in the future
val interStream = new ByteArrayOutputStream()
val interWriter = StreamRDFWriter.getWriterStream(interStream, RDFLanguages.NQUADS)
RDFParser.source(inputStream).lang(JellyLanguage.JELLY).parse(interWriter)
val readerStream = new ByteArrayInputStream(interStream.toByteArray)
val nQuadWriter = StreamRDFWriter.getWriterStream(getOutputStream, RDFLanguages.NQUADS)
RDFParser.source(readerStream).lang(RDFLanguages.NQUADS).parse(nQuadWriter)
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
package eu.neverblink.jelly.cli.command

import eu.neverblink.jelly.cli.command.helpers.*
import eu.neverblink.jelly.cli.command.rdf.*
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class RdfFromJellySpec extends AnyWordSpec with Matchers with CleanUpFilesAfterTest:
class RdfFromJellySpec extends AnyWordSpec with Matchers with CleanUpAfterTest:
"rdf from-jelly command" should {
"be able to convert a Jelly file to NTriples" in {
val jellyFile = DataGenHelper.generateJellyFile(3)
val nQuadString = DataGenHelper.generateNQuadString(3)
val options = RdfFromJellyOptions(inputFile = Some(jellyFile))
val (out, err) = RdfFromJelly.runTest(options)
val sortedOut = out.split("\n").map(_.trim).sorted
val sortedQuads = nQuadString.split("\n").map(_.trim).sorted
sortedOut should contain theSameElementsAs sortedQuads
}
"be able to convert a Jelly stream to NTriples" in {
val jellyStream = DataGenHelper.generateJellyInputStream(3)
System.setIn(jellyStream)
val nQuadString = DataGenHelper.generateNQuadString(3)
val options = RdfFromJellyOptions(inputFile = None)
val (out, err) = RdfFromJelly.runTest(options)
val sortedOut = out.split("\n").map(_.trim).sorted
val sortedQuads = nQuadString.split("\n").map(_.trim).sorted
sortedOut should contain theSameElementsAs sortedQuads
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package eu.neverblink.jelly.cli.command.helpers
import org.scalatest.BeforeAndAfterEach
import org.scalatest.wordspec.AnyWordSpec

trait CleanUpFilesAfterTest extends BeforeAndAfterEach {
trait CleanUpAfterTest extends BeforeAndAfterEach {
this: AnyWordSpec =>
override def afterEach(): Unit = {
DataGenHelper.cleanUpFile()
DataGenHelper.resetInputStream()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package eu.neverblink.jelly.cli.command.helpers

import eu.ostrzyciel.jelly.convert.jena.riot.JellyLanguage
import org.apache.jena.rdf.model.{Model, ModelFactory, ResourceFactory}
import org.apache.jena.riot.RDFDataMgr
import org.apache.jena.riot.{RDFDataMgr, RDFLanguages}

import java.io.FileOutputStream
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, FileOutputStream}
import java.nio.file.{Files, Paths}
import scala.util.Using

Expand All @@ -14,6 +14,7 @@ import scala.util.Using
object DataGenHelper:

private val testFile = "testInput.jelly"
private val inputStream = System.in

/*
* This method generates a triple model with nTriples
Expand All @@ -37,14 +38,40 @@ object DataGenHelper:
/* This method generates a Jelly file with nTriples
* @param nTriples number of triples to generate
* @param fileName name of the file to generate
* @return String
*/
def generateJellyFile(nTriples: Int): Unit =
def generateJellyFile(nTriples: Int): String =
val model = generateTripleModel(nTriples)
// TODO: Add configurable generation for different variants of Jelly (small strict etc)
Using.resource(FileOutputStream(testFile)) { file =>
RDFDataMgr.write(file, model, JellyLanguage.JELLY)
}
testFile

/*
* This method generates a Jelly byte input stream with nTriples
* @param nTriples number of triples to generate
* @return String
*/
def generateJellyInputStream(nTriples: Int): ByteArrayInputStream =
val model = generateTripleModel(nTriples)
val outputStream = new ByteArrayOutputStream()
RDFDataMgr.write(outputStream, model, JellyLanguage.JELLY)
new ByteArrayInputStream(outputStream.toByteArray)

/*
* This method generates a NQuad string with nTriples
* @param nTriples number of triples to generate
* @return String
*/
def generateNQuadString(nTriples: Int): String =
val model = generateTripleModel(nTriples)
val outputStream = new ByteArrayOutputStream()
RDFDataMgr.write(outputStream, model, RDFLanguages.NQUADS)
outputStream.toString

/* This method cleans up the file after the test*/
def cleanUpFile(): Unit =
Files.deleteIfExists(Paths.get(testFile))

def resetInputStream(): Unit =
System.setIn(inputStream)