/*
* 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.groovy.handling;
import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import ratpack.file.FileHandlerSpec;
import ratpack.func.Action;
import ratpack.func.Predicate;
import ratpack.groovy.handling.internal.DefaultGroovyChain;
import ratpack.groovy.internal.ClosureUtil;
import ratpack.handling.Chain;
import ratpack.handling.Context;
import ratpack.handling.Handler;
import ratpack.registry.Registry;
import ratpack.registry.RegistrySpec;
import static ratpack.groovy.Groovy.chainAction;
import static ratpack.groovy.Groovy.groovyHandler;
import static ratpack.groovy.internal.ClosureUtil.delegatingAction;
/**
* A Groovy oriented handler chain builder DSL.
* <p>
* The methods specific to this subclass create {@link ratpack.handling.Handler} instances from closures and
* add them to the underlying chain.
* <p>
* These methods are generally shortcuts for {@link #all(ratpack.handling.Handler)} on this underlying chain.
*/
public interface GroovyChain extends Chain {
/**
* Creates a Groovy chain wrapper over a chain instance.
*
* @param chain a chain instance
* @return a Groovy wrapper
*/
static GroovyChain from(Chain chain) {
if (chain instanceof GroovyChain) {
return (GroovyChain) chain;
} else {
return new DefaultGroovyChain(chain);
}
}
/**
* Adds the given {@code Closure} as a {@code Handler} to this {@code GroovyChain}.
*
* @param handler the {@code Closure} to add
* @return this {@code GroovyChain}
*/
default GroovyChain all(@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return all(groovyHandler(handler));
}
/**
* {@inheritDoc}
*/
@Override
GroovyChain all(Handler handler);
/**
* {@inheritDoc}
*/
@Override
default GroovyChain all(Class<? extends Handler> handler) {
return all(getRegistry().get(handler));
}
/**
* Creates a handler from the given closure.
*
* @param closure a chain definition
* @return a new handler
* @throws Exception any thrown by {@code closure}
*/
default Handler chain(@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> closure) throws Exception {
return chain(c -> ClosureUtil.configureDelegateFirst(GroovyChain.from(c), closure));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler} if the
* relative {@code path} matches the given {@code path} and the {@code request} {@code HTTPMethod} is {@code DELETE}.
* <p>
* See {@link GroovyChain#delete(String, ratpack.handling.Handler)} for more details.
*
* @param path the relative path to match on
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain delete(String path, @DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return delete(path, groovyHandler(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler}
* if the {@code request} {@code HTTPMethod} is {@code DELETE} and the {@code path} is at the current root.
* <p>
* See {@link GroovyChain#delete(ratpack.handling.Handler)} for more details.
*
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain delete(@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return delete(groovyHandler(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain delete(String path, Handler handler) {
return from(Chain.super.delete(path, handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain delete(String path, Class<? extends Handler> handler) {
return delete(path, getRegistry().get(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain delete(Handler handler) {
return from(Chain.super.delete(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain delete(Class<? extends Handler> handler) {
return delete(getRegistry().get(handler));
}
/**
* Creates a {@code List} of {@code Handler} from the given {@code Closure} and adds a {@code Handler} to this {@code GroovyChain} that
* changes the {@link ratpack.file.FileSystemBinding} for the {@code Handler} list.
* <p>
* See {@link GroovyChain#fileSystem(String, ratpack.func.Action)} for more details.
*
* @param path the relative {@code path} to the new file system binding point
* @param handlers the definition of the handler chain
* @return this {@code GroovyChain}
* @throws Exception any thrown by {@code closure}
*/
default GroovyChain fileSystem(String path, @DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handlers) throws Exception {
return fileSystem(path, chainAction(handlers));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain fileSystem(String path, Action<? super Chain> action) throws Exception {
return from(Chain.super.fileSystem(path, action));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain fileSystem(String path, Class<? extends Action<? super Chain>> action) throws Exception {
return fileSystem(path, getRegistry().get(action));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain files(Action<? super FileHandlerSpec> config) throws Exception {
return from(Chain.super.files(config));
}
@Override
default GroovyChain files() {
return from(Chain.super.files());
}
default GroovyChain files(@DelegatesTo(value = FileHandlerSpec.class, strategy = Closure.DELEGATE_FIRST) Closure<?> closure) throws Exception {
return files(delegatingAction(FileHandlerSpec.class, closure));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain get(String path, Handler handler) {
return from(Chain.super.get(path, handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain get(String path, Class<? extends Handler> handler) {
return get(path, getRegistry().get(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain get(Handler handler) {
return from(Chain.super.get(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain get(Class<? extends Handler> handler) {
return get(getRegistry().get(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler} if the
* relative {@code path} matches the given {@code path} and the {@code request} {@code HTTPMethod} is {@code GET}.
* <p>
* See {@link GroovyChain#get(String, ratpack.handling.Handler)} for more details.
*
* @param path the relative path to match on
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain get(String path, @DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return get(path, groovyHandler(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler}
* if the {@code request} {@code HTTPMethod} is {@code GET} and the {@code path} is at the current root.
* <p>
* See {@link GroovyChain#get(ratpack.handling.Handler)} for more details.
*
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain get(@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return get(groovyHandler(handler));
}
/**
* {@inheritDoc}
*/
default GroovyChain host(String hostName, Action<? super Chain> action) throws Exception {
return from(Chain.super.host(hostName, action));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain host(String hostName, Class<? extends Action<? super Chain>> action) throws Exception {
return host(hostName, getRegistry().get(action));
}
/**
* If the request has a {@code Host} header that matches the given host name exactly, handling will be delegated to the chain defined by the given closure.
*
* @param hostName the name of the HTTP Header to match on
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
* @throws Exception any thrown by {@code closure}
* @see #host(String, ratpack.func.Action)
*/
default GroovyChain host(String hostName, @DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) throws Exception {
return host(hostName, chainAction(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain insert(Action<? super Chain> action) throws Exception {
return from(Chain.super.insert(action));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain insert(Class<? extends Action<? super Chain>> action) throws Exception {
return insert(getRegistry().get(action));
}
/**
* Inserts the given nested handler chain.
* <p>
* Shorter form of {@link #all(Handler)} handler}({@link #chain(groovy.lang.Closure) chain}({@code closure}).
*
* @param closure the handler chain to insert
* @return this
* @throws Exception any thrown by {@code closure}
*/
default GroovyChain insert(@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> closure) throws Exception {
return insert(chainAction(closure));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain patch(String path, Handler handler) {
return from(Chain.super.patch(path, handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain patch(String path, Class<? extends Handler> handler) {
return patch(path, getRegistry().get(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain patch(Handler handler) {
return from(Chain.super.patch(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain patch(Class<? extends Handler> handler) {
return patch(getRegistry().get(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler} if the
* relative {@code path} matches the given {@code path} and the {@code request} {@code HTTPMethod} is {@code PATCH}.
* <p>
* See {@link GroovyChain#put(String, ratpack.handling.Handler)} for more details.
*
* @param path the relative path to match on
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain patch(String path, @DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return patch(path, groovyHandler(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler}
* if the {@code request} {@code HTTPMethod} is {@code PATCH} and the {@code path} is at the current root.
* <p>
* See {@link GroovyChain#put(ratpack.handling.Handler)} for more details.
*
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain patch(@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return path(groovyHandler(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain options(String path, Handler handler) {
return from(Chain.super.options(path, handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain options(String path, Class<? extends Handler> handler) {
return options(path, getRegistry().get(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain options(Handler handler) {
return from(Chain.super.options(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain options(Class<? extends Handler> handler) {
return options(getRegistry().get(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler} if the
* relative {@code path} matches the given {@code path} and the {@code request} {@code HTTPMethod} is {@code OPTIONS}.
* <p>
* See {@link GroovyChain#put(String, ratpack.handling.Handler)} for more details.
*
* @param path the relative path to match on
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
* @since 1.1
*/
default GroovyChain options(String path, @DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return options(path, groovyHandler(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler}
* if the {@code request} {@code HTTPMethod} is {@code OPTIONS} and the {@code path} is at the current root.
* <p>
* See {@link GroovyChain#put(ratpack.handling.Handler)} for more details.
*
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
* @since 1.1
*/
default GroovyChain options(@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return path(groovyHandler(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain path(String path, Handler handler) {
return from(Chain.super.path(path, handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain path(Handler handler) {
return path("", handler);
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain path(String path, Class<? extends Handler> handler) {
return path(path, getRegistry().get(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain path(Class<? extends Handler> handler) {
return path("", handler);
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler} if the
* relative {@code path} matches the given {@code path} exactly.
* <p>
* See {@link GroovyChain#path(String, ratpack.handling.Handler)} for more details.
*
* @param path the relative path to match exactly on
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain path(String path, @DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return path(path, groovyHandler(handler));
}
default GroovyChain path(@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return path("", handler);
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain post(String path, Handler handler) {
return from(Chain.super.post(path, handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain post(String path, Class<? extends Handler> handler) {
return post(path, getRegistry().get(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain post(Handler handler) {
return from(Chain.super.post(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain post(Class<? extends Handler> handler) {
return post(getRegistry().get(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler} if the
* relative {@code path} matches the given {@code path} and the {@code request} {@code HTTPMethod} is {@code POST}.
* <p>
* See {@link GroovyChain#post(String, ratpack.handling.Handler)} for more details.
*
* @param path the relative path to match on
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain post(String path, @DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return post(path, groovyHandler(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler}
* if the {@code request} {@code HTTPMethod} is {@code POST} and the {@code path} is at the current root.
* <p>
* See {@link GroovyChain#post(ratpack.handling.Handler)} for more details.
*
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain post(@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return post(groovyHandler(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain prefix(String prefix, Action<? super Chain> action) throws Exception {
return from(Chain.super.prefix(prefix, action));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain prefix(String prefix, Class<? extends Action<? super Chain>> action) throws Exception {
return prefix(prefix, getRegistry().get(action));
}
/**
* Creates a {@code List} of {@code Handler} from the given {@code Closure} and adds a {@code Handler} to
* this {@code GroovyChain} that delegates to the {@code Handler} list if the relative path starts with the given
* {@code prefix}.
* <p>
* See {@link Chain#prefix(String, ratpack.func.Action)} for more details.
*
* @param prefix the relative path to match on
* @param chain the definition of the chain to delegate to
* @return this {@code GroovyChain}
* @throws Exception any exception thrown by the given closure
*/
default GroovyChain prefix(String prefix, @DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> chain) throws Exception {
return prefix(prefix, chainAction(chain));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain put(String path, Handler handler) {
return from(Chain.super.put(path, handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain put(String path, Class<? extends Handler> handler) {
return put(path, getRegistry().get(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain put(Handler handler) {
return from(Chain.super.put(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain put(Class<? extends Handler> handler) {
return put(getRegistry().get(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler} if the
* relative {@code path} matches the given {@code path} and the {@code request} {@code HTTPMethod} is {@code PUT}.
* <p>
* See {@link GroovyChain#put(String, ratpack.handling.Handler)} for more details.
*
* @param path the relative path to match on
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain put(String path, @DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return put(path, groovyHandler(handler));
}
/**
* Adds a {@code Handler} to this {@code GroovyChain} that delegates to the given {@code Closure} as a {@code Handler}
* if the {@code request} {@code HTTPMethod} is {@code PUT} and the {@code path} is at the current root.
* <p>
* See {@link GroovyChain#put(ratpack.handling.Handler)} for more details.
*
* @param handler the handler to delegate to
* @return this {@code GroovyChain}
*/
default GroovyChain put(@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) {
return put(groovyHandler(handler));
}
/**
* {@inheritDoc}
*/
default GroovyChain redirect(int code, String location) {
return from(Chain.super.redirect(code, location));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain register(Registry registry) {
return from(Chain.super.register(registry));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain register(Action<? super RegistrySpec> action) throws Exception {
return from(Chain.super.register(action));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain register(Registry registry, Action<? super Chain> action) throws Exception {
return from(Chain.super.register(registry, action));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain register(Registry registry, Class<? extends Action<? super Chain>> action) throws Exception {
return register(registry, getRegistry().get(action));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain register(Action<? super RegistrySpec> registryAction, Action<? super Chain> chainAction) throws Exception {
return from(Chain.super.register(registryAction, chainAction));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain register(Action<? super RegistrySpec> registryAction, Class<? extends Action<? super Chain>> action) throws Exception {
return register(registryAction, getRegistry().get(action));
}
default GroovyChain register(Action<? super RegistrySpec> registryAction, @DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler) throws Exception {
return register(registryAction, chainAction(handler));
}
default GroovyChain register(Registry registry, @DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handlers) throws Exception {
return register(registry, chainAction(handlers));
}
default GroovyChain register(@DelegatesTo(value = RegistrySpec.class, strategy = Closure.DELEGATE_FIRST) Closure<?> closure) throws Exception {
return register(delegatingAction(closure));
}
@Override
default GroovyChain when(Predicate<? super Context> test, Action<? super Chain> action) throws Exception {
return from(Chain.super.when(test, action));
}
@Override
default GroovyChain when(Predicate<? super Context> test, Class<? extends Action<? super Chain>> action) throws Exception {
return from(Chain.super.when(test, action));
}
default GroovyChain when(
Predicate<? super Context> test,
@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handlers
) throws Exception {
return when(test, chainAction(handlers));
}
default GroovyChain when(
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> test,
@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handlers
) throws Exception {
return when(test, chainAction(handlers));
}
default GroovyChain when(
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> test,
Action<? super Chain> chain
) throws Exception {
return when(
ctx -> {
final GroovyContext groovyContext = GroovyContext.from(ctx);
return DefaultGroovyMethods.asBoolean(
ClosureUtil.cloneAndSetDelegate(groovyContext, test, Closure.DELEGATE_FIRST).isCase(groovyContext)
);
},
chain
);
}
default GroovyChain when(
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> test,
Class<? extends Action<? super Chain>> action
) throws Exception {
return when(test, getRegistry().get(action));
}
/**
* Inlines the given handlers if {@code test} is {@code true}.
* <p>
* This is literally just sugar for wrapping the given action in an {@code if} statement.
* It can be useful when conditionally adding handlers based on state available when building the chain.
*
* @param test whether to include the given chain action
* @param handlers the handlers to maybe include
* @return this
* @throws Exception any thrown by {@code action}
* @since 1.4
* @see Chain#when(boolean, Action)
*/
default GroovyChain when(boolean test, @DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handlers) throws Exception {
return when(test, chainAction(handlers));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain when(boolean test, Action<? super Chain> action) throws Exception {
return from(Chain.super.when(test, action));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain when(boolean test, Class<? extends Action<? super Chain>> action) throws Exception {
return from(Chain.super.when(test, action));
}
@Override
default GroovyChain when(Predicate<? super Context> test, Action<? super Chain> onTrue, Action<? super Chain> onFalse) throws Exception {
return from(Chain.super.when(test, onTrue, onFalse));
}
@Override
default GroovyChain when(Predicate<? super Context> test, Class<? extends Action<? super Chain>> onTrue, Class<? extends Action<? super Chain>> onFalse) throws Exception {
return from(Chain.super.when(test, onTrue, onFalse));
}
default GroovyChain when(
Predicate<? super Context> test,
@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> ifHandlers,
@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> elseHandlers
) throws Exception {
return when(test, chainAction(ifHandlers), chainAction(elseHandlers));
}
default GroovyChain when(
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> test,
@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> ifHandlers,
@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> elseHandlers
) throws Exception {
return when(test, chainAction(ifHandlers), chainAction(elseHandlers));
}
default GroovyChain when(
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> test,
Action<? super Chain> ifChain,
Action<? super Chain> elseChain
) throws Exception {
return when(
ctx -> {
final GroovyContext groovyContext = GroovyContext.from(ctx);
return DefaultGroovyMethods.asBoolean(
ClosureUtil.cloneAndSetDelegate(groovyContext, test, Closure.DELEGATE_FIRST).isCase(groovyContext)
);
},
ifChain,
elseChain
);
}
default GroovyChain when(
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> test,
Class<? extends Action<? super Chain>> ifAction,
Class<? extends Action<? super Chain>> elseAction
) throws Exception {
return when(test, getRegistry().get(ifAction), getRegistry().get(elseAction));
}
/**
* Inlines the appropriate handlers based on the given {@code test}.
* <p>
* A value of {@code true} will result in the given {@code ifHandlers} being used.
* A value of {@code false} will result in the given {@code elseHandlers} being used.
* <p>
* This is literally just sugar for wrapping the given action in an if/else statement.
* It can be useful when conditionally adding handlers based on state available when building the chain.
*
* @param test predicate to decide which handlers to include
* @param ifHandlers the handlers to include when the test is true
* @param elseHandlers the handlers to include when the test is false
* @return this
* @throws Exception any thrown by {@code action}
* @since 1.5
* @see Chain#when(boolean, Action, Action)
*/
default GroovyChain when(
boolean test,
@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> ifHandlers,
@DelegatesTo(value = GroovyChain.class, strategy = Closure.DELEGATE_FIRST) Closure<?> elseHandlers
) throws Exception {
return when(test, chainAction(ifHandlers), chainAction(elseHandlers));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain when(boolean test, Action<? super Chain> onTrue, Action<? super Chain> onFalse) throws Exception {
return from(Chain.super.when(test, onTrue, onFalse));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain when(boolean test, Class<? extends Action<? super Chain>> onTrue, Class<? extends Action<? super Chain>> onFalse) throws Exception {
return from(Chain.super.when(test, onTrue, onFalse));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain onlyIf(Predicate<? super Context> test, Handler handler) {
return from(Chain.super.onlyIf(test, handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain onlyIf(Predicate<? super Context> test, Class<? extends Handler> handler) {
return from(Chain.super.onlyIf(test, handler));
}
default GroovyChain onlyIf(
Predicate<? super Context> test,
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler
) {
return onlyIf(test, groovyHandler(handler));
}
default GroovyChain onlyIf(
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> test,
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> handler
) {
return onlyIf(test, groovyHandler(handler));
}
default GroovyChain onlyIf(
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> test,
Handler handler
) {
return onlyIf(
ctx -> {
final GroovyContext groovyContext = GroovyContext.from(ctx);
return DefaultGroovyMethods.asBoolean(
ClosureUtil.cloneAndSetDelegate(groovyContext, test, Closure.DELEGATE_FIRST).isCase(groovyContext)
);
},
handler
);
}
default GroovyChain onlyIf(
@DelegatesTo(value = GroovyContext.class, strategy = Closure.DELEGATE_FIRST) Closure<?> test,
Class<? extends Handler> handler
) {
return onlyIf(test, getRegistry().get(handler));
}
/**
* {@inheritDoc}
*/
@Override
default GroovyChain notFound() {
return from(Chain.super.notFound());
}
}