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

me.laiseca.urlmapper.UrlMapper.scala Maven / Gradle / Ivy

The newest version!
package me.laiseca.urlmapper

import me.laiseca.urlmapper.trie.Trie

/**
 * Created by Xabier Laiseca on 27/07/14.
 */
trait UrlMapper[T] {
  def map(url: String): Option[T]
}

object UrlMapper {
  private def toPathTrie[T] (wildcard: String, recursiveWildcard: String, mappings: (String, T)*): PathTrie[T] =
    Trie((for {
      mapping <- mappings
      segments = toUrlSegments(mapping._1, wildcard, recursiveWildcard)
    } yield segments -> UrlMapping(mapping._1, segments, mapping._2)):_*)

  def apply[T](paths: PathTrie[T]): UrlMapper[T] = new DefaultUrlMapper(paths)
  def apply[T](paths: PathTrie[T], selectionAlgorithm: UrlMappingSelectionAlgorithm): UrlMapper[T] =
    new CustomizableUrlMapper(paths, selectionAlgorithm)

  def apply[T](wildcard: String, recursiveWildcard: String, mappings: (String, T)*): UrlMapper[T] =
    apply(toPathTrie(wildcard, recursiveWildcard, mappings:_*))

  def apply[T](wildcard: String, recursiveWildcard: String, selectionAlgorithm: UrlMappingSelectionAlgorithm,
               mappings: (String, T)*): UrlMapper[T] =
    apply(toPathTrie(wildcard, recursiveWildcard, mappings:_*), selectionAlgorithm)

  def apply[T](mappings: (String, T)*): UrlMapper[T] = apply("*", "**", mappings:_*)
  def apply[T]( selectionAlgorithm: UrlMappingSelectionAlgorithm, mappings: (String, T)*): UrlMapper[T] =
    apply("*", "**", selectionAlgorithm, mappings:_*)
}

class CustomizableUrlMapper[T] private[urlmapper] (val paths: PathTrie[T],
    val selectionAlgorithm: UrlMappingSelectionAlgorithm) extends UrlMapper[T] {
  private val matcher = new UrlMatcher

  override def map(url: String): Option[T] =
    matcher.matchUrl(url, paths) match {
      case Nil => None
      case options: List[UrlMapping[T]] => Some(selectionAlgorithm.select[T](options).value)
    }
}

class DefaultUrlMapper[T] private[urlmapper] (val paths: PathTrie[T]) extends UrlMapper[T] {
  override def map(url: String): Option[T] = {
    def mapping(current: UrlSegment, rest: List[String], paths: PathTrie[T]) = {
      val subtrie = paths subtrie current
      if (subtrie.isEmpty) None else map(rest, subtrie)
    }

    def fixedMappings(segments: List[String], paths: PathTrie[T]): Option[UrlMapping[T]] =
      mapping(new FixedValueUrlSegment(segments.head), segments.tail, paths)

    def wildcardMappings(segments: List[String], paths: PathTrie[T]): Option[UrlMapping[T]] =
      mapping(WildcardUrlSegment, segments.tail, paths)

    def recursiveWildcardMapping(paths: PathTrie[T]): Option[UrlMapping[T]] =
      mapping(RecursiveWildcardUrlSegment, Nil, paths)

    def map(segments: List[String], paths: PathTrie[T]): Option[UrlMapping[T]] = segments match {
      case Nil => paths.value
      case _ => fixedMappings(segments, paths).
        orElse(wildcardMappings(segments, paths)).
        orElse(recursiveWildcardMapping(paths))
    }

    map(toSegments(url), paths).map(_.value)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy