Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type-safe session-data #98

Open
stangls opened this issue Nov 7, 2016 · 1 comment
Open

Type-safe session-data #98

stangls opened this issue Nov 7, 2016 · 1 comment

Comments

@stangls
Copy link
Contributor

stangls commented Nov 7, 2016

Currently, session-data is stored as type "Any?".
It would be great to have session-data stored in a type-safe way.

At the moment, I have implemented these extension functions to satisfy my requirement:

/**
 * Enables session support for storing arbitrarily typed data.
 * @param initGenerator specifies how session-data is initialized
 * @return An object to retrieve the data in a type-safe way.
 */
fun <T> AppServer.enableTypesafeSessionSupport( initGenerator: (Request) -> T ) : SessionFetcher<T> {
    enableSessionSupport()
    return SessionFetcher<T>(initGenerator)
}
/**
 * Enables session support for storing arbitrarily typed data.
 * @return An object to retrieve the data in a type-safe way.
 */
fun <T> AppServer.enableTypesafeSessionSupport() : SessionFetcher<T?> {
    return enableTypesafeSessionSupport({null})
}

class SessionFetcher<T> internal constructor(val initGenerator: (Request) -> T ) {

    protected val values = ConcurrentHashMap<String,T>()

    operator fun get(request:Request) : T {
        // session must to be there, because session-fetcher is internally created only
        val key = request.session!!.id
        return values.getOrPut( key, { initGenerator(request) } )
    }

}

This can then for example be used like this:

data class SessionData (
    var userId : Int? = null
    // here you may put further stuff to be type-safely stored,
    // for example persisted data of a database or even write functions for retrieving them
)

// easy-access extension-function
val Request.tSession: SessionData
    get() = MyApp.sessionDataFetcher[this]

// application example
object MyApp {
    val sessionDataFetcher: SessionFetcher<SessionData>
    private val server : AppServer
    init {
        server = AppServer()
        sessionDataFetcher = server.enableTypesafeSessionSupport { SessionData() }
        server.get("/", {
            response.send("Your user id is ${request.tSession.userId.toString()}")
        })
        server.get("/set", {
            request.tSession.userId = Random().nextInt()
            response.send("Your user id has been randomly set.")
        })
        server.addStyleSheet(MainCss(),true)
    }
    @JvmStatic fun main(args: Array<String>) {
        server.start()
    }
}
@stangls
Copy link
Contributor Author

stangls commented Nov 8, 2016

It would be great to have this or some other kind of type-safety for session-data introduced into the SessionManagementInterceptor, because when you use the code this way, we create multiple concurrent hash maps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant