Esempio n. 1
0
  /**
   * If there's no match, returns the result with {@link #notFound(Object) notFound} as the target
   * if it is set, otherwise returns {@code null}.
   */
  public RouteResult<T> route(final HttpMethod method, final String uri) {
    final QueryStringDecoder decoder = new QueryStringDecoder(uri);
    final String[] tokens = StringUtil.split(Path.removeSlashesAtBothEnds(decoder.path()), '/');

    MethodlessRouter<T> router = routers.get(method);
    if (router == null) {
      router = anyMethodRouter;
    }

    RouteResult<T> ret = router.route(tokens);
    if (ret != null) {
      return new RouteResult<T>(ret.target(), ret.pathParams(), decoder.parameters());
    }

    if (router != anyMethodRouter) {
      ret = anyMethodRouter.route(tokens);
      if (ret != null) {
        return new RouteResult<T>(ret.target(), ret.pathParams(), decoder.parameters());
      }
    }

    if (notFound != null) {
      // Return mutable map to be consistent, instead of
      // Collections.<String, String>emptyMap()
      return new RouteResult<T>(notFound, new HashMap<String, String>(), decoder.parameters());
    }

    return null;
  }
Esempio n. 2
0
  /** Returns the number of routes in this router. */
  public int size() {
    int ret = anyMethodRouter.size();

    for (MethodlessRouter<T> router : routers.values()) {
      ret += router.size();
    }

    return ret;
  }
Esempio n. 3
0
 /**
  * Given a target and params, this method tries to do the reverse routing and returns the path.
  *
  * <p>The params are put to placeholders in the path. The params can be a map of {@code
  * placeholder name -> value} or ordered values. If a param doesn't have a placeholder, it will be
  * put to the query part of the path.
  *
  * @return {@code null} if there's no match
  */
 public String path(final T target, final Object... params) {
   final Collection<MethodlessRouter<T>> rs = routers.values();
   for (MethodlessRouter<T> r : rs) {
     final String ret = r.path(target, params);
     if (ret != null) {
       return ret;
     }
   }
   return anyMethodRouter.path(target, params);
 }
Esempio n. 4
0
  /**
   * Given a target and params, this method tries to do the reverse routing and returns the path.
   *
   * <p>The params are put to placeholders in the path. The params can be a map of {@code
   * placeholder name -> value} or ordered values. If a param doesn't have a placeholder, it will be
   * put to the query part of the path.
   *
   * @return {@code null} if there's no match
   */
  public String path(final HttpMethod method, final T target, final Object... params) {
    MethodlessRouter<T> router = (method == null) ? anyMethodRouter : routers.get(method);

    // Fallback to anyMethodRouter if no router is found for the method
    if (router == null) {
      router = anyMethodRouter;
    }

    final String ret = router.path(target, params);
    if (ret != null) {
      return ret;
    }

    // Fallback to anyMethodRouter if the router was not anyMethodRouter and no path is found
    return (router != anyMethodRouter) ? anyMethodRouter.path(target, params) : null;
  }
Esempio n. 5
0
  /**
   * Returns allowed methods for a specific URI.
   *
   * <p>For {@code OPTIONS *}, use {@link #allAllowedMethods()} instead of this method.
   */
  public Set<HttpMethod> allowedMethods(final String uri) {
    final QueryStringDecoder decoder = new QueryStringDecoder(uri);
    final String[] tokens = StringUtil.split(Path.removeSlashesAtBothEnds(decoder.path()), '/');

    if (anyMethodRouter.anyMatched(tokens)) {
      return allAllowedMethods();
    }

    final Set<HttpMethod> ret = new HashSet<HttpMethod>(routers.size());
    for (Map.Entry<HttpMethod, MethodlessRouter<T>> entry : routers.entrySet()) {
      final MethodlessRouter<T> router = entry.getValue();
      if (router.anyMatched(tokens)) {
        final HttpMethod method = entry.getKey();
        ret.add(method);
      }
    }

    return ret;
  }
Esempio n. 6
0
 /** Returns all methods that this router handles. For {@code OPTIONS *}. */
 public Set<HttpMethod> allAllowedMethods() {
   if (anyMethodRouter.size() > 0) {
     final Set<HttpMethod> ret = new HashSet<HttpMethod>(9);
     ret.add(HttpMethod.CONNECT);
     ret.add(HttpMethod.DELETE);
     ret.add(HttpMethod.GET);
     ret.add(HttpMethod.HEAD);
     ret.add(HttpMethod.OPTIONS);
     ret.add(HttpMethod.PATCH);
     ret.add(HttpMethod.POST);
     ret.add(HttpMethod.PUT);
     ret.add(HttpMethod.TRACE);
     return ret;
   } else {
     return new HashSet<HttpMethod>(routers.keySet());
   }
 }
Esempio n. 7
0
  /** Returns visualized routing rules. */
  @Override
  public String toString() {
    // Step 1/2: Dump routers and anyMethodRouter in order
    final int numRoutes = size();
    final List<String> methods = new ArrayList<String>(numRoutes);
    final List<String> paths = new ArrayList<String>(numRoutes);
    final List<String> targets = new ArrayList<String>(numRoutes);

    // For router
    for (Entry<HttpMethod, MethodlessRouter<T>> e : routers.entrySet()) {
      HttpMethod method = e.getKey();
      MethodlessRouter<T> router = e.getValue();
      aggregateRoutes(method.toString(), router.first().routes(), methods, paths, targets);
      aggregateRoutes(method.toString(), router.other().routes(), methods, paths, targets);
      aggregateRoutes(method.toString(), router.last().routes(), methods, paths, targets);
    }

    // For anyMethodRouter
    aggregateRoutes("*", anyMethodRouter.first().routes(), methods, paths, targets);
    aggregateRoutes("*", anyMethodRouter.other().routes(), methods, paths, targets);
    aggregateRoutes("*", anyMethodRouter.last().routes(), methods, paths, targets);

    // For notFound
    if (notFound != null) {
      methods.add("*");
      paths.add("*");
      targets.add(targetToString(notFound));
    }

    // Step 2/2: Format the List into aligned columns: <method> <path> <target>
    int maxLengthMethod = maxLength(methods);
    int maxLengthPath = maxLength(paths);
    String format = "%-" + maxLengthMethod + "s  %-" + maxLengthPath + "s  %s\n";
    int initialCapacity = (maxLengthMethod + 1 + maxLengthPath + 1 + 20) * methods.size();
    StringBuilder b = new StringBuilder(initialCapacity);
    for (int i = 0; i < methods.size(); i++) {
      String method = methods.get(i);
      String path = paths.get(i);
      String target = targets.get(i);
      b.append(String.format(format, method, path, target));
    }
    return b.toString();
  }
Esempio n. 8
0
 /** Removes all routes leading to the target. */
 public void removeTarget(final T target) {
   for (MethodlessRouter<T> r : routers.values()) {
     r.removeTarget(target);
   }
   anyMethodRouter.removeTarget(target);
 }
Esempio n. 9
0
 /** Removes the route specified by the path. */
 public void removePath(final String path) {
   for (MethodlessRouter<T> r : routers.values()) {
     r.removePath(path);
   }
   anyMethodRouter.removePath(path);
 }