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

as.rubble_2.10.0.4.1.source-code.rubble.scala Maven / Gradle / Ivy

The newest version!
package com.earldouglas.rubble

import scala.collection.JavaConversions._
import java.io.{InputStream,OutputStream}
import scala.util.matching.Regex
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpServlet
import scala.xml.NodeSeq

object `package` {
  implicit def richRequest(req: HttpServletRequest) = new RichRequest(req)
  implicit def stringBody(body: String) = StringBody(body)
  implicit def streamBody(body: Stream[Byte]) = StreamBody(body)
  implicit def inputStreamBody(body: InputStream) = InputStreamBody(body)
  implicit def xmlBody(body: NodeSeq) = XmlBody(body)
  implicit def richServlet(servlet: HttpServlet) = new RichServlet(servlet)
  implicit def richResponse(res: HttpServletResponse) = new RichResponse(res)
  implicit def utf8ByteStream(string: String): Stream[Byte] = string.getBytes("UTF-8").toStream

  implicit class Builder[+A](a: A) {
    def <+(f: A => Any): A = {
      f(a)
      a
    }
  }

  implicit class Value[A](a: A) {
    def ~>[B](f: A => B): B = map(f)
    def map[B](f: A => B): B = f(a)
    def flatMap[B](f: A => A => B): B = f(a)(a)
  }

}

class RichRequest(req: HttpServletRequest) {

  lazy val root = req.getScheme + "://" + req.getServerName + ":" + req.getServerPort + context

  lazy val context = Option(req.getContextPath).getOrElse("") +
                     Option(req.getServletPath).getOrElse("")

  lazy val headers =
    req.getHeaderNames.map(name => (name -> req.getHeader(name))).toMap

  lazy val method: String = req.getMethod

  lazy val uri: String = req.getRequestURI match {
    case x if x startsWith context => x.substring(context.length)
    case x => x
  }

  lazy val query: Option[String] = Option(req.getQueryString)

  lazy val params: Map[String, String] =
    req.getParameterNames.map(name => (name -> req.getParameter(name))).toMap

  lazy val body: Stream[Byte] =
    Stream.continually(req.getInputStream.read).takeWhile(_ != -1).map(_.toByte)
}

class RichServlet(servlet: HttpServlet) {
  lazy val initParams: Map[String, String] =
    servlet.getInitParameterNames.map(name => (name -> servlet.getInitParameter(name))).toMap
}

sealed trait Body
case object NoBody extends Body
case class StringBody(body: String) extends Body
case class StreamBody(body: Stream[Byte]) extends Body
case class InputStreamBody(body: InputStream) extends Body
case class XmlBody(body: NodeSeq) extends Body
case class MustacheBody(resourceName: String, model: AnyRef) extends Body

class RichResponse(res: HttpServletResponse) {

  def respond(status: Int = 200, headers: Map[String,String] = Map.empty, body: Body = NoBody) {

    res.setStatus(status)

    headers.foreach(kv => res.setHeader(kv._1, kv._2))

    body match {
      case StringBody(body)        => res.getWriter.write(body)
      case StreamBody(body)        => res.getOutputStream ~> { os => write(body, os) }
      case InputStreamBody(body)   => res.getOutputStream ~> { os => write(body, os) }
      case XmlBody(body)           => res.getWriter ~> { w => body.foreach(n => w.write(n.toString)) }
      case MustacheBody(name, mdl) => getClass.getClassLoader.getResourceAsStream(name) ~>
                                        { s =>
                                            val r = new java.io.InputStreamReader(s)
                                            mustache.mustacheFactory.compile(r, name) } ~>
                                        { m => m.execute(res.getWriter, mdl).close }
      case NoBody                  =>
    }
  }

  private def write(s: Stream[Byte], os: OutputStream) {
    s.grouped(10240).foreach { _.toArray ~> { x => os.write(x, 0, x.length) } }
  }

  private def write(is: InputStream, os: OutputStream) {
    val buffer = new Array[Byte](10240)
    var i: Int = is.read(buffer)
    while (i != -1) {
      os.write(buffer, 0, i)
      i = is.read(buffer)
    }
  }

  def redirect(loc: String) = res <+ { _.setStatus(303) } <+ { _.setHeader("Location", loc) }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy