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

com.fireflysource.net.http.server.impl.router.AsyncRouterManager.kt Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
package com.fireflysource.net.http.server.impl.router

import com.fireflysource.net.http.common.codec.URIUtils.canonicalPath
import com.fireflysource.net.http.common.model.HttpHeader
import com.fireflysource.net.http.server.*
import com.fireflysource.net.http.server.impl.matcher.*
import java.util.*
import java.util.concurrent.atomic.AtomicInteger

class AsyncRouterManager(val httpServer: HttpServer) : RouterManager {

    private val routerId = AtomicInteger()

    private val httpMethodMatcher: HttpMethodMatcher = HttpMethodMatcher()
    private val precisePathMatcher: PrecisePathMatcher = PrecisePathMatcher()
    private val parameterPathMatcher: ParameterPathMatcher = ParameterPathMatcher()
    private val patternedPathMatcher: PatternedPathMatcher = PatternedPathMatcher()
    private val regexPathMatcher: RegexPathMatcher = RegexPathMatcher()
    private val preciseContentTypeMatcher: PreciseContentTypeMatcher = PreciseContentTypeMatcher()
    private val patternedContentTypeMatcher: PatternedContentTypeMatcher = PatternedContentTypeMatcher()
    private val acceptHeaderMatcher: AcceptHeaderMatcher = AcceptHeaderMatcher()

    override fun register(): Router = this.register(routerId.getAndIncrement())

    override fun register(id: Int): Router =
        AsyncRouter(id, this)

    override fun findRouters(ctx: RoutingContext): SortedSet {
        val routerMatchTypeMap = TreeMap>()
        val routerParameterMap = TreeMap>()

        val methodResult = httpMethodMatcher.match(ctx.method)
        collectRouterResult(methodResult, routerMatchTypeMap, routerParameterMap)

        val path = canonicalPath(ctx.uri.decodedPath)
        val precisePathResult = precisePathMatcher.match(path)
        collectRouterResult(precisePathResult, routerMatchTypeMap, routerParameterMap)

        val parameterPathResult = parameterPathMatcher.match(path)
        collectRouterResult(parameterPathResult, routerMatchTypeMap, routerParameterMap)

        val patternedPathResult = patternedPathMatcher.match(path)
        collectRouterResult(patternedPathResult, routerMatchTypeMap, routerParameterMap)

        val regexPathResult = regexPathMatcher.match(path)
        collectRouterResult(regexPathResult, routerMatchTypeMap, routerParameterMap)

        val contentType = ctx.contentType ?: ""
        val preciseContentTypeResult = preciseContentTypeMatcher.match(contentType)
        collectRouterResult(preciseContentTypeResult, routerMatchTypeMap, routerParameterMap)

        val patternedContentTypeResult = patternedContentTypeMatcher.match(contentType)
        collectRouterResult(patternedContentTypeResult, routerMatchTypeMap, routerParameterMap)

        val accept = ctx.httpFields[HttpHeader.ACCEPT] ?: ""
        val acceptHeaderResult = acceptHeaderMatcher.match(accept)
        collectRouterResult(acceptHeaderResult, routerMatchTypeMap, routerParameterMap)

        return routerMatchTypeMap
            .filter { it.key.isEnable }
            .filter { it.key.matchTypes == it.value }
            .map { RouterManager.RouterMatchResult(it.key, routerParameterMap[it.key] ?: emptyMap(), it.value) }
            .toSortedSet()
    }

    private fun collectRouterResult(
        result: Matcher.MatchResult?,
        routerMatchTypeMap: SortedMap>,
        routerParameterMap: SortedMap>
    ) {
        result?.routers?.forEach {
            routerMatchTypeMap.computeIfAbsent(it) { HashSet() }.add(result.matchType)
            val params = result.parameters[it]
            if (!params.isNullOrEmpty()) {
                routerParameterMap.computeIfAbsent(it) { HashMap() }.putAll(params)
            }
        }
    }

    fun method(httpMethod: String, router: AsyncRouter) {
        httpMethodMatcher.add(httpMethod, router)
    }

    fun path(url: String, router: AsyncRouter) {
        when {
            url == "/" -> precisePathMatcher.add(url, router)
            url.contains("*") -> patternedPathMatcher.add(url, router)
            ParameterPathMatcher.isParameterPath(url) -> parameterPathMatcher.add(url, router)
            else -> precisePathMatcher.add(url, router)
        }
    }

    fun paths(urlList: MutableList, router: AsyncRouter) {
        urlList.forEach { path(it, router) }
    }

    fun pathRegex(regex: String, router: AsyncRouter) {
        regexPathMatcher.add(regex, router)
    }

    fun consumes(contentType: String, router: AsyncRouter) {
        if (contentType.contains("*")) patternedContentTypeMatcher.add(contentType, router)
        else preciseContentTypeMatcher.add(contentType, router)
    }

    fun produces(accept: String, router: AsyncRouter) {
        acceptHeaderMatcher.add(accept, router)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy