<commit_before>package es.weso.shex.shexR

import es.weso.rdf.RDFBuilder
import es.weso.shex._
import PREFIXES._
import cats._
import cats.data._
import cats.implicits._
import com.typesafe.scalalogging.LazyLogging
import es.weso.rdf.PREFIXES.{rdf, rdfs, xsd}
import es.weso.rdf.jena._
import es.weso.rdf.nodes._
import es.weso.rdf.PREFIXES._
import org.apache.jena.rdf.model.Model

import scala.util.{Success, Try}

trait ShEx2RDF extends RDFSaver with LazyLogging {

  def serialize(shex:Schema, node: Option[IRI], format: String): Try[String] = {
    val rdf: RDFAsJenaModel = toRDF(shex,node,RDFAsJenaModel.empty)
    Success(rdf.serialize(format))
  }

  def toRDF(s: Schema, node: Option[IRI], initial: RDFAsJenaModel): RDFAsJenaModel = {
    val result = schema(s,node).run(initial)
    result.value._1
  }

  def schema(s:Schema, id: Option[IRI]): RDFSaver[Unit] = {
    for {
      node <- makeId(id)
      _ <- addPrefixMap(s.prefixMap)
      _ <- addTriple(node,rdf_type,sx_Schema)
      _ <- maybeAddStarContent(s.shapes, node, sx_shapes, shapeExpr)
    } yield ()
  }

  def listSaver[A](ls: List[A], saver: A => RDFSaver[RDFNode]): RDFSaver[List[RDFNode]] = {
    ls.map(saver(_)).sequence
  }

  def saveAsRDFList[A](ls: List[A], saver: A => RDFSaver[RDFNode]): RDFSaver[RDFNode] = for {
    nodes <- listSaver(ls,saver)
    ls <- mkRDFList(nodes)
  } yield ls

  def mkRDFList(ls: List[RDFNode]): RDFSaver[RDFNode] = ls match {
    case Nil => ok(rdf_nil)
    case x :: xs => for {
      node <- createBNode()
      _ <- addTriple(node,rdf_first,x)
      _ <- addContent(xs,node,rdf_rest,mkRDFList)
    } yield node
  }

  def addListContent[A](ls: List[A], node: RDFNode, pred: IRI, saver: A => RDFSaver[RDFNode]): RDFSaver[Unit] = for {
    listNode <- saveAsRDFList(ls,saver)
    _ <- addTriple(node, pred, listNode)
  } yield ()

  def maybeAddListContent[A](maybeLs: Option[List[A]], node: RDFNode, pred: IRI, saver: A => RDFSaver[RDFNode]): RDFSaver[Unit] =
    maybeLs match {
      case None => ok(())
      case Some(ls) => addListContent(ls,node,pred,saver)
    }

  def addStarContent[A](ls: List[A], node: RDFNode, pred: IRI, saver: A => RDFSaver[RDFNode]): RDFSaver[Unit] = for {
    nodes <- listSaver(ls,saver)
    _ <- nodes.map(n => addTriple(node, pred, n)).sequence
  } yield ()

  def maybeAddStarContent[A](maybeLs: Option[List[A]], node: RDFNode, pred: IRI, saver: A => RDFSaver[RDFNode]): RDFSaver[Unit] =
   maybeLs match {
     case None => ok(())
     case Some(ls) => addStarContent(ls,node,pred,saver)
  }

  def mkId(id: Option[ShapeLabel]): RDFSaver[RDFNode] = id match {
    case None => createBNode
    case Some(IRILabel(iri)) => ok(iri)
    case Some(BNodeLabel(bNode)) => ok(bNode)
  }

  def shapeExpr(e: ShapeExpr): RDFSaver[RDFNode] = e match {
    case ShapeAnd(id,shapeExprs) => for {
      node <- mkId(id)
      _ <- addTriple(node,rdf_type,sx_ShapeAnd)
      _ <- addStarContent(shapeExprs,node,sx_expressions,shapeExpr)
    } yield node
    case ShapeOr(id,shapeExprs) => for {
      node <- mkId(id)
      _ <- addTriple(node,rdf_type,sx_ShapeOr)
      _ <- addStarContent(shapeExprs,node,sx_expressions,shapeExpr)
    } yield node
    case ShapeNot(id,se) => for {
      node <- mkId(id)
      _ <- addTriple(node,rdf_type,sx_ShapeNot)
      _ <- addContent(se,node,sx_expression,shapeExpr)
    } yield node
    case Shape(id,virtual,closed,extra,expr,inherit,semActs) => for {
      shapeId <- mkId(id)
      _ <- addTriple(shapeId,rdf_type,sx_Shape)
      _ <- maybeAddContent(closed,shapeId,sx_closed, rdfBoolean)
      _ <- maybeAddContent(expr, shapeId, sx_expression, tripleExpr)
    } yield shapeId
    case ShapeExternal(id) => for {
      shapeId <- mkId(id)
      _ <- addTriple(shapeId, rdf_type, sx_ShapeExternal)
    } yield shapeId
    case NodeConstraint(id,nk,dt,facets,values) => for {
      shapeId <- mkId(id)
      _ <- addTriple(shapeId,rdf_type,sx_NodeConstraint)
      _ <- maybeAddContent(nk, shapeId, sx_nodeKind, nodeKind)
      _ <- maybeAddContent(dt, shapeId, sx_datatype, iri)
      // _ <- addStarContent(facets, shapeId, sx_, datatype)
      _ <- maybeAddListContent(values,shapeId,sx_values,valueSetValue)
    } yield shapeId
    case ShapeRef(lbl) => label(lbl)
  }


  def valueSetValue(x: ValueSetValue): RDFSaver[RDFNode] = x match {
    case IRIValue(iri) => ok(iri)
    case StringValue(s) => ok(StringLiteral(s))
    case DatatypeString(s,iri) => ok(DatatypeLiteral(s,iri))
    case LangString(s,lang) => ok(LangLiteral(s,Lang(lang)))
    case s: Stem => stem(s)
    case StemRange(stem, exclusions) => for {
      node <- createBNode()
      _ <- addTriple(node,rdf_type,sx_StemRange)
      _ <- addContent(stem, node, sx_stem, stemValue)
      _ <- maybeAddStarContent(exclusions,node,sx_exclusion,objectStemValue)
    }  yield node
  }

  def stem(x: Stem): RDFSaver[RDFNode] = for {
    node <- createBNode()
    _ <- addTriple(node,rdf_type,sx_Stem)
    _ <- addTriple(node,sx_stem,DatatypeLiteral(x.stem.str,xsd_anyUri))
  } yield node

  def objectStemValue(x: ValueSetValue): RDFSaver[RDFNode] = x match {
    case o: ObjectValue => objectValue(o)<commit_msg>Finisshed ShExR<commit_after>package es.weso.shex.shexR

import es.weso.rdf.RDFBuilder
import es.weso.shex._
import PREFIXES._
import cats._
import cats.data._
import cats.implicits._
import com.typesafe.scalalogging.LazyLogging
import es.weso.rdf.PREFIXES.{rdf, rdfs, xsd}
import es.weso.rdf.jena._
import es.weso.rdf.nodes._
import es.weso.rdf.PREFIXES._
import org.apache.jena.rdf.model.Model

import scala.util.{Success, Try}

trait ShEx2RDF extends RDFSaver with LazyLogging {

  def serialize(shex:Schema, node: Option[IRI], format: String): Try[String] = {
    val rdf: RDFAsJenaModel = toRDF(shex,node,RDFAsJenaModel.empty)
    Success(rdf.serialize(format))
  }

  def toRDF(s: Schema, node: Option[IRI], initial: RDFAsJenaModel): RDFAsJenaModel = {
    val result = schema(s,node).run(initial)
    result.value._1
  }

  def schema(s:Schema, id: Option[IRI]): RDFSaver[Unit] = {
    for {
      node <- makeId(id)
      _ <- addPrefixMap(s.prefixMap)
      _ <- addTriple(node,rdf_type,sx_Schema)
      _ <- maybeAddStarContent(s.shapes, node, sx_shapes, shapeExpr)
    } yield ()
  }

  def listSaver[A](ls: List[A], saver: A => RDFSaver[RDFNode]): RDFSaver[List[RDFNode]] = {
    ls.map(saver(_)).sequence
  }

  def saveAsRDFList[A](ls: List[A], saver: A => RDFSaver[RDFNode]): RDFSaver[RDFNode] = for {
    nodes <- listSaver(ls,saver)
    ls <- mkRDFList(nodes)
  } yield ls

  def mkRDFList(ls: List[RDFNode]): RDFSaver[RDFNode] = ls match {
    case Nil => ok(rdf_nil)
    case x :: xs => for {
      node <- createBNode()
      _ <- addTriple(node,rdf_first,x)
      _ <- addContent(xs,node,rdf_rest,mkRDFList)
    } yield node
  }

  def addListContent[A](ls: List[A], node: RDFNode, pred: IRI, saver: A => RDFSaver[RDFNode]): RDFSaver[Unit] = for {
    listNode <- saveAsRDFList(ls,saver)
    _ <- addTriple(node, pred, listNode)
  } yield ()

  def maybeAddListContent[A](maybeLs: Option[List[A]], node: RDFNode, pred: IRI, saver: A => RDFSaver[RDFNode]): RDFSaver[Unit] =
    maybeLs match {
      case None => ok(())
      case Some(ls) => addListContent(ls,node,pred,saver)
    }

  def addStarContent[A](ls: List[A], node: RDFNode, pred: IRI, saver: A => RDFSaver[RDFNode]): RDFSaver[Unit] = for {
    nodes <- listSaver(ls,saver)
    _ <- nodes.map(n => addTriple(node, pred, n)).sequence
  } yield ()

  def maybeAddStarContent[A](maybeLs: Option[List[A]], node: RDFNode, pred: IRI, saver: A => RDFSaver[RDFNode]): RDFSaver[Unit] =
   maybeLs match {
     case None => ok(())
     case Some(ls) => addStarContent(ls,node,pred,saver)
  }

  def mkId(id: Option[ShapeLabel]): RDFSaver[RDFNode] = id match {
    case None => createBNode
    case Some(IRILabel(iri)) => ok(iri)
    case Some(BNodeLabel(bNode)) => ok(bNode)
  }

  def shapeExpr(e: ShapeExpr): RDFSaver[RDFNode] = e match {
    case ShapeAnd(id,shapeExprs) => for {
      node <- mkId(id)
      _ <- addTriple(node,rdf_type,sx_ShapeAnd)
      _ <- addStarContent(shapeExprs,node,sx_expressions,shapeExpr)
    } yield node
    case ShapeOr(id,shapeExprs) => for {
      node <- mkId(id)
      _ <- addTriple(node,rdf_type,sx_ShapeOr)
      _ <- addStarContent(shapeExprs,node,sx_expressions,shapeExpr)
    } yield node
    case ShapeNot(id,se) => for {
      node <- mkId(id)
      _ <- addTriple(node,rdf_type,sx_ShapeNot)
      _ <- addContent(se,node,sx_expression,shapeExpr)
    } yield node
    case Shape(id,virtual,closed,extra,expr,inherit,semActs) => for {
      shapeId <- mkId(id)
      _ <- addTriple(shapeId,rdf_type,sx_Shape)
      _ <- maybeAddContent(closed,shapeId,sx_closed, rdfBoolean)
      _ <- maybeAddContent(expr, shapeId, sx_expression, tripleExpr)
    } yield shapeId
    case ShapeExternal(id) => for {
      shapeId <- mkId(id)
      _ <- addTriple(shapeId, rdf_type, sx_ShapeExternal)
    } yield shapeId
    case NodeConstraint(id,nk,dt,facets,values) => for {
      shapeId <- mkId(id)
      _ <- addTriple(shapeId,rdf_type,sx_NodeConstraint)
      _ <- maybeAddContent(nk, shapeId, sx_nodeKind, nodeKind)
      _ <- maybeAddContent(dt, shapeId, sx_datatype, iri)
      _ <- facets.map(xsFacet(_, shapeId)).sequence
      _ <- maybeAddListContent(values,shapeId,sx_values,valueSetValue)
    } yield shapeId
    case ShapeRef(lbl) => label(lbl)
  }

  def xsFacet(facet: XsFacet, node: RDFNode): RDFSaver[Unit] = facet match {
    case Length(n) => addTriple(node,sx_length,IntegerLiteral(n))
    case MinLength(n) => addTriple(node,sx_minlength,IntegerLiteral(n))
    case MaxLength(n) => addTriple(node,sx_maxlength,IntegerLiteral(n))
    case Pattern(n) => addTriple(node,sx_pattern,StringLiteral(n))
    case MinInclusive(n) => addContent(n,node,sx_mininclusive,numericLiteral)
    case MinExclusive(n) => addContent(n,node,sx_minexclusive,numericLiteral)
    case MaxInclusive(n) => addContent(n,node,sx_maxinclusive,numericLiteral)
    case MaxExclusive(n) => addContent(n,node,sx_maxexclusive,numericLiteral)
    case FractionDigits(n) => addTriple(node,sx_fractiondigits,IntegerLiteral(n))
    case TotalDigits(n) => addTriple(node,sx_totaldigits,IntegerLiteral(n))
  }

  def numericLiteral(n: NumericLiteral): RDFSaver[RDFNode] = n match {
    case NumericInt(n) => ok(IntegerLiteral(n))
    case NumericDouble(n) => ok(DoubleLiteral(n))
    case NumericDecimal(n) => ok(DecimalLiteral(n))
  }

  def valueSetValue(x: ValueSetValue): RDFSaver[RDFNode] = x match {
    case IRIValue(iri) => ok(iri)
    case StringValue(s) => ok(StringLiteral(s))
    case DatatypeString(s,iri) => ok(DatatypeLiteral(s,iri))
    case LangString(s,lang) => ok(LangLiteral(s,Lang(lang)))
    case s: Stem => stem(s)
    case StemRange(stem, exclusions) => for {
      node <- createBNode()
      _ <- addTriple(node,rdf_type,sx_StemRange)
      _ <- addContent(stem, node, sx_stem, stemValue)
      _ <- maybeAddStarContent(exclusions,node,sx_exclusion,objectStemValue)
    }  yield node
  }

  def stem(x: Stem): RDFSaver[RDFNode] = for {
    node <- createBNode()
    _ <- addTriple(node,rdf_type,sx_Stem)
    _ <- addTriple(node,sx_stem,DatatypeLiteral(x.stem.str,xsd_anyUri))
  } yield node

  def objectStemValue(x: ValueSetValue): RDFSaver[RDFNode] = x match {
    case o: ObjectValue => objectValue(o)
{'fraction_non_alphanumeric': 0.1412384716732543, 'fraction_numerical': 0.0003513394817742644, 'mean_word_length': 3.9590592334494774, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 76, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7248272', 'n_tokens_mistral': 4528, 'n_tokens_neox': 4275, 'n_words': 741}