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

lspace.encode.EncodeJson.scala Maven / Gradle / Ivy

The newest version!
package lspace.encode

import lspace.NS.types
import lspace.codec.{ActiveContext, ContextedT}
import lspace.librarian.traversal.Collection
import lspace._
import Label.P._
import lspace.codec.json.jsonld.JsonLDEncoder
import lspace.graphql.{Projection, QueryResult}
import monix.eval.{Coeval, Task}

trait EncodeJson[A, F[_]] extends Encode[A, F] {
  type Out = String
}

object EncodeJson {
  type Aux[In, F[_], Out0] = EncodeJson[In, F] { type Out = Out0 }

  implicit def contextedTToJson[T](implicit en: EncodeJson[T, Coeval]) = new EncodeJson[ContextedT[T], Coeval] {
    def encode(implicit activeContext: ActiveContext) =
      (ct: ContextedT[T]) => en.encode(activeContext ++ ct.activeContext)(ct.t)
  }

  private def _nodeToJsonMap[Json](resource: Resource[_])(implicit encoder: JsonLDEncoder[Json],
                                                          activeContext: ActiveContext): Json = {
    import encoder.baseEncoder._
    (List(
      Some(resource.iri).filter(_.nonEmpty).map(_.asJson).map(`@id`.iri -> _),
      Some(resource.labels)
        .filter(_.nonEmpty)
        .map {
          case List(label) => activeContext.compactIri(label.iri).asJson
          case labels =>
            val x = labels.map(_.iri).map(activeContext.compactIri(_).asJson)
            x.asJson
            labels.map(_.iri).map(activeContext.compactIri(_).asJson).asJson
        }
        .map(`@type`.iri -> _)
    ).filter(_.nonEmpty).map(_.get).toMap ++
      resource
        .outEMap()
        .map {
          case (property, edges) =>
            activeContext.compactIri(property.iri) -> (edges match {
              case List(edge) =>
                encoder.fromAny(edge.to, edge.to.labels.headOption).json
              case edges =>
                edges
                  .map(edge => encoder.fromAny(edge.to, edge.to.labels.headOption).json)
                  .asJson
            })
        }).asJson
  }

  implicit def nodeToJson[Json, T <: Node](implicit encoder: JsonLDEncoder[Json]): EncodeJson[T, Coeval] =
    new EncodeJson[T, Coeval] {
      import encoder.baseEncoder._
      def encode(implicit activeContext: ActiveContext): T => Coeval[String] =
        (node: T) => Coeval { _nodeToJsonMap(node).noSpaces }
    }

  implicit def nodesToJson[T, Json](implicit encoder: JsonLDEncoder[Json]): EncodeJson[List[T], Coeval] =
    new EncodeJson[List[T], Coeval] {
      import encoder.baseEncoder._
      def encode(implicit activeContext: ActiveContext): List[T] => Coeval[String] =
        (nodes: List[T]) =>
          Coeval {
            (nodes
              .map {
                case node: Node       => _nodeToJsonMap(node).asInstanceOf[Json]
                case edge: Edge[_, _] => _nodeToJsonMap(edge).asInstanceOf[Json]
                case value: Value[_]  => _nodeToJsonMap(value).asInstanceOf[Json]
                case value            => encoder.fromAny(value).json
              })
              .asJson
              .noSpaces
        }
    }

  implicit def collectionToJson[T, CT <: ClassType[_], Json](
      implicit encoder: JsonLDEncoder[Json]): EncodeJson[Collection[T, CT], Coeval] =
    new EncodeJson[Collection[T, CT], Coeval] {
      import encoder.baseEncoder._
      def encode(implicit activeContext: ActiveContext): Collection[T, CT] => Coeval[String] =
        (collection: Collection[T, CT]) => Coeval { encoder.fromAny(collection.item, collection.ct).json.noSpaces }
    }

  implicit def activeContextToJson[Json](implicit encoder: JsonLDEncoder[Json]): EncodeJson[ActiveContext, Coeval] = {
    import encoder.baseEncoder._

    new EncodeJson[ActiveContext, Coeval] {
      def encode(implicit activeContext: ActiveContext): ActiveContext => Coeval[String] =
        (activeContext: ActiveContext) =>
          Coeval {
            Map(
              types.`@context` -> encoder
                .fromActiveContext(activeContext)
                .getOrElse(Map[String, Json]().asJson)).asJson.noSpaces
        }
    }
  }

  implicit val encodeJsonJson: EncodeJson[String, Coeval] = new EncodeJson[String, Coeval] {
    def encode(implicit activeContext: ActiveContext) = (string: String) => Coeval { string }
  }
  implicit val encodeBooleanJson: EncodeJson[Boolean, Coeval] = new EncodeJson[Boolean, Coeval] {
    def encode(implicit activeContext: ActiveContext) = (value: Boolean) => Coeval { value.toString }
  }
  implicit val encodeIntJson: EncodeJson[Int, Coeval] = new EncodeJson[Int, Coeval] {
    def encode(implicit activeContext: ActiveContext) = (value: Int) => Coeval { value.toString }
  }
  implicit val encodeDoubleJson: EncodeJson[Double, Coeval] = new EncodeJson[Double, Coeval] {
    def encode(implicit activeContext: ActiveContext) = (value: Double) => Coeval { value.toString }
  }
  implicit val encodeLongJson: EncodeJson[Long, Coeval] = new EncodeJson[Long, Coeval] {
    def encode(implicit activeContext: ActiveContext) = (value: Long) => Coeval { value.toString }
  }

  protected[encode] def namedProjection[Json](projection: Projection, result: List[Any])(
      implicit encoder: JsonLDEncoder[Json],
      activeContext: ActiveContext): Option[Json] = {
    import encoder._
    import encoder.baseEncoder._

    result match {
      case Nil => None
      case result =>
        projection.projections match {
          case Nil =>
            val expKey = activeContext.expandIri(projection.name).iri
            result match {
              case List(value) =>
                Some(encoder.fromAny(value, activeContext.expectedType(expKey)).json)
              case values =>
                Some(values.map(value => encoder.fromAny(value, activeContext.expectedType(expKey)).json).asJson)
            }
          case projections =>
            Some((projection.projections zip result) flatMap {
              case (projection, result: List[Any]) =>
                namedProjection(projection, result).map(v => projection.alias -> v)
            } toMap).map(_.asJson)
        }
    }
  }

  protected[encode] def _queryresultToJsonMap[Json](queryResult: QueryResult)(implicit encoder: JsonLDEncoder[Json],
                                                                              activeContext: ActiveContext): Json = {
    import encoder.baseEncoder._

    queryResult.result match {
      case Nil => List[Json]().asJson
      case result =>
        (result.map {
          case result: List[Any] =>
            ((queryResult.query.projections zip result) flatMap {
              case (projection, result: List[Any]) =>
                namedProjection(projection, result).map(projection.alias -> _)
              case (projection, result: List[Any]) =>
                namedProjection(projection, result).map(projection.alias -> _)
            } toMap).asJson
          case result: Product =>
            ((queryResult.query.projections zip result.productIterator.toList) flatMap {
              case (projection, result: List[Any]) =>
                namedProjection(projection, result).map(projection.alias -> _)
              case (projection, result: List[Any]) =>
                namedProjection(projection, result).map(projection.alias -> _)
            } toMap).asJson
        }).asJson

      case _ => throw new Exception("XXX")
    }
  }

  implicit def queryResultToJson[T <: QueryResult, Json](implicit encoder: JsonLDEncoder[Json]): EncodeJson[T, Coeval] =
    new EncodeJson[T, Coeval] {
      import encoder.baseEncoder._
      def encode(implicit activeContext: ActiveContext) =
        (node: T) => Coeval { _queryresultToJsonMap(node).asInstanceOf[Json].noSpaces }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy