io.circe.generic.extras.Configuration Scala Examples

The following examples show how to use io.circe.generic.extras.Configuration. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: EventSerializer.scala    From nexus-iam   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.io

import java.nio.charset.Charset

import akka.actor.ExtendedActorSystem
import akka.serialization.SerializerWithStringManifest
import ch.epfl.bluebrain.nexus.iam.acls.AclEvent
import ch.epfl.bluebrain.nexus.iam.config.AppConfig.HttpConfig
import ch.epfl.bluebrain.nexus.iam.config.Settings
import ch.epfl.bluebrain.nexus.iam.permissions.PermissionsEvent
import ch.epfl.bluebrain.nexus.iam.realms.RealmEvent
import ch.epfl.bluebrain.nexus.iam.types.GrantType.Camel._
import ch.epfl.bluebrain.nexus.rdf.Iri.Url
import ch.epfl.bluebrain.nexus.rdf.implicits._
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto._
import io.circe.parser._
import io.circe.syntax._
import io.circe.{Decoder, Encoder, Printer}


class EventSerializer(system: ExtendedActorSystem) extends SerializerWithStringManifest {
  private val utf8 = Charset.forName("UTF-8")

  private val printer = Printer.noSpaces.copy(dropNullValues = true)

  private[io] implicit val http: HttpConfig = Settings(system).appConfig.http

  private[io] implicit val config: Configuration = Configuration.default.withDiscriminator("@type")

  private[io] implicit val urlEncoder: Encoder[Url] =
    Encoder.encodeString.contramap(_.asUri)
  private[io] implicit val urlDecoder: Decoder[Url] =
    Decoder.decodeString.emap(Url.apply)

  private[io] implicit val permissionEventEncoder: Encoder[PermissionsEvent] = deriveConfiguredEncoder[PermissionsEvent]
  private[io] implicit val permissionEventDecoder: Decoder[PermissionsEvent] = deriveConfiguredDecoder[PermissionsEvent]
  private[io] implicit val aclEventEncoder: Encoder[AclEvent]                = deriveConfiguredEncoder[AclEvent]
  private[io] implicit val aclEventDecoder: Decoder[AclEvent]                = deriveConfiguredDecoder[AclEvent]
  private[io] implicit val realmEventEncoder: Encoder[RealmEvent]            = deriveConfiguredEncoder[RealmEvent]
  private[io] implicit val realmEventDecoder: Decoder[RealmEvent]            = deriveConfiguredDecoder[RealmEvent]

  override val identifier: Int = 1225

  override def manifest(o: AnyRef): String = o match {
    case _: PermissionsEvent => "permissions-event"
    case _: AclEvent         => "acl-event"
    case _: RealmEvent       => "realm-event"
    case other =>
      throw new IllegalArgumentException(
        s"Cannot determine manifest for unknown type: '${other.getClass.getCanonicalName}'"
      )
  }
  override def toBinary(o: AnyRef): Array[Byte] = o match {
    case ev: PermissionsEvent => ev.asJson.printWith(printer).getBytes(utf8)
    case ev: AclEvent         => ev.asJson.printWith(printer).getBytes(utf8)
    case ev: RealmEvent       => ev.asJson.printWith(printer).getBytes(utf8)
    case other =>
      throw new IllegalArgumentException(s"Cannot serialize unknown type: '${other.getClass.getCanonicalName}'")
  }
  override def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = manifest match {
    case "permissions-event" =>
      val str = new String(bytes, utf8)
      decode[PermissionsEvent](str)
        .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'PermissionsEvent'"))
    case "acl-event" =>
      val str = new String(bytes, utf8)
      decode[AclEvent](str)
        .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'AclEvent'"))
    case "realm-event" =>
      val str = new String(bytes, utf8)
      decode[RealmEvent](str)
        .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'RealmEvent'"))
    case other =>
      throw new IllegalArgumentException(s"Cannot deserialize type with unknown manifest: '$other'")
  }
} 
Example 2
Source File: Rejection.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.storage

import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.model.Uri.Path
import akka.http.scaladsl.server.{Rejection => AkkaRejection}
import ch.epfl.bluebrain.nexus.storage.routes.StatusFrom
import scala.annotation.nowarn
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}


  final case class EmptyFilename(name: String)

  implicit def statusCodeFrom: StatusFrom[Rejection] =
    StatusFrom {
      case _: PathContainsLinks => StatusCodes.BadRequest
      case _: PathAlreadyExists => StatusCodes.Conflict
      case _: BucketNotFound    => StatusCodes.NotFound
      case _: PathNotFound      => StatusCodes.NotFound
    }

  @nowarn("cat=unused")
  implicit val rejectionEncoder: Encoder[Rejection] = {
    implicit val rejectionConfig: Configuration = Configuration.default.withDiscriminator("@type")
    val enc                                     = deriveConfiguredEncoder[Rejection].mapJson(jsonError)
    Encoder.instance(r => enc(r) deepMerge Json.obj("reason" -> Json.fromString(r.msg)))
  }
} 
Example 3
Source File: Gradient2D.scala    From evilplot   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.cibo.evilplot.geometry

import com.cibo.evilplot.JSONUtils.minifyProperties
import com.cibo.evilplot.colors.Color
import com.cibo.evilplot.numeric.{Point, Point2d}
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto._
import io.circe.{Decoder, Encoder, ObjectEncoder}

sealed trait Gradient2d {
  val stops: Seq[GradientStop]
}
object Gradient2d {
  implicit val decoder: Decoder[Gradient2d] = deriveDecoder[Gradient2d]
  implicit val encoder: Encoder[Gradient2d] = deriveEncoder[Gradient2d]
}

case class GradientStop(offset: Double, color: Color)
object GradientStop {
  implicit val decoder: Decoder[GradientStop] = deriveDecoder[GradientStop]
  implicit val encoder: Encoder[GradientStop] = deriveEncoder[GradientStop]
}

case class LinearGradient(x0: Double, y0: Double, x1: Double, y1: Double, stops: Seq[GradientStop])
    extends Gradient2d

object LinearGradient {
  implicit val decoder: Decoder[LinearGradient] = deriveDecoder[LinearGradient]
  implicit val encoder: Encoder[LinearGradient] = deriveEncoder[LinearGradient]

  def leftToRight(ex: Extent, stops: Seq[GradientStop]): LinearGradient =
    LinearGradient(0, 0, x1 = ex.width, 0, stops)

  def rightToLeft(ex: Extent, stops: Seq[GradientStop]): LinearGradient =
    LinearGradient(x0 = ex.width, 0, 0, 0, stops)

  def topToBottom(ex: Extent, stops: Seq[GradientStop]): LinearGradient =
    LinearGradient(0, 0, 0, y1 = ex.height, stops)

  def bottomToTop(ex: Extent, stops: Seq[GradientStop]): LinearGradient = {
    LinearGradient(0, y0 = ex.height, 0, 0, stops)
  }
}

case class RadialGradient(
  x0: Double,
  y0: Double,
  r0: Double,
  x1: Double,
  y1: Double,
  stops: Seq[GradientStop])
    extends Gradient2d

object RadialGradient {
  implicit val decoder: Decoder[RadialGradient] = deriveDecoder[RadialGradient]
  implicit val encoder: Encoder[RadialGradient] = deriveEncoder[RadialGradient]

  def withinExtent(extent: Extent, stops: Seq[GradientStop]): RadialGradient = {
    val radius = extent.height.min(extent.width) / 2

    RadialGradient(
      extent.width / 2,
      extent.height / 2,
      radius,
      extent.width / 2,
      extent.height / 2,
      stops
    )
  }
} 
Example 4
Source File: LineStyle.scala    From evilplot   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.cibo.evilplot.geometry

import com.cibo.evilplot.JSONUtils
import io.circe.{Decoder, Encoder}
import io.circe.generic.extras.Configuration


final case class LineStyle(
  dashPattern: Seq[Double] = Seq.empty[Double],
  offset: Double = 0.0
) {
  require(dashPattern.forall(_ > 0), "A dash pattern must only contain positive values.")
}
object LineStyle {
  import io.circe.generic.extras.semiauto._
  private implicit val jsonConfig: Configuration = JSONUtils.minifyProperties
  implicit val lineStyleEncoder: Encoder[LineStyle] = deriveEncoder[LineStyle]
  implicit val lineStyleDecoder: Decoder[LineStyle] = deriveDecoder[LineStyle]

  val Solid: LineStyle = LineStyle()
  val Dotted: LineStyle = LineStyle(Seq(1, 2))
  val DashDot: LineStyle = LineStyle(Seq(6, 3, 1, 3))
  val Dashed: LineStyle = LineStyle(Seq(6))
  def evenlySpaced(dist: Double): LineStyle = LineStyle(Seq(dist))
} 
Example 5
Source File: Extent.scala    From evilplot   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.cibo.evilplot.geometry

import com.cibo.evilplot.JSONUtils
import com.cibo.evilplot.numeric.{Point, Point2d}
import io.circe.generic.extras.Configuration
import io.circe.{Decoder, Encoder}


case class Extent(width: Double, height: Double) {
  def *(scale: Double): Extent = Extent(scale * width, scale * height)
  def -(w: Double = 0.0, h: Double = 0.0): Extent = Extent(width - w, height - h)

  private[evilplot] def contains(p: Point2d): Boolean = {
    p.x >= 0 && p.x <= width && p.y >= 0 && p.y <= height
  }
}

object Extent {
  private implicit val cfg: Configuration = JSONUtils.minifyProperties
  implicit val extentEncoder: Encoder[Extent] =
    io.circe.generic.extras.semiauto.deriveEncoder[Extent]
  implicit val extentDecoder: Decoder[Extent] =
    io.circe.generic.extras.semiauto.deriveDecoder[Extent]
} 
Example 6
Source File: JSONUtils.scala    From evilplot   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.cibo.evilplot

import io.circe.generic.extras.Configuration
import io.circe.parser.decode
import io.circe.syntax._
import io.circe.{Decoder, Encoder, Error}

object JSONUtils {
  // This should only be used for colors, drawables, and extents.
  private[evilplot] implicit val minifyProperties: Configuration = Configuration.default.copy(
    transformMemberNames = s => s.take(2).toString,
    transformConstructorNames = shortenedName
  )

  // scalastyle:off
  private def shortenedName(s: String): String = {
    s match {
      case "EmptyDrawable" => "E"
      case "Line"          => "L"
      case "Path"          => "P"
      case "Polygon"       => "p"
      case "Rect"          => "R"
      case "BorderRect"    => "B"
      case "Disc"          => "D"
      case "Wedge"         => "W"
      case "Translate"     => "T"
      case "Affine"        => "A"
      case "Scale"         => "C"
      case "Rotate"        => "O"
      case "Group"         => "G"
      case "Resize"        => "Re"
      case "Style"         => "S"
      case "StrokeStyle"   => "Y"
      case "StrokeWeight"  => "H"
      case "LineDash"      => "l"
      case "Text"          => "X"
      case "HSLA"          => "c"
      case "GradientFill"  => "gf"
      case other           => other
    }
  }
  // scalastyle:on

  // Wrap the Circe JSON decode method and return just the desired type, not an Either.
  // If parsing returns an error, throw the error rather than returning it.
  def decodeStr[A: Decoder](input: String): A = {
    val a: Either[Error, A] = decode[A](input)
    a match {
      case Left(error)   => throw error
      case Right(result) => result
    }
  }

  // Encode the input object to JSON, then convert the JSON to a string and return it.
  def encodeObj[A: Encoder](input: A): String = {
    input.asJson.noSpaces
  }
} 
Example 7
Source File: PermissionsEvent.scala    From nexus-iam   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.permissions

import java.time.Instant

import ch.epfl.bluebrain.nexus.iam.config.AppConfig.HttpConfig
import ch.epfl.bluebrain.nexus.iam.config.Contexts._
import ch.epfl.bluebrain.nexus.iam.types.Identity.Subject
import ch.epfl.bluebrain.nexus.iam.types.{Identity, Permission}
import ch.epfl.bluebrain.nexus.rdf.implicits._
import com.github.ghik.silencer.silent
import io.circe.Encoder
import io.circe.generic.extras.Configuration


  final case class PermissionsDeleted(
      rev: Long,
      instant: Instant,
      subject: Subject
  ) extends PermissionsEvent

  object JsonLd {
    import io.circe.generic.extras.semiauto._

    @silent // defined implicits are not recognized as being used
    implicit def permissionsEventEncoder(implicit http: HttpConfig): Encoder[Event] = {
      implicit val config: Configuration = Configuration.default
        .withDiscriminator("@type")
        .copy(transformMemberNames = {
          case "rev"     => "_rev"
          case "instant" => "_instant"
          case "subject" => "_subject"
          case other     => other
        })
      implicit val subjectEncoder: Encoder[Subject] = Identity.subjectIdEncoder
      deriveConfiguredEncoder[Event]
        .mapJson { json =>
          json
            .addContext(iamCtxUri)
            .addContext(resourceCtxUri)
        }
    }
  }
} 
Example 8
Source File: AclRejection.scala    From nexus-iam   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.acls

import akka.http.scaladsl.model.StatusCodes.{BadRequest, Conflict, NotFound}
import ch.epfl.bluebrain.nexus.commons.http.directives.StatusFrom
import ch.epfl.bluebrain.nexus.iam.config.Contexts.errorCtxUri
import ch.epfl.bluebrain.nexus.iam.types.{Permission, ResourceRejection}
import ch.epfl.bluebrain.nexus.rdf.Iri.Path
import ch.epfl.bluebrain.nexus.rdf.implicits._
import com.github.ghik.silencer.silent
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

sealed abstract class AclRejection(val msg: String) extends ResourceRejection

object AclRejection {

  
  final case class UnknownPermissions(permissions: Set[Permission])
      extends AclRejection(
        s"Some of the permissions specified are not known: '${permissions.mkString("\"", ", ", "\"")}'"
      )

  @silent // rejectionConfig is not recognized as being used
  implicit val aclRejectionEncoder: Encoder[AclRejection] = {
    implicit val rejectionConfig: Configuration = Configuration.default.withDiscriminator("@type")
    val enc                                     = deriveConfiguredEncoder[AclRejection].mapJson(_ addContext errorCtxUri)
    Encoder.instance(r => enc(r) deepMerge Json.obj("reason" -> Json.fromString(r.msg)))
  }

  implicit val aclRejectionStatusFrom: StatusFrom[AclRejection] =
    StatusFrom {
      case _: NothingToBeUpdated                        => BadRequest
      case _: AclIsEmpty                                => BadRequest
      case _: AclCannotContainEmptyPermissionCollection => BadRequest
      case _: AclNotFound                               => NotFound
      case _: IncorrectRev                              => Conflict
      case _: UnknownPermissions                        => BadRequest
    }
} 
Example 9
Source File: AclEvent.scala    From nexus-iam   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.acls

import java.time.Instant

import ch.epfl.bluebrain.nexus.iam.config.AppConfig.HttpConfig
import ch.epfl.bluebrain.nexus.iam.config.Contexts._
import ch.epfl.bluebrain.nexus.iam.types.Identity
import ch.epfl.bluebrain.nexus.iam.types.Identity.Subject
import ch.epfl.bluebrain.nexus.rdf.Iri.Path
import ch.epfl.bluebrain.nexus.rdf.implicits._
import com.github.ghik.silencer.silent
import io.circe.Encoder
import io.circe.generic.extras.Configuration


  final case class AclDeleted(
      path: Path,
      rev: Long,
      instant: Instant,
      subject: Subject
  ) extends AclEvent

  object JsonLd {
    import io.circe.generic.extras.semiauto._

    @silent // defined implicits are not recognized as being used
    implicit def aclEventEncoder(implicit httpConfig: HttpConfig): Encoder[AclEvent] = {
      implicit val config: Configuration = Configuration.default
        .withDiscriminator("@type")
        .copy(transformMemberNames = {
          case "rev"     => "_rev"
          case "instant" => "_instant"
          case "subject" => "_subject"
          case "path"    => "_path"
          case other     => other
        })
      implicit val arrayEncoder: Encoder[AccessControlList] = AccessControlList.aclArrayEncoder
      implicit val subjectEncoder: Encoder[Subject]         = Identity.subjectIdEncoder
      deriveConfiguredEncoder[AclEvent]
        .mapJson { json =>
          json
            .addContext(iamCtxUri)
            .addContext(resourceCtxUri)
        }
    }
  }
} 
Example 10
Source File: ActiveRealm.scala    From nexus-iam   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.realms

import ch.epfl.bluebrain.nexus.iam.config.Vocabulary.nxv
import ch.epfl.bluebrain.nexus.iam.types.GrantType.Camel._
import ch.epfl.bluebrain.nexus.iam.types.{GrantType, Label}
import ch.epfl.bluebrain.nexus.rdf.Iri.Url
import ch.epfl.bluebrain.nexus.rdf.implicits._
import com.nimbusds.jose.jwk.{JWK, JWKSet}
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

import scala.util.Try


final case class ActiveRealm(
    id: Label,
    name: String,
    openIdConfig: Url,
    issuer: String,
    grantTypes: Set[GrantType],
    logo: Option[Url],
    authorizationEndpoint: Url,
    tokenEndpoint: Url,
    userInfoEndpoint: Url,
    revocationEndpoint: Option[Url],
    endSessionEndpoint: Option[Url],
    keys: Set[Json]
) {

  private[realms] lazy val keySet: JWKSet = {
    val jwks = keys.foldLeft(Set.empty[JWK]) {
      case (acc, e) => Try(JWK.parse(e.noSpaces)).map(acc + _).getOrElse(acc)
    }
    import scala.jdk.CollectionConverters._
    new JWKSet(jwks.toList.asJava)
  }
}

object ActiveRealm {
  private[ActiveRealm] implicit val config: Configuration = Configuration.default.copy(transformMemberNames = {
    case "issuer"                => nxv.issuer.prefix
    case "grantTypes"            => nxv.grantTypes.prefix
    case "authorizationEndpoint" => nxv.authorizationEndpoint.prefix
    case "tokenEndpoint"         => nxv.tokenEndpoint.prefix
    case "userInfoEndpoint"      => nxv.userInfoEndpoint.prefix
    case "revocationEndpoint"    => nxv.revocationEndpoint.prefix
    case "endSessionEndpoint"    => nxv.endSessionEndpoint.prefix
    case other                   => other
  })
  implicit val activeEncoder: Encoder[ActiveRealm] = {
    val default = deriveConfiguredEncoder[ActiveRealm]
    Encoder
      .instance[ActiveRealm] { realm =>
        default(realm) deepMerge Json.obj(
          nxv.label.prefix      -> Json.fromString(realm.id.value),
          nxv.deprecated.prefix -> Json.fromBoolean(false)
        )
      }
      .mapJson(_.removeKeys("keys", "id"))
  }
} 
Example 11
Source File: TokenRejection.scala    From nexus-iam   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.auth

import com.github.ghik.silencer.silent
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}


  final case object InvalidAccessToken
      extends TokenRejection(
        "The token is invalid; possible causes are: incorrect signature, the token is expired or the 'nbf' value was not met."
      )

  @silent // rejectionConfig is not recognized as being used
  implicit val tokenRejectionEncoder: Encoder[TokenRejection] = {
    implicit val rejectionConfig: Configuration = Configuration.default.withDiscriminator("@type")
    val enc                                     = deriveConfiguredEncoder[TokenRejection]
    Encoder.instance(r => enc(r) deepMerge Json.obj("reason" -> Json.fromString(r.msg)))
  }
} 
Example 12
Source File: File.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.storage

import akka.http.scaladsl.model.{ContentType, Uri}
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.storage.config.Contexts.resourceCtxUri
import scala.annotation.nowarn
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto._
import io.circe.{Decoder, Encoder}

// $COVERAGE-OFF$
object File {

  @nowarn("cat=unused")
  implicit private val config: Configuration = Configuration.default
    .copy(transformMemberNames = {
      case "@context" => "@context"
      case key        => s"_$key"
    })

  
  final case class Digest(algorithm: String, value: String)

  object Digest {
    val empty: Digest                           = Digest("", "")
    implicit val digestEncoder: Encoder[Digest] = deriveConfiguredEncoder[Digest]
    implicit val digestDecoder: Decoder[Digest] = deriveConfiguredDecoder[Digest]
  }

}
// $COVERAGE-ON$ 
Example 13
Source File: EnumerationEncoder.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras.encoding

import io.circe.{ Encoder, Json }
import io.circe.generic.extras.Configuration
import scala.annotation.implicitNotFound
import shapeless.{ :+:, CNil, Coproduct, HNil, Inl, Inr, LabelledGeneric, Witness }
import shapeless.labelled.FieldType

@implicitNotFound(
  """Could not find EnumerationEncoder for type ${A}.
Some possible causes for this:
- ${A} isn't a case class or sealed trat
- some of ${A}'s members don't have codecs of their own
- missing implicit Configuration"""
)
abstract class EnumerationEncoder[A] extends Encoder[A]

object EnumerationEncoder {
  implicit val encodeEnumerationCNil: EnumerationEncoder[CNil] = new EnumerationEncoder[CNil] {
    def apply(a: CNil): Json = sys.error("Cannot encode CNil")
  }

  implicit def encodeEnumerationCCons[K <: Symbol, V, R <: Coproduct](implicit
    witK: Witness.Aux[K],
    gen: LabelledGeneric.Aux[V, HNil],
    encodeR: EnumerationEncoder[R],
    config: Configuration = Configuration.default
  ): EnumerationEncoder[FieldType[K, V] :+: R] = new EnumerationEncoder[FieldType[K, V] :+: R] {
    def apply(a: FieldType[K, V] :+: R): Json = a match {
      case Inl(l) => Json.fromString(config.transformConstructorNames(witK.value.name))
      case Inr(r) => encodeR(r)
    }
  }

  implicit def encodeEnumeration[A, Repr <: Coproduct](implicit
    gen: LabelledGeneric.Aux[A, Repr],
    encodeR: EnumerationEncoder[Repr]
  ): EnumerationEncoder[A] =
    new EnumerationEncoder[A] {
      def apply(a: A): Json = encodeR(gen.to(a))
    }
} 
Example 14
Source File: ConfiguredAsObjectEncoder.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras.encoding

import io.circe.JsonObject
import io.circe.generic.encoding.DerivedAsObjectEncoder
import io.circe.generic.extras.{ Configuration, JsonKey }
import java.util.concurrent.ConcurrentHashMap
import scala.annotation.implicitNotFound
import scala.collection.immutable.Map
import shapeless.{ Annotations, Coproduct, HList, LabelledGeneric, Lazy }
import shapeless.ops.hlist.ToTraversable
import shapeless.ops.record.Keys

@implicitNotFound(
  """Could not find ConfiguredAsObjectEncoder for type ${A}.
Some possible causes for this:
- ${A} isn't a case class or sealed trat
- some of ${A}'s members don't have codecs of their own
- missing implicit Configuration"""
)
abstract class ConfiguredAsObjectEncoder[A](config: Configuration) extends DerivedAsObjectEncoder[A] {
  private[this] val constructorNameCache: ConcurrentHashMap[String, String] =
    new ConcurrentHashMap[String, String]()

  protected[this] def constructorNameTransformer(value: String): String = {
    val current = constructorNameCache.get(value)

    if (current eq null) {
      val transformed = config.transformConstructorNames(value)
      constructorNameCache.put(value, transformed)
      transformed
    } else {
      current
    }
  }
}

object ConfiguredAsObjectEncoder {
  implicit def encodeCaseClass[A, R <: HList, F <: HList, K <: HList](implicit
    gen: LabelledGeneric.Aux[A, R],
    encode: Lazy[ReprAsObjectEncoder[R]],
    config: Configuration,
    fields: Keys.Aux[R, F],
    fieldsToList: ToTraversable.Aux[F, List, Symbol],
    keys: Annotations.Aux[JsonKey, A, K],
    keysToList: ToTraversable.Aux[K, List, Option[JsonKey]]
  ): ConfiguredAsObjectEncoder[A] = new ConfiguredAsObjectEncoder[A](config) {
    private[this] val keyAnnotations: List[Option[JsonKey]] = keysToList(keys())
    private[this] val hasKeyAnnotations: Boolean = keyAnnotations.exists(_.nonEmpty)

    private[this] val keyAnnotationMap: Map[String, String] =
      fieldsToList(fields())
        .map(_.name)
        .zip(keyAnnotations)
        .collect {
          case (field, Some(keyAnnotation)) => (field, keyAnnotation.value)
        }
        .toMap

    private[this] def memberNameTransformer(value: String): String =
      if (hasKeyAnnotations)
        keyAnnotationMap.getOrElse(value, config.transformMemberNames(value))
      else
        config.transformMemberNames(value)

    private[this] val transformedMemberCache: Map[String, String] = {
      fieldsToList(fields()).map(f => (f.name, memberNameTransformer(f.name))).toMap
    }

    private[this] def transformMemberName(value: String) =
      transformedMemberCache.getOrElse(value, value)

    final def encodeObject(a: A): JsonObject =
      encode.value.configuredEncodeObject(gen.to(a))(
        transformMemberName,
        constructorNameTransformer,
        None
      )
  }

  implicit def encodeAdt[A, R <: Coproduct](implicit
    gen: LabelledGeneric.Aux[A, R],
    encode: Lazy[ReprAsObjectEncoder[R]],
    config: Configuration
  ): ConfiguredAsObjectEncoder[A] = new ConfiguredAsObjectEncoder[A](config) {
    final def encodeObject(a: A): JsonObject =
      encode.value.configuredEncodeObject(gen.to(a))(
        Predef.identity,
        constructorNameTransformer,
        config.discriminator
      )
  }
} 
Example 15
Source File: ConfiguredAsObjectCodec.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras.codec

import io.circe.{ Decoder, Encoder, HCursor, JsonObject }
import io.circe.generic.codec.DerivedAsObjectCodec
import io.circe.generic.extras.{ Configuration, JsonKey }
import io.circe.generic.extras.decoding.ConfiguredDecoder
import io.circe.generic.extras.encoding.ConfiguredAsObjectEncoder
import io.circe.generic.extras.util.RecordToMap
import scala.annotation.implicitNotFound
import shapeless.{ Annotations, Coproduct, Default, HList, LabelledGeneric, Lazy }
import shapeless.ops.hlist.ToTraversable
import shapeless.ops.record.Keys

@implicitNotFound(
  """Could not find ConfiguredAsObjectCodec for type ${A}.
Some possible causes for this:
- ${A} isn't a case class or sealed trat
- some of ${A}'s members don't have codecs of their own
- missing implicit Configuration"""
)
abstract class ConfiguredAsObjectCodec[A] extends DerivedAsObjectCodec[A]

object ConfiguredAsObjectCodec {
  implicit def codecForCaseClass[A, R <: HList, D <: HList, F <: HList, K <: HList](implicit
    gen: LabelledGeneric.Aux[A, R],
    codec: Lazy[ReprAsObjectCodec[R]],
    defaults: Default.AsRecord.Aux[A, D],
    defaultMapper: RecordToMap[D],
    config: Configuration,
    fields: Keys.Aux[R, F],
    fieldsToList: ToTraversable.Aux[F, List, Symbol],
    keys: Annotations.Aux[JsonKey, A, K],
    keysToList: ToTraversable.Aux[K, List, Option[JsonKey]]
  ): ConfiguredAsObjectCodec[A] = new ConfiguredAsObjectCodec[A] {
    private[this] val decodeA: Decoder[A] =
      ConfiguredDecoder.decodeCaseClass[A, R, D, F, K](
        gen,
        codec,
        defaults,
        defaultMapper,
        config,
        fields,
        fieldsToList,
        keys,
        keysToList
      )

    private[this] val encodeA: Encoder.AsObject[A] =
      ConfiguredAsObjectEncoder.encodeCaseClass[A, R, F, K](gen, codec, config, fields, fieldsToList, keys, keysToList)

    final def apply(c: HCursor): Decoder.Result[A] = decodeA.apply(c)
    final override def decodeAccumulating(c: HCursor): Decoder.AccumulatingResult[A] = decodeA.decodeAccumulating(c)

    final def encodeObject(a: A): JsonObject = encodeA.encodeObject(a)
  }

  implicit def codecForAdt[A, R <: Coproduct](implicit
    gen: LabelledGeneric.Aux[A, R],
    codec: Lazy[ReprAsObjectCodec[R]],
    config: Configuration
  ): ConfiguredAsObjectCodec[A] = new ConfiguredAsObjectCodec[A] {
    private[this] val decodeA: Decoder[A] =
      ConfiguredDecoder.decodeAdt[A, R](gen, codec, config)

    private[this] val encodeA: Encoder.AsObject[A] =
      ConfiguredAsObjectEncoder.encodeAdt[A, R](gen, codec, config)

    final def apply(c: HCursor): Decoder.Result[A] = decodeA.apply(c)
    final override def decodeAccumulating(c: HCursor): Decoder.AccumulatingResult[A] = decodeA.decodeAccumulating(c)

    final def encodeObject(a: A): JsonObject = encodeA.encodeObject(a)
  }
} 
Example 16
Source File: EnumerationCodec.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras.codec

