-
Notifications
You must be signed in to change notification settings - Fork 334
/
ScalatraRenderContext.scala
148 lines (126 loc) · 4.79 KB
/
ScalatraRenderContext.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package org.scalatra
package scalate
import servlet.{FileItem, FileUploadSupport, FileMultiParams, ServletBase}
import java.io.PrintWriter
import javax.servlet.http.{HttpServletResponse, HttpServletRequest, HttpSession}
import org.fusesource.scalate.TemplateEngine
import org.fusesource.scalate.servlet.ServletRenderContext
import javax.servlet.ServletContext
import servlet.ServletApiImplicits._
/**
* A render context integrated with Scalatra. Exposes a few extra
* standard bindings to the template.
*/
class ScalatraRenderContext(
protected val kernel: ServletBase,
engine: TemplateEngine,
out: PrintWriter,
req: HttpServletRequest,
res: HttpServletResponse) extends ServletRenderContext(engine, out, req, res, kernel.servletContext) {
def flash: scala.collection.Map[String, Any] = kernel match {
case flashMapSupport: FlashMapSupport => flashMapSupport.flash(request)
case _ => Map.empty
}
def session: HttpSession = kernel.session(request)
def sessionOption: Option[HttpSession] = kernel.sessionOption(request)
def params: Params = kernel.params(request)
def multiParams: MultiParams = kernel.multiParams(request)
def format: String = kernel match {
case af: ApiFormats => af.format(request)
case _ => ""
}
def responseFormat: String = kernel match {
case af: ApiFormats => af.responseFormat(request, response)
case _ => ""
}
def fileMultiParams: FileMultiParams = kernel match {
case fu: FileUploadSupport => fu.fileMultiParams(request)
case _ => new FileMultiParams()
}
def fileParams: scala.collection.Map[String, FileItem] = kernel match {
case fu: FileUploadSupport => fu.fileParams(request)
case _ => Map.empty
}
def csrfKey = kernel match {
case csrfTokenSupport: CsrfTokenSupport => csrfTokenSupport.csrfKey
case _ => ""
}
def csrfToken = kernel match {
case csrfTokenSupport: CsrfTokenSupport => csrfTokenSupport.csrfToken(request)
case _ => ""
}
def xsrfKey = kernel match {
case csrfTokenSupport: XsrfTokenSupport => csrfTokenSupport.xsrfKey
case _ => ""
}
def xsrfToken = kernel match {
case csrfTokenSupport: XsrfTokenSupport => csrfTokenSupport.xsrfToken(request)
case _ => ""
}
/**
* Calculate a URL for a reversible route and some params.
*
* @param route a reversible route
* @param params a list of named param/value pairs
* @return a URI that matches the route for the given params
* @throws Exception if the route is not reversible
* @throws IllegalStateException if the route's base path cannot be
* determined. This may occur outside of an HTTP request's lifecycle.
*/
def url(route: Route, params: Pair[String, String]*): String =
url(route, params.toMap, Seq.empty)
/**
* Calculate a URL for a reversible route and some splats.
*
* @param route a reversible route
* @param splat the first splat parameter
* @param moreSplats any splat parameters beyond the first
* @return a URI that matches the route for the given splats
* @throws Exception if the route is not reversible
* @throws IllegalStateException if the route's base path cannot be
* determined. This may occur outside of an HTTP request's lifecycle.
*/
def url(route: Route, splat: String, moreSplats: String*): String =
url(route, Map[String, String](), splat +: moreSplats)
/**
* Calculate a URL for a reversible route, some params, and some splats.
*
* @param route a reversible route
* @param params a map of param/value pairs
* @param splats a series of splat parameters
* @return a URI that matches the route for the given splats
* @throws Exception if the route is not reversible
* @throws IllegalStateException if the route's base path cannot be
* determined. This may occur outside of an HTTP request's lifecycle.
*/
def url(
route: Route,
params: Map[String, String],
splats: Iterable[String]
): String = {
route.reversibleMatcher match {
case Some(matcher: ReversibleRouteMatcher) =>
withRouteMultiParams(MatchedRoute(route.action, multiParams)) {
route.contextPath(request) + matcher.reverse(params, splats.toList)
}
case _ =>
throw new Exception("Route \"%s\" is not reversible" format (route))
}
}
private[this] def withRouteMultiParams[S](matchedRoute: MatchedRoute)(thunk: => S): S = {
val originalParams = multiParams
setMultiparams(matchedRoute, originalParams)
try {
thunk
} finally {
request(MultiParamsKey) = originalParams
}
}
def setMultiparams[S](matchedRoute: MatchedRoute, originalParams: MultiParams) {
val routeParams = matchedRoute.multiParams map {
case (key, values) =>
key -> values.map(UriDecoder.secondStep(_))
}
request(MultiParamsKey) = originalParams ++ routeParams
}
}