Create base UriTemplate
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
package com.bartlomiejpluta.ttsserver.core.web.exception
|
||||
|
||||
class UriTemplateException(message: String, val position: Int) : Exception(message)
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.bartlomiejpluta.ttsserver.core.web.uri
|
||||
|
||||
import com.bartlomiejpluta.ttsserver.core.web.exception.UriTemplateException
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class UriTemplate private constructor(uri: String) {
|
||||
private val variables = mutableListOf<String>()
|
||||
private var pattern: Pattern
|
||||
|
||||
init {
|
||||
val patternBuilder = StringBuilder()
|
||||
var variableBuilder: StringBuilder? = null
|
||||
var isVariable = false
|
||||
|
||||
uri.forEachIndexed { index, char ->
|
||||
when {
|
||||
char == '{' -> {
|
||||
if (isVariable) {
|
||||
error("Templates cannot be nested", index + 1)
|
||||
}
|
||||
isVariable = true
|
||||
variableBuilder = StringBuilder()
|
||||
patternBuilder.append("(\\w+)")
|
||||
}
|
||||
|
||||
char == '}' -> {
|
||||
isVariable = false
|
||||
variables.add(variableBuilder.toString())
|
||||
}
|
||||
|
||||
isVariable -> char.takeIf { it.isLetter() } ?: error(
|
||||
"Only letters are allowed as template",
|
||||
index + 1
|
||||
).let { variableBuilder?.append(it) }
|
||||
|
||||
else -> patternBuilder.append(char)
|
||||
}
|
||||
}
|
||||
|
||||
if (isVariable) {
|
||||
error("Unclosed template found", patternBuilder.length)
|
||||
}
|
||||
|
||||
pattern = Pattern.compile("^${patternBuilder.toString()}\$")
|
||||
}
|
||||
|
||||
private fun error(message: String, position: Int): Unit =
|
||||
throw UriTemplateException(message, position)
|
||||
|
||||
|
||||
fun match(url: String): MatchingResult {
|
||||
val matcher = pattern.matcher(url)
|
||||
|
||||
if (matcher.find()) {
|
||||
val matchedVariables = IntRange(0, matcher.groupCount() - 1)
|
||||
.map { variables[it] to matcher.group(it + 1)!! }
|
||||
.toMap()
|
||||
|
||||
return MatchingResult(true, matchedVariables)
|
||||
}
|
||||
|
||||
return MatchingResult(false)
|
||||
}
|
||||
|
||||
data class MatchingResult(val matched: Boolean, val variables: Map<String, String> = emptyMap())
|
||||
|
||||
companion object {
|
||||
fun parse(uriTemplate: String): UriTemplate {
|
||||
return UriTemplate(uriTemplate)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user