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

ratpack.handling.Handlers Maven / Gradle / Ivy

There is a newer version: 2.0.0-rc-1
Show newest version
/*
 * Copyright 2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ratpack.handling;

import ratpack.api.Nullable;
import ratpack.file.internal.AssetHandler;
import ratpack.file.internal.FileSystemBindingHandler;
import ratpack.func.Action;
import ratpack.handling.internal.*;
import ratpack.http.internal.*;
import ratpack.launch.LaunchConfig;
import ratpack.path.PathBinder;
import ratpack.path.PathBinders;
import ratpack.path.internal.PathHandler;
import ratpack.registry.Registry;

import java.util.List;

import static com.google.common.collect.ImmutableList.copyOf;

/**
 * Factory methods for handler decorations.
 */
public abstract class Handlers {

  private Handlers() {
  }

  /**
   * A handler that delegates to the next handler if the request claims that it can accept one of the given types, otherwise raises a 406 client error.
   *
   * @param contentTypes The content types to verify that the request can support for the response
   * @return A handler
   */
  public static Handler accepts(String... contentTypes) {
    return new AcceptsHandler(contentTypes);
  }

  /**
   * A handler that serves static assets at the given file system path, relative to the contextual file system binding.
   * 

* The file to serve is calculated based on the contextual {@link ratpack.file.FileSystemBinding} and the * contextual {@link ratpack.path.PathBinding}. * The {@link ratpack.path.PathBinding#getPastBinding()} of the contextual path binding is used to find a file/directory * relative to the contextual file system binding. *

* If the request matches a directory, an index file may be served. * The {@code indexFiles} array specifies the names of files to look for in order to serve. *

* If no file can be found to serve, then control will be delegated to the next handler. * * @param launchConfig The application launch config * @param path The relative path to the location of the assets to serve * @param indexFiles The index files to try if the request is for a directory * @return A handler */ public static Handler assets(LaunchConfig launchConfig, String path, List indexFiles) { Handler handler = new AssetHandler(copyOf(indexFiles)); return fileSystem(launchConfig, path, handler); } /** * Builds a handler chain, with no backing registry. * * @param launchConfig The application launch config * @param action The chain definition * @return A handler * @throws Exception any thrown by {@code action} */ public static Handler chain(LaunchConfig launchConfig, Action action) throws Exception { return chain(launchConfig, null, action); } /** * Builds a chain, backed by the given registry. * * @param launchConfig The application launch config * @param registry The registry. * @param action The chain building action. * @return A handler * @throws Exception any thrown by {@code action} */ public static Handler chain(@Nullable LaunchConfig launchConfig, @Nullable Registry registry, Action action) throws Exception { return ChainBuilders.build(launchConfig != null && launchConfig.isDevelopment(), new ChainActionTransformer(launchConfig, registry), action); } /** * Creates a handler chain from the given handlers. * * @param handlers The handlers to connect into a chain * @return A new handler that is the given handlers connected into a chain */ public static Handler chain(List handlers) { if (handlers.size() == 0) { return ctx -> ctx.next(); } else if (handlers.size() == 1) { return handlers.get(0); } else { return new ChainHandler(handlers); } } /** * Creates a handler chain from the given handlers. * * @param handlers The handlers to connect into a chain * @return A new handler that is the given handlers connected into a chain */ public static Handler chain(Handler... handlers) { if (handlers.length == 0) { return ctx -> ctx.next(); } else if (handlers.length == 1) { return handlers[0]; } else { return new ChainHandler(handlers); } } /** * A handler that simply calls {@link Context#clientError(int)} with the given status code. * * @param statusCode The 4xx client error status code * @return A handler */ public static Handler clientError(int statusCode) { return new ClientErrorForwardingHandler(statusCode); } /** * A handler that delegates to the next handler if the content type of the request is one of the given types, otherwise raises a 415 client error. * * @param contentTypes The request content types to require * @return A handler */ public static Handler contentTypes(String... contentTypes) { return new ContentTypeHandler(contentTypes); } /** * A handler that delegates to the next handler if the request is DELETE, otherwise raises a 405 client error. * * @return A handler */ public static Handler delete() { return MethodHandler.DELETE; } /** * A handlers that changes the {@link ratpack.file.FileSystemBinding} for the given handlers. *

* The new file system binding will be created by the {@link ratpack.file.FileSystemBinding#binding(String)} method of the contextual binding. * * @param launchConfig The application launch config * @param path The relative path to the new file system binding point * @param handler The handler to execute with the new file system binding * @return A handler */ public static Handler fileSystem(LaunchConfig launchConfig, String path, Handler handler) { return new FileSystemBindingHandler(launchConfig, path, handler); } /** * A handler that delegates to the next handler if the request is GET, otherwise raises a 405 client error. * * @return A handler */ public static Handler get() { return MethodHandler.GET; } /** * Creates a handler that delegates to the given handler if the {@code request} has a {@code HTTPHeader} with the * given name and a it's value matches the given value exactly. * * @param headerName the name of the HTTP Header to match on * @param headerValue the value of the HTTP Header to match on * @param handler the handler to delegate to * @return A handler */ public static Handler header(String headerName, String headerValue, Handler handler) { return new HeaderHandler(headerName, headerValue, handler); } /** * Creates a handler that delegates to the given handler if the {@code request} has a {@code HTTPHost} with the * given name that matches the given value exactly. * * @param hostName the name of the HTTP Header to match on * @param handler the handler to delegate to * @return A handler */ public static Handler host(String hostName, Handler handler) { return new HeaderHandler("Host", hostName, handler); } /** * A handler that simply delegates to the next handler. *

* Effectively a noop. * * @return A handler */ public static Handler next() { return NextHandler.INSTANCE; } /** * Convenience for {@link #clientError(int) clientError(404)}. * * @return A handler */ public static Handler notFound() { return ClientErrorForwardingHandler.NOT_FOUND; } /** * A handler that delegates to the next handler if the request is PATCH, otherwise raises a 405 client error. * * @return A handler */ public static Handler patch() { return MethodHandler.PATCH; } /** * Creates a handler that delegates to the given handlers if the request matches the given path exactly. *

* The {@code path} is relative to the contextual {@link ratpack.path.PathBinding} of the exchange. *

* A new contextual {@link ratpack.path.PathBinding} will be established for the given handlers, * using the given path as the bind point. * * @param path The exact path to match to * @param handler The handlers to delegate to if the path matches * @return A handler */ public static Handler path(String path, Handler handler) { return path(PathBinders.parse(path, true), handler); } /** * Creates a handler that delegates to the given handlers if the request can be bound by the given path binder. * * @param pathBinder The path binder that may bind to the request path * @param handler The handlers to delegate to if path binder does bind to the path * @return A handler */ public static Handler path(PathBinder pathBinder, Handler handler) { return new PathHandler(pathBinder, handler); } /** * A handler that delegates to the next handler if the request is POST, otherwise raises a 405 client error. * * @return A handler */ public static Handler post() { return MethodHandler.POST; } /** * Creates a handler that delegates to the given handlers if the request path starts with the given prefix. *

* The {@code prefix} is relative to the contextual {@link ratpack.path.PathBinding} of the exchange. *

* A new contextual {@link ratpack.path.PathBinding} will be established for the given handlers, * using the given prefix as the bind point. * * @param prefix The path prefix to match * @param handler The handler to delegate to * @return A handler */ public static Handler prefix(String prefix, Handler handler) { return path(PathBinders.parse(prefix, false), handler); } /** * A handler that delegates to the next handler if the request is PUT, otherwise raises a 405 client error. * * @return A handler */ public static Handler put() { return MethodHandler.PUT; } /** * A handler that simply calls {@link Context#insert(Registry, Handler...)} with the given registry and handler. * * @param registry the registry to insert * @param handler The handler to insert * @return A handler */ public static Handler register(Registry registry, Handler handler) { return new RegistryInsertHandler(registry, handler); } /** * A handler that simply calls {@link Context#next(Registry)} with the given registry. * * @param registry The registry to make available to the next handlers * @return A handler * @see Context#next(Registry) */ public static Handler register(Registry registry) { return new RegistryNextHandler(registry); } /** * Creates a handler that always issues a redirect using {@link Context#redirect(int, String)} with exactly the given code and location. *

* This method will immediate throw an {@link IllegalArgumentException} if code is < 300 || > 399. * * @param code the 3XX HTTP status code * @param location the URL to set in the Location response header * @return a handler * @see Context#redirect(int, String) */ public static Handler redirect(int code, String location) { return new RedirectionHandler(location, code); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy