Skip to content

Commit

Permalink
Added RDFReport
Browse files Browse the repository at this point in the history
  • Loading branch information
labra committed Oct 28, 2020
1 parent 2898d70 commit c73893d
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ case class JenaShacl(shapesGraph: Model) extends Schema {
Result(isValid = isValid,
message = message,
shapeMaps = Seq(shapesMap),
validationReport = esRdf,
validationReport = JenaShaclReport(report.getModel),
errors = errors,
trigger = Some(TargetDeclarations),
nodesPrefixMap = nodesPrefixMap,
Expand Down
31 changes: 31 additions & 0 deletions modules/schema/src/main/scala/es/weso/schema/RDFReport.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package es.weso.schema

import es.weso.rdf.RDFBuilder
import es.weso.shacl.report.ValidationReport
import cats.effect._
import cats.implicits._
import es.weso.rdf.jena.RDFAsJenaModel
import org.apache.jena.rdf.model.Model

sealed abstract class RDFReport extends Product with Serializable {
def toRDF(builder: RDFBuilder): IO[RDFBuilder]
}

case object EmptyReport extends RDFReport {
override def toRDF(builder: RDFBuilder) = builder.pure[IO]
}

case class ShaclexReport(vr: ValidationReport) extends RDFReport {
override def toRDF(builder: RDFBuilder) = vr.toRDF(builder)
}

case class JenaShaclReport(model: Model) extends RDFReport {
override def toRDF(builder: RDFBuilder) = builder match {
case rdfJena: RDFAsJenaModel => RDFAsJenaModel.fromModel(model).flatMap(m => rdfJena.merge(m))
case _ => IO.raiseError(new RuntimeException(s"Builder in JenaShaclReport.toRDF must be RDFAsJenaModel"))
}
}

object RDFReport {
def empty: RDFReport = EmptyReport
}
79 changes: 24 additions & 55 deletions modules/schema/src/main/scala/es/weso/schema/Result.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ import io.circe.generic.auto._
import io.circe.syntax._
import es.weso.shapeMaps._
import es.weso.rdf.jena.RDFAsJenaModel
import java.io
import java.io.ByteArrayOutputStream
import java.io._
import es.weso.shacl.report.ValidationReport
import es.weso.rdf.RDFBuilder
import cats.effect._


case class Result(
isValid: Boolean,
message: String,
shapeMaps: Seq[ResultShapeMap],
validationReport: Either[String,RDFReader],
validationReport: RDFReport, // Either[String,RDFReader],
errors: Seq[ErrorInfo],
trigger: Option[ValidationTrigger],
nodesPrefixMap: PrefixMap,
Expand Down Expand Up @@ -59,13 +62,7 @@ case class Result(
sb.toString
}

def toJson: Json = {

/* implicit val encodeIRI: Encoder[IRI] = new Encoder[IRI] {
final def apply(iri: IRI): Json = {
Json.fromString(iri.getLexicalForm)
}
} */
def toJson(builder: RDFBuilder): IO[Json] = {

implicit val encodePrefixMap: Encoder[PrefixMap] = new Encoder[PrefixMap] {
final def apply(prefixMap: PrefixMap): Json = {
Expand All @@ -76,26 +73,7 @@ case class Result(
}
}

/* implicit val encodeShapeMap: Encoder[ResultShapeMap] = new Encoder[ResultShapeMap] {
final def apply(a: ResultShapeMap): Json = {
def node2String(n: RDFNode): String = a.nodesPrefixMap.qualify(n)
def shapeMapLabel2String(s: ShapeMapLabel): String = s match {
case IRILabel(iri) => a.shapesPrefixMap.qualify(iri)
case BNodeLabel(b) => b.getLexicalForm
case _ => throw new Exception(s"encodeShapeMap. shapeMapLabel2String: unsupported $s")
}
def info2Json(i: Info): Json = i.asJson
def result2Json(s: Map[ShapeMapLabel, Info]): Json = {
Json.fromJsonObject(JsonObject.fromMap(cnvMap(s, shapeMapLabel2String, info2Json)))
}
Json.fromJsonObject(JsonObject.fromMap(cnvMap(a.resultMap, node2String, result2Json)))
}
} */

implicit val encodeResult: Encoder[Result] = new Encoder[Result] {
final def apply(a: Result): Json =
Json.obj(
def result2Json(result: Result, strValidationReport: String): Json = Json.obj(
("valid", isValid.asJson),
("type", "Result".asJson),
("message", message.asJson),
Expand All @@ -106,28 +84,19 @@ case class Result(
("errors", errors.toList.asJson),
("nodesPrefixMap", nodesPrefixMap.asJson),
("shapesPrefixMap", shapesPrefixMap.asJson),
("validationReport", validationReport match {
case Left(msg) => msg.asJson
case Right(rdf) => Json.fromString(serializeRDF(rdf, reportFormat))
})
)
}

this.asJson
}
("validationReport", Json.fromString(strValidationReport))
)

private def serializeRDF(rdf: RDFReader, format: String): String = rdf match {
case rdfJena: RDFAsJenaModel => {
val model = rdfJena.modelRef.get.unsafeRunSync()
val out = new ByteArrayOutputStream()
model.write(out, format)
out.toString
for {
rdf <- validationReport.toRDF(builder)
str <- rdf.serialize(reportFormat)
} yield {
result2Json(this, str)
}
case _ => s"Unsupported serialization of ${rdf.rdfReaderName}"
}
}

private def toJsonString2spaces: String =
toJson.spaces2
private def toJsonString2spaces(builder: RDFBuilder): IO[String] =
toJson(builder)map(_.spaces2)

private lazy val cut = 1 // TODO maybe remove concept of cut

Expand All @@ -136,10 +105,10 @@ case class Result(
else n.toString
}

def serialize(format: String, base: Option[IRI] = None): String = format.toUpperCase match {
case Result.TEXT => show(base)
case Result.JSON => toJsonString2spaces
case _ => s"Unsupported format to serialize result: $format, $this"
def serialize(format: String, base: Option[IRI] = None, builder: RDFBuilder): IO[String] = format.toUpperCase match {
case Result.TEXT => IO(show(base))
case Result.JSON => toJsonString2spaces(builder)
case _ => IO.raiseError(new RuntimeException(s"Unsupported format to serialize result: $format, $this"))
}

def hasShapes(node: RDFNode): Seq[SchemaLabel] = {
Expand All @@ -164,7 +133,7 @@ object Result extends LazyLogging {
isValid = true,
message = "",
shapeMaps = Seq(),
validationReport = Left("No report"),
validationReport = RDFReport.empty,
errors = Seq(),
None,
PrefixMap.empty,
Expand Down Expand Up @@ -226,7 +195,7 @@ object Result extends LazyLogging {
isValid,
message,
solutions,
Left("Not implemented ValidationReport Json decoder yet"),
RDFReport.empty,
errors,
trigger,
nodesPrefixMap,
Expand Down
28 changes: 4 additions & 24 deletions modules/schema/src/main/scala/es/weso/schema/ShExSchema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ case class ShExSchema(schema: SchemaShEx)
false,
message = "Error validating",
shapeMaps = Seq(),
validationReport = Left("No validation report in ShEx"),
validationReport = EmptyReport,
errors = Seq(ErrorInfo(msg)),
None,
pm,
Expand All @@ -81,7 +81,7 @@ case class ShExSchema(schema: SchemaShEx)
true,
"Validated",
shapeMaps = Seq(resultShapeMap),
validationReport = Left(s"No validaton report in ShEx"),
validationReport = EmptyReport,
errors = Seq(),
None,
pm,
Expand Down Expand Up @@ -118,7 +118,7 @@ case class ShExSchema(schema: SchemaShEx)
false,
"Error validating",
Seq(),
Left("No validation report yet"),
EmptyReport,
Seq(ErrorInfo(error.getMessage())),
None,
pm,
Expand All @@ -130,30 +130,14 @@ case class ShExSchema(schema: SchemaShEx)
true,
"Validated",
Seq(resultShapeMap),
Left(s"No validation report for ShEx"),
EmptyReport,
Seq(),
None,
pm,
schema.prefixMap
)
}
} yield res
/* match {
case Right(resultShapeMap) => {
// println(s"Validated, result=$resultShapeMap")
Result(
true,
"Validated",
Seq(resultShapeMap),
Left(s"No validation report for ShEx"),
Seq(),
None,
rdf.getPrefixMap(),
schema.prefixMap
)
}
}
} */

def cnvViolationError(v: ShExError): ErrorInfo = {
ErrorInfo(v.show)
Expand All @@ -167,10 +151,6 @@ case class ShExSchema(schema: SchemaShEx)
s => IO.raiseError(new RuntimeException(s)),
IO.pure(_)
)
/* {
val x: Either[Throwable,A] = e.leftMap(new RuntimeException(_))
MonadError[IO,Throwable].rethrow(IO(x))
} */

override def fromRDF(rdf: RDFReader): IO[es.weso.schema.Schema] = for {
eitherSchema <- RDF2ShEx.rdf2Schema(rdf)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ case class ShaclexSchema(schema: ShaclSchema) extends Schema {
builder: RDFBuilder
): IO[Result] = {
val vr: ValidationReport =
r.result.fold(e => ValidationReport.fromError(e), r =>
r.result.fold(
e => ValidationReport.fromError(e), r =>
r._1.toValidationReport
)
for {
pm <- rdf.getPrefixMap
eitherVR <- vr.toRDF(builder).attempt
} yield Result(
isValid = vr.conforms,
message = if (vr.conforms) "Valid" else "Not valid",
shapeMaps = r.results.map(cnvShapeTyping(_, rdf,pm)),
validationReport = eitherVR.leftMap(_.getMessage),
validationReport = ShaclexReport(vr),
errors = vr.results.map(cnvViolationError),
trigger = None,
nodesPrefixMap = pm,
Expand Down
12 changes: 7 additions & 5 deletions src/main/scala/es/weso/shaclex/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,21 @@ object Main extends IOApp with LazyLogging {

private def doShowResult(opts: MainOpts, result: Result): ESIO[Unit] =
if (opts.showResult() || opts.outputFile.isDefined) {
val resultSerialized = result.serialize(opts.resultFormat(),relativeBase)
// val resultSerialized = result.serialize(opts.resultFormat(),relativeBase)
for {
_ <- whenA(opts.showResult(),fromUnit(println(resultSerialized)))
_ <- whenA(opts.outputFile.isDefined,fromUnit(FileUtils.writeFile(opts.outputFile(), resultSerialized)))
resEmpty <-fromIO(RDFAsJenaModel.empty)
str <- fromIO(resEmpty.use(builder => result.serialize(opts.resultFormat(),relativeBase,builder)))
_ <- whenA(opts.showResult(),fromUnit(println(str)))
_ <- whenA(opts.outputFile.isDefined,fromUnit(FileUtils.writeFile(opts.outputFile(), str)))
} yield (())
} else done


private def doShowValidationReport(opts:MainOpts, result: Result): ESIO[Unit] =
if (opts.showValidationReport())
for {
rdf <- fromEither(result.validationReport)
str <- fromIO(rdf.serialize(opts.validationReportFormat()))
res <- fromIO(RDFAsJenaModel.empty)
str <- fromIO(res.use(builder => result.validationReport.toRDF(builder).flatMap(_.serialize(opts.validationReportFormat()))))
_ <- fromUnit(println(str))
} yield (())
else done
Expand Down
2 changes: 1 addition & 1 deletion version.sbt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version in ThisBuild := "0.1.66"
version in ThisBuild := "0.1.67"

0 comments on commit c73893d

Please sign in to comment.