From f47551fc6fa3a163be19c90560be4de5fb2f9650 Mon Sep 17 00:00:00 2001 From: jeffcheasey88 <66554203+jeffcheasey88@users.noreply.github.com> Date: Thu, 1 May 2025 20:20:21 +0200 Subject: [PATCH] RouteInterceptor -> Add possibility to associate an interceptor with specific Route(s) --- src/dev/peerat/framework/RouteBinder.java | 72 +++++++++++++++++++++++ src/dev/peerat/framework/RouteFilter.java | 10 ++++ src/dev/peerat/framework/RouteMapper.java | 12 ++++ src/dev/peerat/framework/RouteState.java | 12 ++++ src/dev/peerat/framework/Router.java | 5 ++ 5 files changed, 111 insertions(+) create mode 100644 src/dev/peerat/framework/RouteBinder.java create mode 100644 src/dev/peerat/framework/RouteFilter.java diff --git a/src/dev/peerat/framework/RouteBinder.java b/src/dev/peerat/framework/RouteBinder.java new file mode 100644 index 0000000..8d24518 --- /dev/null +++ b/src/dev/peerat/framework/RouteBinder.java @@ -0,0 +1,72 @@ +package dev.peerat.framework; + +import java.lang.reflect.Method; +import java.util.regex.Matcher; + +public class RouteBinder{ + + //TODO interceptor -------> bind to a specific route, no all routes ? or both. Could be interesting for somes cases ! + + private Class[] types; + private int[] bindMethod; + private int parameterCount; + + public RouteBinder(){} + + public void bind(Class... types){ + if(this.types == null){ + this.types = types; + this.parameterCount = this.types.length; + return; + } + Class[] copy = new Class[this.types.length+types.length]; + System.arraycopy(this.types, 0, copy, 0, this.types.length); + System.arraycopy(types, 0, copy, this.types.length, types.length); + this.types = copy; + this.parameterCount = this.types.length; + } + + public void bindIndexes(Method method){ + Class[] parameters = method.getParameterTypes(); + this.bindMethod = new int[4+(types == null ? 0 : types.length)]; + this.bindMethod[0] = findIndex(parameters, Matcher.class); + this.bindMethod[1] = findIndex(parameters, Context.class); + this.bindMethod[2] = findIndex(parameters, HttpReader.class); + this.bindMethod[3] = findIndex(parameters, HttpWriter.class); + if(this.types == null) return; + for(int i = 0; i < this.types.length; i++){ + this.bindMethod[4+i] = findIndex(parameters, this.types[i]); + } + this.types = null; + } + + public int getParameterCount(){ + return this.parameterCount; + } + + public Object[] bindMethod(Method method, Matcher matcher, Context context, HttpReader reader, HttpWriter writer, Object[] objects){ + Object[] result = new Object[method.getParameterCount()]; + setElement(result, bindMethod[0], matcher); + setElement(result, bindMethod[1], context); + setElement(result, bindMethod[2], reader); + setElement(result, bindMethod[3], writer); + for(int i = 0; i < objects.length; i++){ + setElement(result, bindMethod[4+i], objects[i]); + } + return result; + } + + private void setElement(Object[] array, int position, Object element){ + if(position < 0) return; + array[position] = element; + } + + private int findIndex(Class[] array, Class type){ + for(int i = 0; i < array.length; i++){ + Class clazz = array[i]; + if(type.isAssignableFrom(clazz)) return i; + } + return -1; + } + +} diff --git a/src/dev/peerat/framework/RouteFilter.java b/src/dev/peerat/framework/RouteFilter.java new file mode 100644 index 0000000..174821c --- /dev/null +++ b/src/dev/peerat/framework/RouteFilter.java @@ -0,0 +1,10 @@ +package dev.peerat.framework; + +import java.lang.reflect.Method; +import java.util.regex.Pattern; + +public interface RouteFilter{ + + boolean accept(Method method, Route route, Pattern pattern); + +} diff --git a/src/dev/peerat/framework/RouteMapper.java b/src/dev/peerat/framework/RouteMapper.java index a684fdf..d9fc465 100644 --- a/src/dev/peerat/framework/RouteMapper.java +++ b/src/dev/peerat/framework/RouteMapper.java @@ -27,6 +27,12 @@ public class RouteMapper{ if(this.calls != null) this.calls = new int[length]; } + public void addInterceptor(RouteFilter filter, RouteInterceptor interceptor){ + for(RouteState state : this.states){ + if(filter.accept(state.getMethod(), state.getRoute(), state.getPattern())) state.addInterceptor(interceptor); + } + } + public void bind(RouteFilter filter, Class... types){ for(RouteState state : this.states){ if(filter.accept(state.getMethod(), state.getRoute(), state.getPattern())) state.getBinder().bind(types); @@ -77,6 +83,12 @@ public class RouteMapper{ for(RouteInterceptor interceptor : interceptors){ if(!interceptor.intercept(matcher, context, reader, writer, target.getMethod(), params)) return true; } + List localInterceptors = target.getInterceptors(); + if(localInterceptors != null){ + for(RouteInterceptor interceptor : localInterceptors){ + if(!interceptor.intercept(matcher, context, reader, writer, target.getMethod(), params)) return true; + } + } Object[] inv = target.getBinder().bindMethod(target.getMethod(), matcher, context, reader, writer, params); target.getMethod().invoke(target.getInstance(), inv); return true; diff --git a/src/dev/peerat/framework/RouteState.java b/src/dev/peerat/framework/RouteState.java index 7ac0d97..32adcfe 100644 --- a/src/dev/peerat/framework/RouteState.java +++ b/src/dev/peerat/framework/RouteState.java @@ -1,6 +1,8 @@ package dev.peerat.framework; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -11,6 +13,7 @@ public class RouteState { private Route route; private Pattern pattern; private RouteBinder binder; + private List interceptors; //TODO concat interceptors ?? public RouteState(Object instance, Method method, Route route){ this.instance = instance; @@ -29,6 +32,15 @@ public class RouteState { return matcher.matches() ? matcher : null; } + public void addInterceptor(RouteInterceptor interceptor){ + if(this.interceptors == null) this.interceptors = new ArrayList<>(); + this.interceptors.add(interceptor); + } + + public List getInterceptors(){ + return this.interceptors; + } + public Route getRoute(){ return this.route; } diff --git a/src/dev/peerat/framework/Router.java b/src/dev/peerat/framework/Router.java index 257a753..d17839a 100644 --- a/src/dev/peerat/framework/Router.java +++ b/src/dev/peerat/framework/Router.java @@ -135,6 +135,11 @@ public class Router{ return this; } + public Router addInterceptor(RouteFilter filter, RouteInterceptor interceptor){ + for(RouteMapper mapper : this.mappers) mapper.addInterceptor(filter, interceptor); + return this; + } + public Router bind(RouteFilter filter, Class... types){ for(RouteMapper mapper : this.mappers) mapper.bind(filter, types); return this;