import io.circe.{ Codec, Decoder, DecodingFailure, HCursor, Json }
import io.circe.generic.extras.Configuration
import scala.annotation.implicitNotFound
import shapeless.{ :+:, CNil, Coproduct, HNil, Inl, Inr, LabelledGeneric, Witness }
import shapeless.labelled.{ FieldType, field }

@implicitNotFound(
  """Could not find EnumerationCodec for type ${A}.
Some possible causes for this:
- ${A} isn't a case class or sealed trat
- some of ${A}'s members don't have codecs of their own
- missing implicit Configuration"""
)
abstract class EnumerationCodec[A] extends Codec[A]

object EnumerationCodec {
  implicit val codecForEnumerationCNil: EnumerationCodec[CNil] = new EnumerationCodec[CNil] {
    def apply(c: HCursor): Decoder.Result[CNil] = Left(DecodingFailure("Enumeration", c.history))
    def apply(a: CNil): Json = sys.error("Cannot encode CNil")
  }

  implicit def codecForEnumerationCCons[K <: Symbol, V, R <: Coproduct](implicit
    witK: Witness.Aux[K],
    gen: LabelledGeneric.Aux[V, HNil],
    codecForR: EnumerationCodec[R],
    config: Configuration = Configuration.default
  ): EnumerationCodec[FieldType[K, V] :+: R] = new EnumerationCodec[FieldType[K, V] :+: R] {
    def apply(c: HCursor): Decoder.Result[FieldType[K, V] :+: R] =
      c.as[String] match {
        case Right(s) if s == config.transformConstructorNames(witK.value.name) =>
          Right(Inl(field[K](gen.from(HNil))))
        case Right(_) =>
          codecForR.apply(c) match {
            case Right(v)  => Right(Inr(v))
            case Left(err) => Left(err)
          }
        case Left(err) => Left(DecodingFailure("Enumeration", c.history))
      }
    def apply(a: FieldType[K, V] :+: R): Json = a match {
      case Inl(l) => Json.fromString(config.transformConstructorNames(witK.value.name))
      case Inr(r) => codecForR(r)
    }
  }

  implicit def codecForEnumeration[A, R <: Coproduct](implicit
    gen: LabelledGeneric.Aux[A, R],
    codecForR: EnumerationCodec[R]
  ): EnumerationCodec[A] =
    new EnumerationCodec[A] {
      def apply(c: HCursor): Decoder.Result[A] = codecForR(c) match {
        case Right(v)  => Right(gen.from(v))
        case Left(err) => Left(err)
      }
      def apply(a: A): Json = codecForR(gen.to(a))
    }
} 
Example 17
Source File: IncompleteConfiguredDecoders.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras.decoding

import io.circe.{ Decoder, HCursor }
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.util.RecordToMap
import io.circe.generic.util.PatchWithOptions
import scala.collection.immutable.Map
import shapeless.{ Default, HList, LabelledGeneric }
import shapeless.ops.function.FnFromProduct
import shapeless.ops.record.RemoveAll

private[circe] trait IncompleteConfiguredDecoders {
  implicit final def decodeIncompleteCaseClass[F, P <: HList, A, D <: HList, T <: HList, R <: HList](implicit
    ffp: FnFromProduct.Aux[P => A, F],
    gen: LabelledGeneric.Aux[A, T],
    removeAll: RemoveAll.Aux[T, P, (P, R)],
    decode: ReprDecoder[R],
    defaults: Default.AsRecord.Aux[A, D],
    defaultMapper: RecordToMap[D],
    config: Configuration
  ): ConfiguredDecoder[F] = new ConfiguredDecoder[F](config) {
    private[this] val defaultMap: Map[String, Any] = if (config.useDefaults) defaultMapper(defaults()) else Map.empty

    final def apply(c: HCursor): Decoder.Result[F] = decode.configuredDecode(c)(
      config.transformMemberNames,
      constructorNameTransformer,
      defaultMap,
      None
    ) match {
      case Right(r)    => Right(ffp(p => gen.from(removeAll.reinsert((p, r)))))
      case l @ Left(_) => l.asInstanceOf[Decoder.Result[F]]
    }

    override final def decodeAccumulating(c: HCursor): Decoder.AccumulatingResult[F] =
      decode
        .configuredDecodeAccumulating(c)(
          config.transformMemberNames,
          constructorNameTransformer,
          defaultMap,
          None
        )
        .map(r => ffp(p => gen.from(removeAll.reinsert((p, r)))))
  }

  implicit final def decodeCaseClassPatch[A, D <: HList, R <: HList, O <: HList](implicit
    gen: LabelledGeneric.Aux[A, R],
    patch: PatchWithOptions.Aux[R, O],
    decode: ReprDecoder[O],
    defaults: Default.AsRecord.Aux[A, D],
    defaultMapper: RecordToMap[D],
    config: Configuration
  ): ConfiguredDecoder[A => A] = new ConfiguredDecoder[A => A](config) {
    private[this] val defaultMap: Map[String, Any] = if (config.useDefaults) defaultMapper(defaults()) else Map.empty

    final def apply(c: HCursor): Decoder.Result[A => A] = decode.configuredDecode(c)(
      config.transformMemberNames,
      constructorNameTransformer,
      defaultMap,
      None
    ) match {
      case Right(o)    => Right(a => gen.from(patch(gen.to(a), o)))
      case l @ Left(_) => l.asInstanceOf[Decoder.Result[A => A]]
    }

    override final def decodeAccumulating(c: HCursor): Decoder.AccumulatingResult[A => A] =
      decode
        .configuredDecodeAccumulating(c)(
          config.transformMemberNames,
          constructorNameTransformer,
          defaultMap,
          None
        )
        .map(o => a => gen.from(patch(gen.to(a), o)))
  }
} 
Example 18
Source File: EnumerationDecoder.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras.decoding

import io.circe.{ Decoder, DecodingFailure, HCursor }
import io.circe.generic.extras.Configuration
import scala.annotation.implicitNotFound
import shapeless.{ :+:, CNil, Coproduct, HNil, Inl, Inr, LabelledGeneric, Witness }
import shapeless.labelled.{ FieldType, field }

@implicitNotFound(
  """Could not find EnumerationDecoder for type ${A}.
Some possible causes for this:
- ${A} isn't a case class or sealed trat
- some of ${A}'s members don't have codecs of their own
- missing implicit Configuration"""
)
abstract class EnumerationDecoder[A] extends Decoder[A]

object EnumerationDecoder {
  implicit val decodeEnumerationCNil: EnumerationDecoder[CNil] = new EnumerationDecoder[CNil] {
    def apply(c: HCursor): Decoder.Result[CNil] = Left(DecodingFailure("Enumeration", c.history))
  }

  implicit def decodeEnumerationCCons[K <: Symbol, V, R <: Coproduct](implicit
    witK: Witness.Aux[K],
    gen: LabelledGeneric.Aux[V, HNil],
    decodeR: EnumerationDecoder[R],
    config: Configuration = Configuration.default
  ): EnumerationDecoder[FieldType[K, V] :+: R] = new EnumerationDecoder[FieldType[K, V] :+: R] {
    def apply(c: HCursor): Decoder.Result[FieldType[K, V] :+: R] =
      c.as[String] match {
        case Right(s) if s == config.transformConstructorNames(witK.value.name) =>
          Right(Inl(field[K](gen.from(HNil))))
        case Right(_) =>
          decodeR.apply(c) match {
            case Right(v)  => Right(Inr(v))
            case Left(err) => Left(err)
          }
        case Left(err) => Left(DecodingFailure("Enumeration", c.history))
      }
  }

  implicit def decodeEnumeration[A, Repr <: Coproduct](implicit
    gen: LabelledGeneric.Aux[A, Repr],
    decodeR: EnumerationDecoder[Repr]
  ): EnumerationDecoder[A] =
    new EnumerationDecoder[A] {
      def apply(c: HCursor): Decoder.Result[A] = decodeR(c) match {
        case Right(v)  => Right(gen.from(v))
        case Left(err) => Left(err)
      }
    }
} 
Example 19
Source File: package.scala    From patchless   with Apache License 2.0 5 votes vote down vote up
package patchless.circe

import cats.syntax.either._
import io.circe.{Decoder, HCursor, Json, JsonObject}
import io.circe.generic.decoding.DerivedDecoder
import io.circe.generic.extras.decoding.ReprDecoder
import io.circe.generic.encoding.DerivedObjectEncoder
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.encoding.ReprObjectEncoder
import io.circe.generic.extras.util.RecordToMap
import patchless.{Patch, Patchable}
import shapeless.{Default, HList, Lazy}

package object extras {

  
  implicit def decodeOptionOption[T](
    implicit decodeOpt: Decoder[Option[T]]
  ) : Decoder[Option[Option[T]]] =
    Decoder.withReattempt {
      c => if (c.succeeded) c.as[Option[T]].map(Some(_)) else Right(None)
    }

  implicit def decodePatch[T, U <: HList, D <: HList](implicit
    patchable: Patchable.Aux[T, U],
    decodeU: Lazy[ReprDecoder[U]],
    defaults: Default.AsRecord.Aux[T, D],
    defaultMapper: RecordToMap[D],
    config: Configuration
  ): DerivedDecoder[Patch[T]] = new DerivedDecoder[Patch[T]] {
    def apply(c: HCursor): Decoder.Result[Patch[T]] = decodeU.value.configuredDecode(c)(
      config.transformMemberNames,
      config.transformConstructorNames,
      if(config.useDefaults) defaultMapper(defaults()) else Map.empty,
      config.discriminator
    ).map {
      updates =>
        Patch.ofUpdates[T, U](updates)
    }
  }

  implicit def encodePatch[T, U <: HList](implicit
    patchable: Patchable.Aux[T, U],
    encodeU: Lazy[ReprObjectEncoder[U]],
    config: Configuration
  ): DerivedObjectEncoder[Patch[T]] = new DerivedObjectEncoder[Patch[T]] {
    def encodeObject(a: Patch[T]): JsonObject = encodeU.value.configuredEncodeObject(a.patchUpdates)(
      config.transformMemberNames,
      config.transformConstructorNames,
      config.discriminator
    )
  }

} 
Example 20
Source File: ConfigurablePatchJsonSpec.scala    From patchless   with Apache License 2.0 5 votes vote down vote up
package patchless.circe.extras

import cats.syntax.either._
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.auto._
import io.circe.parser.parse
import org.scalatest.{FreeSpec, Matchers}
import patchless.Patch
import shapeless.record.Record

class ConfigurablePatchJsonSpec extends FreeSpec with Matchers {


  "Configurable decoder" - {
    "Normal" in {
      import io.circe.generic.extras.defaults._
      case class Foo(aString: String, bInt: Int, cBoolean: Boolean)

      def parsePatch(str: String) =
        parse(str).valueOr(throw _).as[Patch[Foo]].valueOr(throw _)

      val aPatched = parsePatch("""{"aString": "patched"}""")
      val bPatched = parsePatch("""{"bInt": 22}""")
      val cPatched = parsePatch("""{"cBoolean": false}""")

      aPatched.updates shouldEqual Record(aString = Some("patched"), bInt = None, cBoolean = None)
      bPatched.updates shouldEqual Record(aString = None, bInt = Some(22), cBoolean = None)
      cPatched.updates shouldEqual Record(aString = None, bInt = None, cBoolean = Some(false))
    }

    "Snake case" in {
      implicit val configuration = Configuration.default.withSnakeCaseMemberNames
      case class Foo(aString: String, bInt: Int, cBoolean: Boolean)

      def parsePatch(str: String) =
        parse(str).valueOr(throw _).as[Patch[Foo]].valueOr(throw _)

      val aPatched = parsePatch("""{"a_string": "patched"}""")
      val bPatched = parsePatch("""{"b_int": 22}""")
      val cPatched = parsePatch("""{"c_boolean": false}""")

      aPatched.updates shouldEqual Record(aString = Some("patched"), bInt = None, cBoolean = None)
      bPatched.updates shouldEqual Record(aString = None, bInt = Some(22), cBoolean = None)
      cPatched.updates shouldEqual Record(aString = None, bInt = None, cBoolean = Some(false))
    }

    "Options" in {
      import io.circe.generic.extras.defaults._
      case class Foo(aString: Option[String])
      def parsePatch(str: String) =
        parse(str).valueOr(throw _).as[Patch[Foo]].valueOr(throw _)

      val aPatchedSome = parsePatch("""{"aString": "patched"}""")
      val aPatchedNone = parsePatch("""{"aString": null}""")

      aPatchedSome.updates shouldEqual Record(aString = Some(Some("patched")))
      aPatchedNone.updates shouldEqual Record(aString = Some(None))
    }

  }

} 
Example 21
Source File: EncodingUtils.scala    From scala-openrtb   with Apache License 2.0 5 votes vote down vote up
package com.powerspace.openrtb.json.util

import com.powerspace.openrtb.json.OpenRtbExtensions.ExtensionRegistry
import io.circe._
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.decoding.ConfiguredDecoder
import io.circe.generic.extras.encoding.ConfiguredAsObjectEncoder
import scalapb.{ExtendableMessage, GeneratedEnumCompanion, UnknownFieldSet}
import shapeless.Lazy

import scala.reflect.ClassTag
import scala.util.Try

object EncodingUtils {

  import PrimitivesUtils._
  import io.circe.generic.extras.semiauto._

  import scala.reflect.runtime.universe.TypeTag
  import scala.reflect.runtime.{currentMirror => cm}

  private implicit val customConfig: Configuration = Configuration.default.withSnakeCaseMemberNames.withDefaults

  def extendedEncoder[Ext <: ExtendableMessage[Ext]](
    implicit encoder: Lazy[ConfiguredAsObjectEncoder[Ext]],
    er: ExtensionRegistry,
    tag: ClassTag[Ext]): Encoder[Ext] =
    er.encoderWithExtensions[Ext](baseEncoder = openRtbEncoder)

  def openRtbEncoder[A](implicit encoder: Lazy[ConfiguredAsObjectEncoder[A]]): Encoder[A] =
    deriveConfiguredEncoder[A](encoder).cleanRtb

  def extendedDecoder[Ext <: ExtendableMessage[Ext]](
    implicit encoder: Lazy[ConfiguredDecoder[Ext]],
    er: ExtensionRegistry,
    tag: ClassTag[Ext]): Decoder[Ext] =
    er.decoderWithExtensions[Ext](baseDecoder = openRtbDecoder)

  def openRtbDecoder[A](implicit decoder: Lazy[ConfiguredDecoder[A]]): Decoder[A] = deriveConfiguredDecoder[A](decoder)

  
  def protobufOneofEncoder[Oneof <: _root_.scalapb.GeneratedOneof](
    partialFunction: PartialFunction[Oneof, Json]): Encoder[Oneof] = { oneOf: Oneof =>
    {
      if (oneOf.isEmpty) Json.Null
      else partialFunction.apply(oneOf)
    }
  }

  implicit val booleanDecoder: Decoder[Boolean] = Decoder.decodeBoolean.prepare(cursor => {
    cursor.withFocus(
      _.asNumber
        .map(
          number =>
            number.toInt
              .map(_.toBoolean)
              .map(Json.fromBoolean)
              getOrElse Json.False
        )
        .getOrElse(Json.False))
  })

} 
Example 22
Source File: OrganizationRejection.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.admin.organizations

import java.util.UUID

import akka.http.scaladsl.model.StatusCodes.{BadRequest, Conflict, NotFound}
import ch.epfl.bluebrain.nexus.commons.http.directives.StatusFrom
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.Contexts._
import ch.epfl.bluebrain.nexus.service.routes.ResourceRejection
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

import scala.annotation.nowarn

sealed abstract class OrganizationRejection(val msg: String) extends ResourceRejection

object OrganizationRejection {

  
  final case class IncorrectRev(expected: Long, provided: Long)
      extends OrganizationRejection(
        s"Incorrect revision '$provided' provided, expected '$expected', the organization may have been updated since last seen."
      )

  @nowarn("cat=unused")
  implicit val organizationRejectionEncoder: Encoder[OrganizationRejection] = {
    implicit val rejectionConfig: Configuration = Configuration.default.withDiscriminator("@type")
    val enc                                     = deriveConfiguredEncoder[OrganizationRejection].mapJson(_ addContext errorCtxUri)
    Encoder.instance(r => enc(r) deepMerge Json.obj("reason" -> Json.fromString(r.msg)))
  }

  implicit val organizationStatusFrom: StatusFrom[OrganizationRejection] = StatusFrom {
    case _: IncorrectRev              => Conflict
    case _: OrganizationAlreadyExists => Conflict
    case _: OrganizationNotFound      => NotFound
    case _: InvalidOrganizationFormat => BadRequest
  }
} 
Example 23
Source File: CommitsConfig.scala    From scala-steward   with Apache License 2.0 5 votes vote down vote up
package org.scalasteward.core.repoconfig

import io.circe.Codec
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto._

final case class CommitsConfig(
    message: Option[String] = None
) {
  def messageOrDefault: String =
    message.getOrElse(CommitsConfig.defaultMessage)
}

object CommitsConfig {
  val defaultMessage = "${default}"

  implicit val customConfig: Configuration =
    Configuration.default.withDefaults

  implicit val commitsConfigCodec: Codec[CommitsConfig] =
    deriveConfiguredCodec
} 
Example 24
Source File: PullRequestsConfig.scala    From scala-steward   with Apache License 2.0 5 votes vote down vote up
package org.scalasteward.core.repoconfig

import io.circe.Codec
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredCodec

final case class PullRequestsConfig(
    frequency: Option[PullRequestFrequency] = None
) {
  def frequencyOrDefault: PullRequestFrequency =
    frequency.getOrElse(PullRequestFrequency.default)
}

object PullRequestsConfig {
  implicit val customConfig: Configuration =
    Configuration.default.withDefaults

  implicit val pullRequestsConfigCodec: Codec[PullRequestsConfig] =
    deriveConfiguredCodec
} 
Example 25
Source File: RepoConfig.scala    From scala-steward   with Apache License 2.0 5 votes vote down vote up
package org.scalasteward.core.repoconfig

import io.circe.Codec
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto._

final case class RepoConfig(
    commits: CommitsConfig = CommitsConfig(),
    pullRequests: PullRequestsConfig = PullRequestsConfig(),
    updates: UpdatesConfig = UpdatesConfig(),
    updatePullRequests: Option[PullRequestUpdateStrategy] = None
) {
  def updatePullRequestsOrDefault: PullRequestUpdateStrategy =
    updatePullRequests.getOrElse(PullRequestUpdateStrategy.default)
}

object RepoConfig {
  val empty: RepoConfig = RepoConfig()

  implicit val customConfig: Configuration =
    Configuration.default.withDefaults

  implicit val repoConfigCodec: Codec[RepoConfig] =
    deriveConfiguredCodec
} 
Example 26
Source File: UpdatesConfig.scala    From scala-steward   with Apache License 2.0 5 votes vote down vote up
package org.scalasteward.core.repoconfig

import eu.timepit.refined.types.numeric.PosInt
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto._
import io.circe.refined._
import io.circe.{Decoder, Encoder}
import org.scalasteward.core.data.Update
import org.scalasteward.core.update.FilterAlg.{
  FilterResult,
  IgnoredByConfig,
  NotAllowedByConfig,
  VersionPinnedByConfig
}
import org.scalasteward.core.util.Nel

final case class UpdatesConfig(
    pin: List[UpdatePattern] = List.empty,
    allow: List[UpdatePattern] = List.empty,
    ignore: List[UpdatePattern] = List.empty,
    limit: Option[PosInt] = None,
    includeScala: Option[Boolean] = None,
    fileExtensions: List[String] = List.empty
) {
  def keep(update: Update.Single): FilterResult =
    isAllowed(update).flatMap(isPinned).flatMap(isIgnored)

  def fileExtensionsOrDefault: Set[String] =
    if (fileExtensions.isEmpty)
      UpdatesConfig.defaultFileExtensions
    else
      fileExtensions.toSet

  private def isAllowed(update: Update.Single): FilterResult = {
    val m = UpdatePattern.findMatch(allow, update, include = true)
    if (m.filteredVersions.nonEmpty)
      Right(update.copy(newerVersions = Nel.fromListUnsafe(m.filteredVersions)))
    else if (allow.isEmpty)
      Right(update)
    else Left(NotAllowedByConfig(update))
  }

  private def isPinned(update: Update.Single): FilterResult = {
    val m = UpdatePattern.findMatch(pin, update, include = true)
    if (m.filteredVersions.nonEmpty)
      Right(update.copy(newerVersions = Nel.fromListUnsafe(m.filteredVersions)))
    else if (m.byArtifactId.isEmpty)
      Right(update)
    else Left(VersionPinnedByConfig(update))
  }

  private def isIgnored(update: Update.Single): FilterResult = {
    val m = UpdatePattern.findMatch(ignore, update, include = false)
    if (m.filteredVersions.nonEmpty)
      Right(update.copy(newerVersions = Nel.fromListUnsafe(m.filteredVersions)))
    else
      Left(IgnoredByConfig(update))
  }
}

object UpdatesConfig {
  implicit val customConfig: Configuration =
    Configuration.default.withDefaults

  implicit val updatesConfigDecoder: Decoder[UpdatesConfig] =
    deriveConfiguredDecoder

  implicit val updatesConfigEncoder: Encoder[UpdatesConfig] =
    deriveConfiguredEncoder

  val defaultIncludeScala: Boolean = false

  val defaultFileExtensions: Set[String] =
    Set(".scala", ".sbt", ".sbt.shared", ".sc", ".yml", "pom.xml")

  // prevent IntelliJ from removing the import of io.circe.refined._
  locally(refinedDecoder: Decoder[PosInt])
} 
Example 27
Source File: GroupMigrations.scala    From scala-steward   with Apache License 2.0 5 votes vote down vote up
package org.scalasteward.core.update

import cats.implicits._
import io.circe.Decoder
import io.circe.config.parser
import io.circe.generic.extras.{semiauto, Configuration}
import org.scalasteward.core.application.Config
import org.scalasteward.core.data._
import org.scalasteward.core.io.FileAlg
import org.scalasteward.core.util.{MonadThrowable, Nel}

trait GroupMigrations {
  def findUpdateWithNewerGroupId(dependency: Dependency): Option[Update.Single]
}

object GroupMigrations {
  def create[F[_]: MonadThrowable](implicit
      fileAlg: FileAlg[F],
      config: Config
  ): F[GroupMigrations] = {
    val migrationSources = {

      val fromParameters: F[Option[String]] =
        config.groupMigrations.traverse(fileAlg.readFile(_)).flatMap {
          case None => none[String].pure[F]
          case Some(None) =>
            new Throwable("Couldn't read the file with custom group migrations")
              .raiseError[F, Option[String]]
          case Some(Some(text)) => text.some.pure[F]
        }

      List(
        fileAlg.readResource("group-migrations.conf").map(List(_)),
        fromParameters.map(_.toList)
      ).flatSequence
    }

    val decodeFile: String => F[GroupIdChanges] = parser
      .decode[GroupIdChanges](_)
      .leftMap(e => new Throwable("Couldn't decode migrations file", e))
      .liftTo[F]

    migrationSources
      .flatMap(_.traverse(decodeFile))
      .map(_.flatMap(_.changes))
      .map(migrations => dependency => migrateGroupId(dependency, migrations))
  }

  def migrateGroupId(
      dependency: Dependency,
      migrations: List[GroupIdChange]
  ): Option[Update.Single] =
    migrations.view
      .filter(_.before === dependency.groupId)
      .find(_.artifactId === dependency.artifactId.name)
      .map { migration =>
        Update.Single(
          CrossDependency(dependency),
          Nel.one(migration.initialVersion),
          Some(migration.after)
        )
      }

  implicit val customConfig: Configuration =
    Configuration.default.withDefaults

  final case class GroupIdChanges(changes: List[GroupIdChange])
  object GroupIdChanges {
    implicit val decoder: Decoder[GroupIdChanges] =
      semiauto.deriveConfiguredDecoder
  }

  final case class GroupIdChange(
      before: GroupId,
      after: GroupId,
      artifactId: String,
      initialVersion: String
  )

  object GroupIdChange {

    implicit val decoder: Decoder[GroupIdChange] =
      semiauto.deriveConfiguredDecoder
  }
} 
Example 28
Source File: ScalafixMigrations.scala    From scala-steward   with Apache License 2.0 5 votes vote down vote up
package org.scalasteward.core.scalafix

import io.circe.Decoder
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto._

final case class ScalafixMigrations(
    disableDefaults: Boolean = false,
    migrations: List[Migration] = List.empty
)

object ScalafixMigrations {
  implicit val configuration: Configuration =
    Configuration.default.withDefaults

  implicit val scalafixMigrationsDecoder: Decoder[ScalafixMigrations] =
    deriveConfiguredDecoder
} 
Example 29
Source File: instances.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.sourcing.projections

import java.util.UUID

import akka.persistence.query.{NoOffset, Offset, Sequence, TimeBasedUUID}
import io.circe.generic.extras.Configuration
import io.circe._

import scala.reflect.ClassTag

object instances extends AllInstances

trait AllInstances extends CirceInstances with OffsetOrderingInstances

trait CirceInstances {
  implicit private[projections] val config: Configuration = Configuration.default.withDiscriminator("type")

  implicit final val sequenceEncoder: Encoder[Sequence] = Encoder.instance { seq =>
    Json.obj("value" -> Json.fromLong(seq.value))
  }

  implicit final val sequenceDecoder: Decoder[Sequence] = Decoder.instance { cursor =>
    cursor.get[Long]("value").map(value => Sequence(value))
  }

  implicit final val timeBasedUUIDEncoder: Encoder[TimeBasedUUID] = Encoder.instance { uuid =>
    Json.obj("value" -> Encoder.encodeUUID(uuid.value))
  }

  implicit final val timeBasedUUIDDecoder: Decoder[TimeBasedUUID] = Decoder.instance { cursor =>
    cursor.get[UUID]("value").map(uuid => TimeBasedUUID(uuid))
  }

  implicit final val noOffsetEncoder: Encoder[NoOffset.type] = Encoder.instance(_ => Json.obj())

  implicit final val noOffsetDecoder: Decoder[NoOffset.type] = Decoder.instance { cursor =>
    cursor.as[JsonObject].map(_ => NoOffset)
  }

  implicit final val offsetEncoder: Encoder[Offset] = Encoder.instance {
    case o: Sequence      => encodeDiscriminated(o)
    case o: TimeBasedUUID => encodeDiscriminated(o)
    case o: NoOffset.type => encodeDiscriminated(o)
  }

  implicit final def offsetDecoder(implicit
      S: ClassTag[Sequence],
      TBU: ClassTag[TimeBasedUUID],
      NO: ClassTag[NoOffset.type]
  ): Decoder[Offset] = {
    val sequence      = S.runtimeClass.getSimpleName
    val timeBasedUUID = TBU.runtimeClass.getSimpleName
    val noOffset      = NO.runtimeClass.getSimpleName

    Decoder.instance { cursor =>
      cursor.get[String]("type").flatMap {
        case `sequence`      => cursor.as[Sequence]
        case `timeBasedUUID` => cursor.as[TimeBasedUUID]
        case `noOffset`      => cursor.as[NoOffset.type]
        //       $COVERAGE-OFF$
        case other           => Left(DecodingFailure(s"Unknown discriminator value '$other'", cursor.history))
        //       $COVERAGE-ON$
      }
    }
  }

  private def encodeDiscriminated[A: Encoder](a: A)(implicit A: ClassTag[A]) =
    Encoder[A].apply(a).deepMerge(Json.obj("type" -> Json.fromString(A.runtimeClass.getSimpleName)))
}

trait OffsetOrderingInstances {
  implicit final val offsetOrdering: Ordering[Offset] = {
    case (x: Sequence, y: Sequence)           => x compare y
    case (x: TimeBasedUUID, y: TimeBasedUUID) => x.value.timestamp() compareTo y.value.timestamp()
    case (NoOffset, _)                        => -1
    case (_, NoOffset)                        => 1
    case _                                    => 0
  }
} 
Example 30
Source File: AdminError.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.admin.exceptions

import akka.http.scaladsl.model.StatusCodes
import ch.epfl.bluebrain.nexus.commons.http.directives.StatusFrom
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.Contexts._
import ch.epfl.bluebrain.nexus.service.exceptions.ServiceError
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

import scala.annotation.nowarn


  final case object InvalidFormat extends AdminError("The json representation is incorrectly formatted.")

  @nowarn("cat=unused")
  implicit val adminErrorEncoder: Encoder[AdminError] = {
    implicit val rejectionConfig: Configuration = Configuration.default.withDiscriminator("@type")
    val enc                                     = deriveConfiguredEncoder[AdminError].mapJson(_ addContext errorCtxUri)
    Encoder.instance(r => enc(r) deepMerge Json.obj("reason" -> Json.fromString(r.msg)))
  }

  implicit val adminErrorStatusFrom: StatusFrom[AdminError] = {
    case NotFound             => StatusCodes.NotFound
    case AuthenticationFailed => StatusCodes.Unauthorized
    case AuthorizationFailed  => StatusCodes.Forbidden
    case InvalidFormat        => StatusCodes.BadRequest
    case _                    => StatusCodes.InternalServerError
  }
} 
Example 31
Source File: EventSerializer.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.admin.persistence

