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

org.scalatra.Route.scala Maven / Gradle / Ivy

package org.scalatra

import org.scalatra.ServletCompat.http.HttpServletRequest

/**
 * A route is a set of matchers and an action.  A route is considered to match
 * if all of its route matchers return Some.  If a route matches, its action
 * may be invoked.  The route parameters extracted by the matchers are made
 * available to the action.
 */
case class Route(
  routeMatchers: Seq[RouteMatcher] = Seq.empty,
  action: Action,
  contextPath: HttpServletRequest => String = _ => "",
  metadata: Map[Symbol, Any] = Map.empty) {
  /**
   * Optionally returns this route's action and the multi-map of route
   * parameters extracted from the matchers.  Each matcher's returned params
   * are merged into those of the previous.  If any matcher returns None,
   * None is returned.  If there are no route matchers, some empty map is
   * returned.
   */
  def apply(requestPath: String): Option[MatchedRoute] = {
    routeMatchers.foldLeft(Option(Map.empty[String, Seq[String]])) {
      (acc: Option[MultiParams], routeMatcher: RouteMatcher) =>
        for {
          routeParams <- acc
          matcherParams <- routeMatcher(requestPath)
        } yield routeParams ++ matcherParams
    } map { routeParams => MatchedRoute(action, routeParams) }
  }

  /**
   * The reversible matcher of a route is the first reversible matcher, if
   * any.  This matcher may be used to generate URIs.
   */
  lazy val reversibleMatcher: Option[RouteMatcher] =
    routeMatchers find (_.isInstanceOf[ReversibleRouteMatcher])

  /**
   * Determines whether this is a reversible route.
   */
  lazy val isReversible: Boolean = !reversibleMatcher.isEmpty

  override def toString: String = routeMatchers mkString " "
}

object Route {

  def apply(transformers: Seq[RouteTransformer], action: Action): Route =
    apply(transformers, action, (_: HttpServletRequest) => "")

  def apply(transformers: Seq[RouteTransformer], action: Action, contextPath: HttpServletRequest => String): Route = {
    val route = Route(action = action, contextPath = contextPath)
    transformers.foldLeft(route) { (route, transformer) => transformer(route) }
  }

  def appendMatcher(matcher: RouteMatcher): RouteTransformer = { (route: Route) =>
    route.copy(routeMatchers = route.routeMatchers :+ matcher)
  }

}

/**
 * An action and the multi-map of route parameters to invoke it with.
 */
case class MatchedRoute(action: Action, multiParams: MultiParams)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy