All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lspace.decode.DecodeJson.scala Maven / Gradle / Ivy

The newest version!
package lspace.decode

import java.util.UUID

import lspace.codec.ActiveContext
import lspace.codec.json.jsonld.Decoder
import lspace.provider.mem.MemGraph
import lspace.structure.{ClassType, Edge, Node, Ontology, Property}
import monix.eval.Task

trait DecodeJson[A, F[_]] extends Decode[A, F] {
  type In = String
}

object DecodeJson {
  type Aux[Out, F[_], In0] = DecodeJson[Out, F] { type In = In0 }

  case class InvalidJson(message: String)       extends DecodeException(message)
  case class NotAcceptableJson(message: String) extends NotAcceptable(message)

  def jsonToNode(allowedProperties: List[Property] = List(), forbiddenProperties: List[Property] = List())(
      implicit decoder: Decoder[_]): DecodeJson[Node, Task] = {
    val validProperty = (property: Property) =>
      if (allowedProperties.nonEmpty) {
        allowedProperties.contains(property) && !forbiddenProperties.contains(property)
      } else if (forbiddenProperties.nonEmpty) {
        !forbiddenProperties.contains(property)
      } else {
        true
    }

    if (allowedProperties.nonEmpty || forbiddenProperties.nonEmpty) {
      new DecodeJson[Node, Task] {
        def decode(implicit activeContext: ActiveContext) = { (json: String) =>
          decoder
            .stringToNode(json)
            .flatMap { node =>
              val resultGraph = MemGraph.apply(UUID.randomUUID().toString)
              for {
                fNode <- resultGraph.nodes.create()
                _ <- Task.gatherUnordered(
                  node.outE().filter(e => validProperty(e.key)).map(e => fNode --- e.key --> e.to))
              } yield fNode
            }
        }
      }
    } else
      new DecodeJson[Node, Task] {
        def decode(implicit activeContext: ActiveContext) = { (json: String) =>
          decoder
            .stringToNode(json)
        }
      }
  }
//  implicit def decodeJsonEdge(implicit decoder: lspace.codec.json.jsonld.Decoder) = new DecodeJson[Edge[Any, Any]] {
//    def decode =
//      (json: String) =>
//        decoder
//          .stringToEdge(json)
//  }

  /**
    *
    * @param label a label which is added to the resulting node
    * @param allowedProperties a whitelist for properties which are accepted
    * @param decoder
    * @return
    */
  def jsonToLabeledNode(
      label: Ontology,
      allowedProperties: List[Property] = List(),
      forbiddenProperties: List[Property] = List())(implicit decoder: Decoder[_]): DecodeJson[Node, Task] = {
    val filter = if (allowedProperties.nonEmpty) { node: Node =>
      val resultGraph = MemGraph.apply(UUID.randomUUID().toString)
      for {
        fNode <- resultGraph.nodes.create()
        _     <- Task.gatherUnordered(node.outE(allowedProperties: _*).map(e => fNode --- e.key --> e.to))
      } yield fNode
    } else if (forbiddenProperties.nonEmpty) { node: Node =>
      val resultGraph = MemGraph.apply(UUID.randomUUID().toString)
      for {
        fNode <- resultGraph.nodes.create()
        _ <- Task.gatherUnordered(
          node.outE().filterNot(forbiddenProperties.contains).map(e => fNode --- e.key --> e.to))
      } yield fNode
    } else { node: Node =>
      Task.now(node)
    }
    new DecodeJson[Node, Task] {
      def decode(implicit activeContext: ActiveContext) =
        (json: String) =>
          decoder
            .stringToLabeledNode(json, label)
            .flatMap(filter)
    }
  }

  /**
    *
    * @param label a label which is added to the resulting node
    * @param nodeToT a function to transform the parsed result to object T
    * @param allowedProperties a whitelist for properties which are accepted
    * @param decoder
    * @tparam T
    * @return
    */
  def jsonToNodeToT[T](
      label: Ontology,
      nodeToT: Node => T,
      allowedProperties: List[Property] = List(),
      forbiddenProperties: List[Property] = List())(implicit decoder: Decoder[_]): DecodeJson[T, Task] =
    new DecodeJson[T, Task] {
      def decode(implicit activeContext: ActiveContext): String => Task[T] = { json: String =>
        jsonToLabeledNode(label, allowedProperties, forbiddenProperties)
          .decode(activeContext)(json)
          .map(nodeToT(_))
      }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy