package org.webpieces.router.impl; import java.lang.reflect.Method; import java.util.concurrent.CompletableFuture; import org.webpieces.router.api.actions.Action; import org.webpieces.router.api.dto.MethodMeta; import org.webpieces.util.filters.Filter; import org.webpieces.util.filters.Service; public class ChainFilters { public static Service<MethodMeta, Action> addOnTop(Service<MethodMeta, Action> svc, Filter<MethodMeta, Action> filter) { return new ServiceFilterProxy(svc, filter); } private static class ServiceFilterProxy implements Service<MethodMeta, Action> { private Service<MethodMeta, Action> svc; private Filter<MethodMeta, Action> filter; public ServiceFilterProxy(Service<MethodMeta, Action> svc, Filter<MethodMeta, Action> filter) { this.svc = svc; this.filter = filter; } @Override public CompletableFuture<Action> invoke(MethodMeta meta) { Method method = meta.getMethod(); CompletableFuture<Action> resp = filter.filter(meta, svc).thenApply((r) -> responseCheck(method, r)); if(resp == null) throw new IllegalStateException("Filter returned null CompletableFuture<Action> which is not allowed="+filter.getClass()+" after being given request with controller method="+method); return resp; } private Action responseCheck(Method method, Action resp) { if(resp == null) throw new IllegalStateException("Filter returned CompletableFuture<Action> where the Action resolved to null which is not allowed="+filter.getClass()+" after being given request with controller method="+method); return resp; } @Override public String toString() { return filter +"->"+svc; } } }