import akka.actor.ExtendedActorSystem
import akka.serialization.SerializerWithStringManifest
import ch.epfl.bluebrain.nexus.admin.organizations.OrganizationEvent
import ch.epfl.bluebrain.nexus.admin.projects.ProjectEvent
import ch.epfl.bluebrain.nexus.commons.serialization.AkkaCoproductSerializer
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig
import ch.epfl.bluebrain.nexus.service.config.Settings
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.{deriveConfiguredDecoder, deriveConfiguredEncoder}
import io.circe.{Decoder, Encoder}
import shapeless.{:+:, CNil}

import scala.annotation.nowarn

@nowarn("cat=unused")
class EventSerializer(system: ExtendedActorSystem) extends SerializerWithStringManifest {

  implicit private val httpConfig: HttpConfig = Settings(system).serviceConfig.http

  implicit private val config: Configuration = Configuration.default.withDiscriminator("@type")

  implicit private val projectEventDecoder: Decoder[ProjectEvent]           = deriveConfiguredDecoder[ProjectEvent]
  implicit private val projectEventEncoder: Encoder[ProjectEvent]           = deriveConfiguredEncoder[ProjectEvent]
  implicit private val organizationEventDecoder: Decoder[OrganizationEvent] = deriveConfiguredDecoder[OrganizationEvent]
  implicit private val organizationEventEncoder: Encoder[OrganizationEvent] = deriveConfiguredEncoder[OrganizationEvent]

  private val serializer = new AkkaCoproductSerializer[OrganizationEvent :+: ProjectEvent :+: CNil](1129)

  override val identifier: Int = serializer.identifier

  override def manifest(o: AnyRef): String = serializer.manifest(o)

  override def toBinary(o: AnyRef): Array[Byte] = serializer.toBinary(o)

  override def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = serializer.fromBinary(bytes, manifest)
} 
Example 32
Source File: ProjectRejection.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.admin.projects

import java.util.UUID

import akka.http.scaladsl.model.StatusCodes.{BadRequest, Conflict, NotFound}
import ch.epfl.bluebrain.nexus.commons.http.directives.StatusFrom
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.Contexts._
import ch.epfl.bluebrain.nexus.service.routes.ResourceRejection
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

import scala.annotation.nowarn

sealed abstract class ProjectRejection(val msg: String) extends ResourceRejection

object ProjectRejection {

  
  final case class IncorrectRev(expected: Long, provided: Long)
      extends ProjectRejection(
        s"Incorrect revision '$provided' provided, expected '$expected', the project may have been updated since last seen."
      )

  @nowarn("cat=unused")
  implicit val projectRejectionEncoder: Encoder[ProjectRejection] = {
    implicit val rejectionConfig: Configuration = Configuration.default.withDiscriminator("@type")
    val enc                                     = deriveConfiguredEncoder[ProjectRejection].mapJson(_ addContext errorCtxUri)
    Encoder.instance(r => enc(r) deepMerge Json.obj("reason" -> Json.fromString(r.msg)))
  }

  implicit val projectStatusFrom: StatusFrom[ProjectRejection] = StatusFrom {
    case _: IncorrectRev             => Conflict
    case _: ProjectAlreadyExists     => Conflict
    case _: ProjectNotFound          => NotFound
    case _: OrganizationNotFound     => NotFound
    case _: ProjectIsDeprecated      => BadRequest
    case _: OrganizationIsDeprecated => BadRequest
    case _: InvalidProjectFormat     => BadRequest
  }

} 
Example 33
Source File: Utils.scala    From mantis   with Apache License 2.0 5 votes vote down vote up
package io.iohk.ethereum.vm.utils

import java.io.File

import akka.util.ByteString
import io.circe.parser.decode
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.auto._
import io.circe.Error
import scala.io.Source

object Utils {

  def loadContractCodeFromFile(file: File): ByteString = {
    val src = Source.fromFile(file)
    val raw = try { src.mkString } finally { src.close() }
    ByteString(raw.trim.grouped(2).map(Integer.parseInt(_, 16).toByte).toArray)
  }

  def loadContractAbiFromFile(file: File): Either[Error, List[ABI]] = {
    val src = Source.fromFile(file)
    val raw = try { src.mkString } finally { src.close() }
    implicit val config = Configuration.default.withDefaults
    decode[List[ABI]](raw)
  }

} 
Example 34
Source File: OrganizationEvent.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.admin.organizations

import java.time.Instant
import java.util.UUID

import ch.epfl.bluebrain.nexus.iam.types.Identity.Subject
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.Contexts._
import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig
import ch.epfl.bluebrain.nexus.service.config.Vocabulary.nxv
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto._
import io.circe.syntax._
import io.circe.{Encoder, Json}

import scala.annotation.nowarn


  final case class OrganizationDeprecated(
      id: UUID,
      rev: Long,
      instant: Instant,
      subject: Subject
  ) extends OrganizationEvent

  object JsonLd {

    @nowarn("cat=unused")
    implicit private val config: Configuration = Configuration.default
      .withDiscriminator("@type")
      .copy(transformMemberNames = {
        case nxv.`@id`.name        => nxv.uuid.prefix
        case nxv.label.name        => nxv.label.prefix
        case nxv.rev.name          => nxv.rev.prefix
        case nxv.instant.name      => nxv.instant.prefix
        case nxv.eventSubject.name => nxv.eventSubject.prefix
        case other                 => other
      })

    @nowarn("cat=unused")
    implicit private def subjectIdEncoder(implicit http: HttpConfig): Encoder[Subject] =
      Encoder.encodeJson.contramap(_.id.asJson)

    @nowarn("cat=unused")
    implicit final def orgEventEncoder(implicit http: HttpConfig): Encoder[OrganizationEvent] =
      Encoder.encodeJson.contramap[OrganizationEvent] { ev =>
        deriveConfiguredEncoder[OrganizationEvent]
          .mapJson { json =>
            val rev = Json.obj(nxv.rev.prefix -> Json.fromLong(ev.rev))
            json
              .deepMerge(rev)
              .addContext(adminCtxUri)
              .addContext(resourceCtxUri)
          }
          .apply(ev)
      }
  }
} 
Example 35
Source File: PermissionsEvent.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.permissions

import java.time.Instant

import ch.epfl.bluebrain.nexus.iam.types.Identity.Subject
import ch.epfl.bluebrain.nexus.iam.types.{Identity, Permission}
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.Contexts._
import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig
import io.circe.Encoder
import io.circe.generic.extras.Configuration

import scala.annotation.nowarn


  final case class PermissionsDeleted(
      rev: Long,
      instant: Instant,
      subject: Subject
  ) extends PermissionsEvent

  object JsonLd {
    import io.circe.generic.extras.semiauto._

    @nowarn("cat=unused")
    implicit def permissionsEventEncoder(implicit http: HttpConfig): Encoder[Event] = {
      implicit val config: Configuration            = Configuration.default
        .withDiscriminator("@type")
        .copy(transformMemberNames = {
          case "rev"     => "_rev"
          case "instant" => "_instant"
          case "subject" => "_subject"
          case other     => other
        })
      implicit val subjectEncoder: Encoder[Subject] = Identity.subjectIdEncoder
      deriveConfiguredEncoder[Event]
        .mapJson { json =>
          json
            .addContext(iamCtxUri)
            .addContext(resourceCtxUri)
        }
    }
  }
} 
Example 36
Source File: AclRejection.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.acls

import akka.http.scaladsl.model.StatusCodes.{BadRequest, Conflict, NotFound}
import ch.epfl.bluebrain.nexus.commons.http.directives.StatusFrom
import ch.epfl.bluebrain.nexus.iam.types.Permission
import ch.epfl.bluebrain.nexus.rdf.Iri.Path
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.Contexts.errorCtxUri
import ch.epfl.bluebrain.nexus.service.routes.ResourceRejection
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

import scala.annotation.nowarn

sealed abstract class AclRejection(val msg: String) extends ResourceRejection

object AclRejection {

  
  final case class UnknownPermissions(permissions: Set[Permission])
      extends AclRejection(
        s"Some of the permissions specified are not known: '${permissions.mkString("\"", ", ", "\"")}'"
      )

  @nowarn("cat=unused")
  implicit val aclRejectionEncoder: Encoder[AclRejection] = {
    implicit val rejectionConfig: Configuration = Configuration.default.withDiscriminator("@type")
    val enc                                     = deriveConfiguredEncoder[AclRejection].mapJson(_ addContext errorCtxUri)
    Encoder.instance(r => enc(r) deepMerge Json.obj("reason" -> Json.fromString(r.msg)))
  }

  implicit val aclRejectionStatusFrom: StatusFrom[AclRejection] =
    StatusFrom {
      case _: NothingToBeUpdated                        => BadRequest
      case _: AclIsEmpty                                => BadRequest
      case _: AclCannotContainEmptyPermissionCollection => BadRequest
      case _: AclNotFound                               => NotFound
      case _: IncorrectRev                              => Conflict
      case _: UnknownPermissions                        => BadRequest
    }
} 
Example 37
Source File: AclEvent.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.acls

import java.time.Instant

import ch.epfl.bluebrain.nexus.iam.types.Identity
import ch.epfl.bluebrain.nexus.iam.types.Identity.Subject
import ch.epfl.bluebrain.nexus.rdf.Iri.Path
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.Contexts._
import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig
import io.circe.Encoder
import io.circe.generic.extras.Configuration

