RegexPathPattern.kt
- package com.hexagonkt.http.patterns
- import com.hexagonkt.core.text.filter
- import com.hexagonkt.http.patterns.TemplatePathPattern.Companion.VARIABLE_PATTERN
- import com.hexagonkt.http.patterns.TemplatePathPattern.Companion.patternToRegex
- data class RegexPathPattern(val regex: Regex) : PathPattern {
- override val pattern: String = regex.pattern
- override val prefix: Boolean = !regex.pattern.endsWith("$")
- internal companion object {
- const val PARAMETER_PREFIX = "(?<"
- const val PARAMETER_SUFFIX = ">$VARIABLE_PATTERN?)"
- val PARAMETER_REGEX = Regex("""\(\?<\w+>""")
- }
- init {
- checkPathPatternPrefix(pattern, listOf("(.*?)", "$"))
- }
- val parameters: List<String> =
- PARAMETER_REGEX.findAll(pattern)
- .map { it.value.removePrefix("(?<").removeSuffix(">") }
- .toList()
- override fun addPrefix(prefix: String?): PathPattern =
- if (prefix == null) this
- else copy(regex = Regex(patternToRegex(prefix, true) + pattern))
- override fun matches(requestUrl: String): Boolean =
- if (prefix) regex.matchesAt(requestUrl, 0)
- else regex.matches(requestUrl)
- override fun extractParameters(requestUrl: String): Map<String, String> {
- val result = regex.matchEntire(requestUrl)
- require(result != null) { "URL '$requestUrl' does not match path" }
- val allValues = result.groupValues
- .drop(1)
- .mapIndexed { ii, v -> ii.toString() to v }
- .toMap()
- val resultGroups = result.groups as MatchNamedGroupCollection
- return if (parameters.isEmpty()) allValues
- else parameters.associateWith { resultGroups[it]?.value ?: "" } + allValues
- }
- override fun insertParameters(parameters: Map<String, Any>): String {
- val keys = parameters.keys
- val patternParameters = this.parameters
- require(keys.toSet() == patternParameters.toSet()) {
- "Parameters must match pattern's parameters($patternParameters). Provided: $keys"
- }
- return pattern.filter(PARAMETER_PREFIX, PARAMETER_SUFFIX, parameters)
- }
- }