HttpPredicate.kt

  1. package com.hexagontk.http.handlers

  2. import com.hexagontk.handlers.Context
  3. import com.hexagontk.http.patterns.LiteralPathPattern
  4. import com.hexagontk.http.model.HttpMethod
  5. import com.hexagontk.http.patterns.PathPattern
  6. import com.hexagontk.http.patterns.createPathPattern
  7. import com.hexagontk.http.model.HttpCall

  8. class HttpPredicate(
  9.     val methods: Set<HttpMethod> = emptySet(),
  10.     val pathPattern: PathPattern = LiteralPathPattern(),
  11.     val status: Int? = null,
  12. ) : (Context<HttpCall>) -> Boolean {

  13.     private fun PathPattern.isEmpty(): Boolean =
  14.         pattern.isEmpty()

  15.     val predicate: (Context<HttpCall>) -> Boolean =
  16.         if (methods.isEmpty()) ::filterWithoutMethod else ::filterWithMethod

  17.     constructor(
  18.         methods: Set<HttpMethod> = emptySet(),
  19.         pattern: String = "",
  20.         status: Int? = null,
  21.         prefix: Boolean = false,
  22.     ) :
  23.         this(methods, createPathPattern(pattern, prefix), status)

  24.     override fun invoke(context: Context<HttpCall>): Boolean =
  25.         predicate(context)

  26.     fun clearMethods(): HttpPredicate =
  27.         HttpPredicate(emptySet(), pathPattern, status)

  28.     private fun filterMethod(context: Context<HttpCall>): Boolean =
  29.         context.event.request.method in methods

  30.     private fun filterPattern(context: Context<HttpCall>): Boolean =
  31.         if (pathPattern.isEmpty() && context.event.request.path == "/") true
  32.         else pathPattern.matches(context.event.request.path)

  33.     private fun filterStatus(context: Context<HttpCall>): Boolean =
  34.         status == context.event.response.status

  35.     private fun filterWithoutMethod(context: Context<HttpCall>): Boolean =
  36.         filterPattern(context)
  37.             && (status == null || filterStatus(context))

  38.     private fun filterWithMethod(context: Context<HttpCall>): Boolean =
  39.         filterMethod(context) && filterWithoutMethod(context)

  40.     fun addPrefix(prefix: String): HttpPredicate =
  41.         HttpPredicate(methods, pathPattern.addPrefix(prefix), status)

  42.     fun describe(): String =
  43.         methods
  44.             .map { it.name }
  45.             .ifEmpty { listOf("ANY") }
  46.             .joinToString(
  47.                 separator = ", ",
  48.                 postfix = pathPattern.describe().prependIndent(" "),
  49.                 transform = { it }
  50.             )
  51. }