import scala.annotation.nowarn


  final case class AclDeleted(
      path: Path,
      rev: Long,
      instant: Instant,
      subject: Subject
  ) extends AclEvent

  object JsonLd {
    import io.circe.generic.extras.semiauto._

    @nowarn("cat=unused")
    implicit def aclEventEncoder(implicit httpConfig: HttpConfig): Encoder[AclEvent] = {
      implicit val config: Configuration                    = Configuration.default
        .withDiscriminator("@type")
        .copy(transformMemberNames = {
          case "rev"     => "_rev"
          case "instant" => "_instant"
          case "subject" => "_subject"
          case "path"    => "_path"
          case other     => other
        })
      implicit val arrayEncoder: Encoder[AccessControlList] = AccessControlList.aclArrayEncoder
      implicit val subjectEncoder: Encoder[Subject]         = Identity.subjectIdEncoder
      deriveConfiguredEncoder[AclEvent]
        .mapJson { json =>
          json
            .addContext(iamCtxUri)
            .addContext(resourceCtxUri)
        }
    }
  }
} 
Example 38
Source File: ActiveRealm.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.realms

import ch.epfl.bluebrain.nexus.iam.types.GrantType.Camel._
import ch.epfl.bluebrain.nexus.iam.types.{GrantType, Label}
import ch.epfl.bluebrain.nexus.rdf.Iri.Url
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.Vocabulary.nxv
import com.nimbusds.jose.jwk.{JWK, JWKSet}
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

import scala.util.Try


final case class ActiveRealm(
    id: Label,
    name: String,
    openIdConfig: Url,
    issuer: String,
    grantTypes: Set[GrantType],
    logo: Option[Url],
    authorizationEndpoint: Url,
    tokenEndpoint: Url,
    userInfoEndpoint: Url,
    revocationEndpoint: Option[Url],
    endSessionEndpoint: Option[Url],
    keys: Set[Json]
) {

  private[realms] lazy val keySet: JWKSet = {
    val jwks = keys.foldLeft(Set.empty[JWK]) {
      case (acc, e) => Try(JWK.parse(e.noSpaces)).map(acc + _).getOrElse(acc)
    }
    import scala.jdk.CollectionConverters._
    new JWKSet(jwks.toList.asJava)
  }
}

object ActiveRealm {
  implicit private[ActiveRealm] val config: Configuration = Configuration.default.copy(transformMemberNames = {
    case "issuer"                => nxv.issuer.prefix
    case "grantTypes"            => nxv.grantTypes.prefix
    case "authorizationEndpoint" => nxv.authorizationEndpoint.prefix
    case "tokenEndpoint"         => nxv.tokenEndpoint.prefix
    case "userInfoEndpoint"      => nxv.userInfoEndpoint.prefix
    case "revocationEndpoint"    => nxv.revocationEndpoint.prefix
    case "endSessionEndpoint"    => nxv.endSessionEndpoint.prefix
    case other                   => other
  })
  implicit val activeEncoder: Encoder[ActiveRealm] = {
    val default = deriveConfiguredEncoder[ActiveRealm]
    Encoder
      .instance[ActiveRealm] { realm =>
        default(realm) deepMerge Json.obj(
          nxv.label.prefix      -> Json.fromString(realm.id.value),
          nxv.deprecated.prefix -> Json.fromBoolean(false)
        )
      }
      .mapJson(_.removeKeys("keys", "id"))
  }
} 
Example 39
Source File: TokenRejection.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.auth

import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

import scala.annotation.nowarn


  final case object InvalidAccessToken
      extends TokenRejection(
        "The token is invalid; possible causes are: incorrect signature, the token is expired or the 'nbf' value was not met."
      )

  @nowarn("cat=unused")
  implicit val tokenRejectionEncoder: Encoder[TokenRejection] = {
    implicit val rejectionConfig: Configuration = Configuration.default.withDiscriminator("@type")
    val enc                                     = deriveConfiguredEncoder[TokenRejection]
    Encoder.instance(r => enc(r) deepMerge Json.obj("reason" -> Json.fromString(r.msg)))
  }
} 
Example 40
Source File: EventSerializer.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.io

import java.nio.charset.Charset

import akka.actor.ExtendedActorSystem
import akka.serialization.SerializerWithStringManifest
import ch.epfl.bluebrain.nexus.iam.acls.AclEvent
import ch.epfl.bluebrain.nexus.iam.permissions.PermissionsEvent
import ch.epfl.bluebrain.nexus.iam.realms.RealmEvent
import ch.epfl.bluebrain.nexus.iam.types.GrantType.Camel._
import ch.epfl.bluebrain.nexus.rdf.Iri.Url
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig
import ch.epfl.bluebrain.nexus.service.config.Settings
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto._
import io.circe.parser._
import io.circe.syntax._
import io.circe.{Decoder, Encoder, Printer}


class EventSerializer(system: ExtendedActorSystem) extends SerializerWithStringManifest {
  private val utf8 = Charset.forName("UTF-8")

  private val printer = Printer.noSpaces.copy(dropNullValues = true)

  implicit private[io] val http: HttpConfig = Settings(system).serviceConfig.http

  implicit private[io] val config: Configuration = Configuration.default.withDiscriminator("@type")

  implicit private[io] val urlEncoder: Encoder[Url] =
    Encoder.encodeString.contramap(_.asUri)
  implicit private[io] val urlDecoder: Decoder[Url] =
    Decoder.decodeString.emap(Url.apply)

  implicit private[io] val permissionEventEncoder: Encoder[PermissionsEvent] = deriveConfiguredEncoder[PermissionsEvent]
  implicit private[io] val permissionEventDecoder: Decoder[PermissionsEvent] = deriveConfiguredDecoder[PermissionsEvent]
  implicit private[io] val aclEventEncoder: Encoder[AclEvent]                = deriveConfiguredEncoder[AclEvent]
  implicit private[io] val aclEventDecoder: Decoder[AclEvent]                = deriveConfiguredDecoder[AclEvent]
  implicit private[io] val realmEventEncoder: Encoder[RealmEvent]            = deriveConfiguredEncoder[RealmEvent]
  implicit private[io] val realmEventDecoder: Decoder[RealmEvent]            = deriveConfiguredDecoder[RealmEvent]

  override val identifier: Int = 1225

  override def manifest(o: AnyRef): String                              =
    o match {
      case _: PermissionsEvent => "permissions-event"
      case _: AclEvent         => "acl-event"
      case _: RealmEvent       => "realm-event"
      case other               =>
        throw new IllegalArgumentException(
          s"Cannot determine manifest for unknown type: '${other.getClass.getCanonicalName}'"
        )
    }
  override def toBinary(o: AnyRef): Array[Byte]                         =
    o match {
      case ev: PermissionsEvent => ev.asJson.printWith(printer).getBytes(utf8)
      case ev: AclEvent         => ev.asJson.printWith(printer).getBytes(utf8)
      case ev: RealmEvent       => ev.asJson.printWith(printer).getBytes(utf8)
      case other                =>
        throw new IllegalArgumentException(s"Cannot serialize unknown type: '${other.getClass.getCanonicalName}'")
    }
  override def fromBinary(bytes: Array[Byte], manifest: String): AnyRef =
    manifest match {
      case "permissions-event" =>
        val str = new String(bytes, utf8)
        decode[PermissionsEvent](str)
          .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'PermissionsEvent'"))
      case "acl-event"         =>
        val str = new String(bytes, utf8)
        decode[AclEvent](str)
          .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'AclEvent'"))
      case "realm-event"       =>
        val str = new String(bytes, utf8)
        decode[RealmEvent](str)
          .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'RealmEvent'"))
      case other               =>
        throw new IllegalArgumentException(s"Cannot deserialize type with unknown manifest: '$other'")
    }
} 
Example 41
Source File: ServiceError.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.service.exceptions

import ch.epfl.bluebrain.nexus.admin.exceptions.AdminError
import ch.epfl.bluebrain.nexus.iam.types.IamError
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.service.config.Contexts._
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

import scala.annotation.nowarn

@SuppressWarnings(Array("IncorrectlyNamedExceptions"))
abstract class ServiceError(val msg: String) extends Exception with Product with Serializable

object ServiceError {

  
  @SuppressWarnings(Array("IncorrectlyNamedExceptions"))
  final case class InternalError(reason: String) extends ServiceError(reason)

  @nowarn("cat=unused")
  implicit val internalErrorEncoder: Encoder[InternalError] = {
    implicit val rejectionConfig: Configuration = Configuration.default.withDiscriminator("@type")
    val enc                                     = deriveConfiguredEncoder[InternalError].mapJson(_ addContext errorCtxUri)
    Encoder.instance(r => {
      enc(r) deepMerge Json
        .obj("@type" -> Json.fromString(r.getClass.getSimpleName), "reason" -> Json.fromString(r.msg))
    })
  }

  implicit val serviceErrorEncoder: Encoder[ServiceError] = Encoder.instance {
    case i: IamError   => IamError.iamErrorEncoder(i)
    case a: AdminError => AdminError.adminErrorEncoder(a)
    case r             =>
      Json.obj(
        "@type"  -> Json.fromString(r.getClass.getSimpleName),
        "reason" -> Json.fromString(r.msg)
      ) addContext errorCtxUri
  }
} 
Example 42
Source File: StorageError.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.storage

import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.model.Uri.Path
import ch.epfl.bluebrain.nexus.storage.routes.StatusFrom
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveConfiguredEncoder
import io.circe.{Encoder, Json}

import scala.annotation.nowarn


  final case class OperationTimedOut(override val msg: String) extends StorageError(msg)

  @nowarn("cat=unused")
  implicit private val config: Configuration = Configuration.default.withDiscriminator("@type")

  private val derivedEncoder = deriveConfiguredEncoder[StorageError].mapJson(jsonError)

  implicit val storageErrorEncoder: Encoder[StorageError]       =
    Encoder.instance(r => derivedEncoder(r) deepMerge Json.obj("reason" -> Json.fromString(r.msg)))

  implicit val storageErrorStatusFrom: StatusFrom[StorageError] = {
    case _: PathNotFound      => StatusCodes.NotFound
    case _: PathInvalid       => StatusCodes.BadRequest
    case AuthenticationFailed => StatusCodes.Unauthorized
    case AuthorizationFailed  => StatusCodes.Forbidden
    case _                    => StatusCodes.InternalServerError
  }
}