package scalaz
package http
package servlet
import request.Request
import Scalaz._
import request.{Method, RequestHeader}
import request.Line.line
import request.Uri.uri
import HttpSession.HttpSessionSession
import Util.Nel._
sealed trait HttpServletRequest {
val request: javax.servlet.http.HttpServletRequest
def apply(param: String) = Option(request.getParameter(param))
def !(param: String) = Option(request.getParameter(param)) err ("Missing request parameter: " + param)
def -=(attr: String) = request.removeAttribute(attr)
def update[A](attr: String, value: A) = request.setAttribute(attr, value)
def attr(attr: String) = Option(request.getAttribute(attr))
def session = HttpSessionSession(request.getSession)
def session(create: Boolean) = HttpSessionSession(request.getSession(create))
def asRequest[I[_]](implicit in: InputStreamer[I]) = {
val headers: List[(RequestHeader, NonEmptyList[Char])] = request.getHeaderNames.elements.map(_.asInstanceOf[String]).toList ∗
(h => request.getHeaders(h).elements.map(_.asInstanceOf[String]).filter(_.length > 0).map
(v => ((h: Option[RequestHeader]).get, v.toList.toNel.get)).toList)
val rline = (request.getMethod.toList: Option[Method]) >>= (m =>
request.getRequestURI.toList.toNel map
(p => uri(p, Option(request.getQueryString) map (_.toList))) >>=
(u => (request.getProtocol: Option[Version]) map
(v => line(m, u, v))))
rline map (Request.request[I](_, headers, in(request.getInputStream)))
}
}
trait HttpServletRequests {
implicit def HttpServletRequestRequest(r: javax.servlet.http.HttpServletRequest): HttpServletRequest = new HttpServletRequest {
val request = r
}
implicit def RequestHttpServletRequest(request: HttpServletRequest) = request.request
}
object HttpServletRequest extends HttpServletRequests {
def link(s: String)(implicit request: HttpServletRequest) =
request.getContextPath + '/' + s
def c[IN[_]](r: Request[IN])(implicit request: HttpServletRequest) = {
val k: Option[NonEmptyList[Char]] = (r.path drop request.getContextPath.length).toNel
k ∘ (p => r(r.uri(p))) | r
}
object MethodPath {
def unapply[IN[_]](r: Request[IN])(implicit hsr: HttpServletRequest): Option[(Method, String)] =
scalaz.http.request.Request.MethodPath.unapply(r) map (ms => (ms._1, ms._2.drop((hsr.getContextPath + "/").length)))
}
object Path {
def unapply[IN[_]](r: Request[IN])(implicit hsr: HttpServletRequest): Option[String] =
scalaz.http.request.Request.Path.unapply(r) map (_.drop((hsr.getContextPath + "/").length))
}
}