Skip to content

Commit

Permalink
Update to Kotlin 1.1.4-2 and clean up/reformat code
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasMega committed Aug 19, 2017
1 parent 2304f7a commit 8e697cb
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 140 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pom.xml - The Apache POM file that builds and packages the sample

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.version>0.12.1218</kotlin.version>
<kotlin.version>1.1.4-2</kotlin.version>
</properties>

<build>
Expand Down
25 changes: 9 additions & 16 deletions src/main/kotlin/com/nordicapis/kotlin_spark_sample/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,23 @@ import org.picocontainer.DefaultPicoContainer
import org.picocontainer.MutablePicoContainer
import spark.servlet.SparkApplication
import kotlin.reflect.KClass
import kotlin.reflect.jvm.java

public class Application(
class Application(
var composer: Composable = Noncomposer(),
var appContainer: MutablePicoContainer = DefaultPicoContainer(),
var routes: () -> List<Application.RouteData<Controllable>>) : SparkApplication
{
private var appContainer: MutablePicoContainer = DefaultPicoContainer(),
var routes: () -> List<Application.RouteData<Controllable>>) : SparkApplication {
private var router = Router()

init
{
init {
composer.composeApplication(appContainer)
}

override fun init() { }
override fun init() {}

fun host()
{
fun host() {
var routes = routes.invoke()

for (routeData in routes)
{
for (routeData in routes) {
val (path, controllerClass, template) = routeData

router.routeTo(path, appContainer, controllerClass, composer, template)
Expand All @@ -52,13 +47,11 @@ public class Application(
data class RouteData<out T : Controllable>(val path: String, val controllerClass: Class<out T>, val template: String? = null)
}

fun api(composer: Composable, routes: () -> List<Application.RouteData<Controllable>>)
{
fun api(composer: Composable, routes: () -> List<Application.RouteData<Controllable>>) {
Application(composer = composer, routes = routes).host()
}

fun <T : Controllable> path(path: String, to: KClass<T>, renderWith: String? = null) : Application.RouteData<T>
{
fun <T : Controllable> path(path: String, to: KClass<T>, renderWith: String? = null): Application.RouteData<T> {
return Application.RouteData(path, to.java, renderWith)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ AuthorizeController.kt - The controller class that provides the logic for the au

package com.nordicapis.kotlin_spark_sample

import org.slf4j.Logger
import org.slf4j.LoggerFactory
import spark.Request
import spark.Response
import kotlin.reflect.jvm.java

public class AuthorizeController : Controllable()
{
private val _logger = LoggerFactory.getLogger(javaClass<AuthorizeController>())
class AuthorizeController : Controllable() {

public override fun before(request: Request, response: Response): Boolean
{
companion object {
val _logger: Logger = LoggerFactory.getLogger(AuthorizeController::class.java)
}

override fun before(request: Request, response: Response): Boolean {
_logger.trace("before on Authorize controller invoked")

if (request.session(false) == null)
{
if (request.session(false) == null) {
_logger.debug("No session exists. Redirecting to login")

response.redirect("/login")
Expand All @@ -45,7 +45,7 @@ public class AuthorizeController : Controllable()
return true
}

public override fun get(request: Request, response: Response): ControllerResult = ControllerResult(model = mapOf(
override fun get(request: Request, response: Response): ControllerResult = ControllerResult(model = mapOf(
"user" to request.session(false).attribute("username"),
"data" to mapOf(
"e1" to "e1 value",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ package com.nordicapis.kotlin_spark_sample

import org.picocontainer.MutablePicoContainer

interface Composable
{
fun composeApplication(appContainer: MutablePicoContainer) { }
interface Composable {
fun composeApplication(appContainer: MutablePicoContainer) {}

fun composeRequest(container: MutablePicoContainer) { }
fun composeRequest(container: MutablePicoContainer) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,16 @@ ContainerComposer.kt - The composer that wires up the dependencies of this appli

package com.nordicapis.kotlin_spark_sample

import org.picocontainer.DefaultPicoContainer
import org.picocontainer.MutablePicoContainer
import kotlin.reflect.jvm.java

class ContainerComposer : Composable
{
public override fun composeApplication(appContainer: MutablePicoContainer)
{
appContainer.addComponent(javaClass<AuthorizeController>())
appContainer.addComponent(javaClass<TokenController>())
appContainer.addComponent(javaClass<LoginController>())

class ContainerComposer : Composable {

override fun composeApplication(appContainer: MutablePicoContainer) {
appContainer.addComponent(AuthorizeController::class.java)
appContainer.addComponent(TokenController::class.java)
appContainer.addComponent(LoginController::class.java)
}

public override fun composeRequest(container: MutablePicoContainer)
{
override fun composeRequest(container: MutablePicoContainer) {
}
}
27 changes: 13 additions & 14 deletions src/main/kotlin/com/nordicapis/kotlin_spark_sample/Controllable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,27 @@ package com.nordicapis.kotlin_spark_sample
import spark.Request
import spark.Response

SuppressWarnings("unused")
abstract class Controllable
{
public open fun before(request: Request, response: Response): Boolean = true
@SuppressWarnings("unused")
abstract class Controllable {
open fun before(request: Request, response: Response): Boolean = true

public open fun get(request: Request, response: Response): ControllerResult = ControllerResult()
open fun get(request: Request, response: Response): ControllerResult = ControllerResult()

public open fun post(request: Request, response: Response): ControllerResult = ControllerResult()
open fun post(request: Request, response: Response): ControllerResult = ControllerResult()

public open fun put(request: Request, response: Response): ControllerResult = ControllerResult()
open fun put(request: Request, response: Response): ControllerResult = ControllerResult()

public open fun delete(request: Request, response: Response): ControllerResult = ControllerResult()
open fun delete(request: Request, response: Response): ControllerResult = ControllerResult()

public open fun patch(request: Request, response: Response): ControllerResult = ControllerResult()
open fun patch(request: Request, response: Response): ControllerResult = ControllerResult()

public open fun head(request: Request, response: Response): ControllerResult = ControllerResult()
open fun head(request: Request, response: Response): ControllerResult = ControllerResult()

public open fun trace(request: Request, response: Response): ControllerResult = ControllerResult()
open fun trace(request: Request, response: Response): ControllerResult = ControllerResult()

public open fun connect(request: Request, response: Response): ControllerResult = ControllerResult()
open fun connect(request: Request, response: Response): ControllerResult = ControllerResult()

public open fun options(request: Request): ControllerResult = ControllerResult()
open fun options(request: Request): ControllerResult = ControllerResult()

public open fun after(request: Request, response: Response) { }
open fun after(request: Request, response: Response) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ ControllerResult.kt - Simple data class that contains the information about a ro

package com.nordicapis.kotlin_spark_sample

import java.util.*

data class ControllerResult(
val continueProcessing: Boolean = true,
val model: Map<String, Any> = emptyMap())
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@ package com.nordicapis.kotlin_spark_sample
import spark.Request
import spark.Response

public class LoginController : Controllable()
{
class LoginController : Controllable() {
// If this isn't overidden, even with this trivial response, it won't be routed. So, this is the minimum
// implementation to get the page to show up. Usually, a model will be created and returned in addition to the
// default response (which, because continueProcessing is true, will cause the router to continue processing).
public override fun get(request: Request, response: Response): ControllerResult = ControllerResult()
override fun get(request: Request, response: Response): ControllerResult = ControllerResult()

public override fun post(request: Request, response: Response): ControllerResult
{
override fun post(request: Request, response: Response): ControllerResult {
var session = request.session() // Create session

// Save the username in the session, so that it can be used in the authorize endpoint (e.g., for consent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ Noncomposer.kt - A trivial no-op composer for cases where DI isn't needed or des
package com.nordicapis.kotlin_spark_sample

// For when DI isn't used
class Noncomposer() : Composable
class Noncomposer : Composable
120 changes: 51 additions & 69 deletions src/main/kotlin/com/nordicapis/kotlin_spark_sample/Router.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,28 @@ import spark.*
import spark.Spark.halt
import spark.template.velocity.VelocityTemplateEngine
import java.util.*
import kotlin.reflect.jvm.java

class Router constructor() : SparkBase()
{
public fun <T : Controllable> routeTo(path: String, container: PicoContainer, controllerClass: Class<T>,
composer: Composable, template: String? = null)
{
for (classMethod in controllerClass.getDeclaredMethods())
{
val methodName = classMethod.getName()

if (methodName == "before" || methodName == "after")
{

class Router : SparkBase() {
fun <T : Controllable> routeTo(path: String, container: PicoContainer, controllerClass: Class<T>,
composer: Composable, template: String? = null) {
for (classMethod in controllerClass.declaredMethods) {
val methodName = classMethod.name

if (methodName == "before" || methodName == "after") {
continue // We don't want to route after or before using Spark, so skip these.
}

// See if the controller class' method is overriding one of Controllable's
for (interfaceMethod in javaClass<Controllable>().getMethods())
{
if (methodName == interfaceMethod.getName() && // method names match?
classMethod.getReturnType() == interfaceMethod.getReturnType() && // method return the same type?
Arrays.deepEquals(classMethod.getParameterTypes(), interfaceMethod.getParameterTypes())) // Params match?
for (interfaceMethod in Controllable::class.java.methods) {
if (methodName == interfaceMethod.name && // method names match?
classMethod.returnType == interfaceMethod.returnType && // method return the same type?
Arrays.deepEquals(classMethod.parameterTypes, interfaceMethod.parameterTypes)) // Params match?
{
if (template == null || template.isBlank())
{
addRoute(methodName, path, container, controllerClass, composer)
}
else
{
addTemplatizedRoute(methodName, template, path, container, controllerClass, composer)
when {
template == null || template.isBlank() ->
addRoute(methodName, path, container, controllerClass, composer)
else ->
addTemplatizedRoute(methodName, template, path, container, controllerClass, composer)
}

break
Expand All @@ -61,24 +53,20 @@ class Router constructor() : SparkBase()
}
}

private fun <T: Controllable> addTemplatizedRoute(httpMethod: String, template: String, path: String,
container: PicoContainer, controllerClass: Class<T>, composer: Composable)
{
val r = fun (request: Request, response: Response): ModelAndView
{
var model = router(request, response, container, controllerClass, composer)
private fun <T : Controllable> addTemplatizedRoute(httpMethod: String, template: String, path: String,
container: PicoContainer, controllerClass: Class<T>, composer: Composable) {
val r = fun(request: Request, response: Response): ModelAndView {
val model = router(request, response, container, controllerClass, composer)

return ModelAndView(model, template)
}

SparkBase.addRoute(httpMethod, TemplateViewRouteImpl.create(path, r, VelocityTemplateEngine()))
}

private fun <T: Controllable> addRoute(httpMethod: String, path: String, container: PicoContainer,
controllerClass: Class<T>, composer: Composable)
{
val r = fun (request: Request, response: Response): Any
{
private fun <T : Controllable> addRoute(httpMethod: String, path: String, container: PicoContainer,
controllerClass: Class<T>, composer: Composable) {
val r = fun(request: Request, response: Response): Any {
router(request, response, container, controllerClass, composer)

return response.body()
Expand All @@ -87,38 +75,32 @@ class Router constructor() : SparkBase()
SparkBase.addRoute(httpMethod, SparkBase.wrap(path, r))
}

private fun <T: Controllable> router(request: Request, response: Response, container: PicoContainer,
controllerClass: Class<T>, composer: Composable) : Map<String, Any>
{
val requestContainer = DefaultPicoContainer(container)
var model : Map<String, Any> = emptyMap()

composer.composeRequest(requestContainer)

try
{
val controller = requestContainer.getComponent(controllerClass)

if (controller.before(request, response))
{
// Fire the controller's method depending on the HTTP method of the request
val httpMethod = request.requestMethod().toLowerCase()
val method = controllerClass.getMethod(httpMethod, javaClass<Request>(), javaClass<Response>())
val result = method.invoke(controller, request, response)

if (result is ControllerResult && result.continueProcessing)
{
controller.after(request, response)

model = result.model
}
}
}
catch (e: Exception)
{
halt(500, "Server Error")
}

return model
private fun <T : Controllable> router(request: Request, response: Response, container: PicoContainer,
controllerClass: Class<T>, composer: Composable): Map<String, Any> {
val requestContainer = DefaultPicoContainer(container)
var model: Map<String, Any> = emptyMap()

composer.composeRequest(requestContainer)

try {
val controller = requestContainer.getComponent(controllerClass)

if (controller.before(request, response)) {
// Fire the controller's method depending on the HTTP method of the request
val httpMethod = request.requestMethod().toLowerCase()
val method = controllerClass.getMethod(httpMethod, Request::class.java, Response::class.java)
val result = method.invoke(controller, request, response)

if (result is ControllerResult && result.continueProcessing) {
controller.after(request, response)

model = result.model
}
}
} catch (e: Exception) {
halt(500, "Server Error")
}

return model
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ package com.nordicapis.kotlin_spark_sample
import spark.Request
import spark.Response

public class TokenController : Controllable()
{
public override fun get(request: Request, response: Response): ControllerResult
{
class TokenController : Controllable() {
override fun get(request: Request, response: Response): ControllerResult {
response.body("my good token")

return ControllerResult()
Expand Down
3 changes: 1 addition & 2 deletions src/main/kotlin/com/nordicapis/kotlin_spark_sample/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ main.kt - The entry point of the application

package com.nordicapis.kotlin_spark_sample

fun main(args: Array<String>) = api(composer = ContainerComposer())
{
fun main(args: Array<String>) = api(composer = ContainerComposer()) {
route(
path("/login", to = LoginController::class, renderWith = "login.vm"),
path("/authorize", to = AuthorizeController::class, renderWith = "authorize.vm"),
Expand Down
Loading

0 comments on commit 8e697cb

Please sign in to comment.