<commit_before>package blueeyes.core.service

import blueeyes.core.http.HttpMethods._
import blueeyes.util.Future
import blueeyes.core.http.HttpMethod
import blueeyes.core.http.HttpHeaders._
import blueeyes.core.http.HttpHeaderImplicits._

trait RestHierarchy[S] {
  private type Parameters[T] = (RestPathPattern, HttpMethod, HttpRequest[T] => Future[HttpResponse[T]], HttpDataTranscoder[T, S])
  def hierarchy: List[Parameters[_]]
}

/** A handler for a particular http method (get/post/put/delete/etc.). A 
 * handler is a partial function from request to response. In order to 
 * create a method handler, four pieces of information are required:
 * a path pattern, a method, a request handler, and a transcoder.
 */
sealed trait HttpMethodHandler[In, Out, Base] extends PartialFunction[HttpRequest[In], Future[HttpResponse[Base]]] { self =>
  /** The pattern of paths handled by the request handler.
   */
  def pathPattern: RestPathPattern
  
  /** The HTTP method handled by the request handler.
   */
  def method: HttpMethod
  
  /** The request handler, which must return a future of the response.
   */
  def handler: HttpRequest[In] => Future[HttpResponse[Out]]
  
  /** The transcoder, which will convert data from the response type to a base
   * type.
   */
  def transcoder: HttpDataTranscoder[Out, Base]
  
  def isDefinedAt(request: HttpRequest[In]): Boolean = pathPattern.isDefinedAt(request.path) && method == request.method
    
  def apply(request: HttpRequest[In]): Future[HttpResponse[Base]] = {
    val pathParameters = pathPattern(request.path)
    
    val newRequest = request.copy(parameters = request.parameters ++ pathParameters)
    
    handler(newRequest).map { response =>
      response.copy(headers = response.headers + `Content-Type`(transcoder.mimeType), content = response.content.map(transcoder.transcode))
    }
  }
}

trait HttpService2[Base] {
  protected type RequestHandler[In, Out] = HttpRequest[In] => Future[HttpResponse[Out]]
  protected type NotFoundHandler[In, Out] = (RequestHandler[In, Out], HttpDataTranscoder[Out, Base])
  
  def name:             String
  def version:          String = majorVersion.toString + "." + String.format("%02d", int2Integer(minorVersion))
  def majorVersion:     Int = version.split(".")(0).toInt
  def minorVersion:     Int = version.split(".")(1).toInt
  
  def startupHooks:     List[() => Future[_]] = Nil
  def shutdownHooks:    List[() => Future[_]] = Nil
  def notFoundHandler:  Option[NotFoundHandler[_, _]] = None
  def requestHandlers:  List[HttpMethodHandler[_, _, Base]] = Nil
}

trait HttpServiceBuilder[Base] { self =>
  import scala.collection.mutable.{Buffer, ListBuffer, Stack}
  
  def services: Buffer[HttpService2[Base]]
  
  case class service(name: String) extends HttpService2[Base] {
    private val pathStack: Stack[RestPathPattern] = new Stack[RestPathPattern].push(RestPathPattern.Root);
    
    private type MethodHandler[T] = RequestHandler[T, T]
    
    self.services += this
    
    private var _notFoundHandler: Option[NotFoundHandler[_, _]] = None
    
    private val _startupHooks     = new ListBuffer[() => Future[_]]
    private val _shutdownHooks    = new ListBuffer[() => Future[_]]
    private val _requestHandlers  = new ListBuffer[HttpMethodHandler[_, _, Base]]
    
    override def startupHooks    = _startupHooks.toList
    override def shutdownHooks   = _shutdownHooks.toList
    override def notFoundHandler = _notFoundHandler
    override def requestHandlers = _requestHandlers.toList
    
    def path(path: RestPathPattern)(f: => Unit): Unit = {
      pathStack.push(path)

      try { f } finally { pathStack.pop() }
    }
    
    def get[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(GET, handler, t)

    def put[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(PUT, handler, t)

    def post[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(POST, handler, t)

    def delete[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(DELETE, handler, t)

    def options[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(OPTIONS, handler, t)

    def head[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(HEAD, handler, t)

    def connect[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(CONNECT, handler, t)

    def trace[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(TRACE, handler, t)<commit_msg>fix compile errors<commit_after>package blueeyes.core.service

import blueeyes.core.http.HttpMethods._
import blueeyes.util.Future
import blueeyes.core.http.HttpMethod
import blueeyes.core.http.HttpHeaders._
import blueeyes.core.http.HttpHeaderImplicits._

trait RestHierarchy[S] {
  private type Parameters[T] = (RestPathPattern, HttpMethod, HttpRequest[T] => Future[HttpResponse[T]], HttpDataTranscoder[T, S])
  def hierarchy: List[Parameters[_]]
}

/** A handler for a particular http method (get/post/put/delete/etc.). A 
 * handler is a partial function from request to response. In order to 
 * create a method handler, four pieces of information are required:
 * a path pattern, a method, a request handler, and a transcoder.
 */
sealed trait HttpMethodHandler[In, Out, Base] extends PartialFunction[HttpRequest[In], Future[HttpResponse[Base]]] { self =>
  /** The pattern of paths handled by the request handler.
   */
  def pathPattern: RestPathPattern
  
  /** The HTTP method handled by the request handler.
   */
  def method: HttpMethod
  
  /** The request handler, which must return a future of the response.
   */
  def handler: HttpRequest[In] => Future[HttpResponse[Out]]
  
  /** The transcoder, which will convert data from the response type to a base
   * type.
   */
  def transcoder: HttpDataTranscoder[Out, Base]
  
  def isDefinedAt(request: HttpRequest[In]): Boolean = pathPattern.isDefinedAt(request.path) && method == request.method
    
  def apply(request: HttpRequest[In]): Future[HttpResponse[Base]] = {
    val pathParameters = pathPattern(request.path)
    
    val newRequest = request.copy(parameters = request.parameters ++ pathParameters)
    
    handler(newRequest).map { response =>
      response.copy(headers = response.headers + `Content-Type`(transcoder.mimeType), content = response.content.map(transcoder.transcode))
    }
  }
}

trait HttpService2[Base] {
  protected type NotFoundHandler[In, Out] = (HttpRequest[In] => Future[HttpResponse[Out]], HttpDataTranscoder[Out, Base])
  
  def name:             String
  def version:          String = majorVersion.toString + "." + String.format("%02d", int2Integer(minorVersion))
  def majorVersion:     Int = version.split(".")(0).toInt
  def minorVersion:     Int = version.split(".")(1).toInt
  
  def startupHooks:     List[() => Future[_]] = Nil
  def shutdownHooks:    List[() => Future[_]] = Nil
  def notFoundHandler:  Option[NotFoundHandler[_, _]] = None
  def requestHandlers:  List[HttpMethodHandler[_, _, Base]] = Nil
}

trait HttpServiceBuilder[Base] {
  protected type RequestHandler[In, Out] = HttpRequest[In] => Future[HttpResponse[Out]]
  protected type MethodHandler[T] = RequestHandler[T, T]
  
  def path(path: RestPathPattern)(f: => Unit): Unit
  
  def get[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(GET, handler, t)

  def put[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(PUT, handler, t)

  def post[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(POST, handler, t)

  def delete[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(DELETE, handler, t)

  def options[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(OPTIONS, handler, t)

  def head[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(HEAD, handler, t)

  def connect[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(CONNECT, handler, t)

  def trace[T](handler: MethodHandler[T])(implicit t: HttpDataTranscoder[T, Base]) = custom(TRACE, handler, t)

  def custom[T](method: HttpMethod, handler: MethodHandler[T], transcoder: HttpDataTranscoder[T, Base])
  
  def startup(f: => Future[_])
  
  def shutdown(f: => Future[_])
  
  def notFound[In, Out](handler: RequestHandler[In, Out])(implicit transcoder: HttpDataTranscoder[Out, Base]): Unit
}

trait HttpServiceBuilderComposable[Base] { self =>
  import scala.collection.mutable.{Buffer, ListBuffer, Stack}
  
  def services: Buffer[HttpService2[Base]]
  
  case class service(name: String) extends HttpService2[Base] with HttpServiceBuilder[Base] {
    private val pathStack: Stack[RestPathPattern] = new Stack[RestPathPattern].push(RestPathPattern.Root);
    
    self.services += this
    
    private var _notFoundHandler: Option[NotFoundHandler[_, _]] = None
    
    private val _startupHooks     = new ListBuffer[() => Future[_]]
    private val _shutdownHooks    = new ListBuffer[() => Future[_]]
    private val _requestHandlers  = new ListBuffer[HttpMethodHandler[_, _, Base]]
    
    override def startupHooks    = _startupHooks.toList
    override def shutdownHooks   = _shutdownHooks.toList
    override def notFoundHandler = _notFoundHandler
    override def requestHandlers = _requestHandlers.toList
    
    def path(path: RestPathPattern)(f: => Unit): Unit = {
      pathStack.push(path)

      try { f } finally { pathStack.pop() }
    }
{'fraction_non_alphanumeric': 0.12149630092737314, 'fraction_numerical': 0.001667187662811295, 'mean_word_length': 4.484571428571429, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6436774', 'n_tokens_mistral': 2943, 'n_tokens_neox': 2906, 'n_words': 755}