001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.aop;
017
018import com.jfinal.aop.Aop;
019import com.jfinal.aop.Interceptor;
020import com.jfinal.aop.InterceptorManager;
021import io.jboot.utils.ClassUtil;
022
023import java.util.ArrayList;
024import java.util.Comparator;
025import java.util.List;
026import java.util.function.Predicate;
027import java.util.stream.Collectors;
028
029/**
030 * @author michael yang (fuhai999@gmail.com)
031 */
032public class Interceptors {
033
034    private List<InterceptorWarpper> warppers = new ArrayList<>();
035
036    private int minimalWeight = 1;
037    private int currentWeight = 1;
038
039    public Interceptors() {
040    }
041
042    public Interceptors(Interceptor[] inters) {
043        if (inters != null && inters.length > 0) {
044            for (Interceptor interceptor : inters) {
045                add(interceptor);
046            }
047        }
048    }
049
050    public void add(Interceptor interceptor) {
051        warppers.add(new InterceptorWarpper(interceptor, currentWeight++));
052    }
053
054    public void add(Class<? extends Interceptor> interceptorClass) {
055        add(singleton(interceptorClass));
056    }
057
058    public void add(Interceptor interceptor, int weight) {
059        warppers.add(new InterceptorWarpper(interceptor, weight));
060    }
061
062    public void add(Class<? extends Interceptor> interceptorClass, int weight) {
063        add(singleton(interceptorClass), weight);
064    }
065
066
067    public void addIfNotExist(Interceptor interceptor) {
068        if (!contains(interceptor)) {
069            add(interceptor);
070        }
071    }
072
073    public void addIfNotExist(Class<? extends Interceptor> interceptorClass) {
074        if (!contains(interceptorClass)) {
075            add(singleton(interceptorClass));
076        }
077    }
078
079
080    public void addToFirst(Interceptor interceptor) {
081        warppers.add(new InterceptorWarpper(interceptor, --minimalWeight));
082    }
083
084    public void addToFirst(Class<? extends Interceptor> interceptorClass) {
085        addToFirst(singleton(interceptorClass));
086    }
087
088
089    public void addToFirstIfNotExist(Interceptor interceptor) {
090        if (!contains(interceptor)) {
091            warppers.add(new InterceptorWarpper(interceptor, --minimalWeight));
092        }
093    }
094
095    public void addToFirstIfNotExist(Class<? extends Interceptor> interceptorClass) {
096        if (!contains(interceptorClass)) {
097            addToFirst(singleton(interceptorClass));
098        }
099    }
100
101    public boolean addBefore(Interceptor interceptor, Predicate<? super Interceptor> filter) {
102        Integer weight = null;
103        for (InterceptorWarpper warpper : warppers) {
104            if (filter.test(warpper.interceptor)) {
105                weight = warpper.weight;
106                break;
107            }
108        }
109
110        //所有在 新加 的拦截器往前推 1
111        if (weight != null) {
112            for (InterceptorWarpper warpper : warppers) {
113                if (warpper.weight < weight) {
114                    warpper.weight--;
115                }
116            }
117            minimalWeight--;
118            warppers.add(new InterceptorWarpper(interceptor, --weight));
119            return true;
120        } else {
121            return false;
122        }
123    }
124
125    public boolean addBefore(Class<? extends Interceptor> interceptorClass, Predicate<? super Interceptor> filter) {
126        return addBefore(singleton(interceptorClass), filter);
127    }
128
129    public boolean addBefore(Interceptor interceptor, Class<? extends Interceptor> toClass) {
130        return addBefore(interceptor, interceptor1 -> interceptor1.getClass() == toClass);
131    }
132
133    public boolean addBefore(Class<? extends Interceptor> interceptorClass, Class<? extends Interceptor> toClass) {
134        return addBefore(singleton(interceptorClass), toClass);
135    }
136
137
138    public boolean addAfter(Interceptor interceptor, Predicate<? super Interceptor> filter) {
139        Integer weight = null;
140        for (InterceptorWarpper warpper : warppers) {
141            if (filter.test(warpper.interceptor)) {
142                weight = warpper.weight;
143                break;
144            }
145        }
146
147        //所有在 新加 的拦截器往后推 1
148        if (weight != null) {
149            for (InterceptorWarpper warpper : warppers) {
150                if (warpper.weight > weight) {
151                    warpper.weight++;
152                }
153            }
154            currentWeight++;
155            warppers.add(new InterceptorWarpper(interceptor, ++weight));
156            return true;
157        } else {
158            return false;
159        }
160    }
161
162    public boolean addAfter(Class<? extends Interceptor> interceptorClass, Predicate<? super Interceptor> filter) {
163        return addAfter(singleton(interceptorClass), filter);
164    }
165
166
167    public boolean addAfter(Interceptor interceptor, Class<? extends Interceptor> toClass) {
168        return addAfter(interceptor, interceptor1 -> interceptor1.getClass() == toClass);
169    }
170
171
172    public boolean addAfter(Class<? extends Interceptor> interceptorClass, Class<? extends Interceptor> toClass) {
173        return addAfter(singleton(interceptorClass), toClass);
174    }
175
176
177    public boolean remove(Interceptor interceptor) {
178        return warppers.removeIf(interceptorWarpper -> interceptorWarpper.interceptor == interceptor);
179    }
180
181
182    public boolean remove(Predicate<? super Interceptor> predicate) {
183        return warppers.removeIf(warpper -> predicate.test(warpper.interceptor));
184    }
185
186
187    public boolean remove(Class<? extends Interceptor> clazz) {
188        return warppers.removeIf(interceptorWarpper -> interceptorWarpper.interceptor.getClass() == clazz);
189    }
190
191
192    public Integer getWeight(Interceptor interceptor) {
193        for (InterceptorWarpper warpper : warppers) {
194            if (warpper.interceptor == interceptor) {
195                return warpper.weight;
196            }
197        }
198        return null;
199    }
200
201
202    public Integer getWeight(Class<? extends Interceptor> clazz) {
203        for (InterceptorWarpper warpper : warppers) {
204            if (warpper.interceptor.getClass() == clazz) {
205                return warpper.weight;
206            }
207        }
208        return null;
209    }
210
211
212    public List<Interceptor> toList() {
213        // 排序:weight 越小越靠前
214        warppers.sort(Comparator.comparingInt(InterceptorWarpper::getWeight));
215        return warppers.stream().map(InterceptorWarpper::getInterceptor)
216                .collect(Collectors.toList());
217    }
218
219
220    public Interceptor[] toArray() {
221        if (warppers == null || warppers.size() == 0) {
222            return InterceptorManager.NULL_INTERS;
223        } else {
224            // 排序:weight 越小越靠前
225            warppers.sort(Comparator.comparingInt(InterceptorWarpper::getWeight));
226
227            Interceptor[] inters = new Interceptor[warppers.size()];
228            for (int i = 0; i < warppers.size(); i++) {
229                inters[i] = warppers.get(i).getInterceptor();
230            }
231            return inters;
232        }
233    }
234
235
236    public boolean contains(Interceptor interceptor) {
237        for (InterceptorWarpper warpper : warppers) {
238            if (warpper.interceptor == interceptor) {
239                return true;
240            }
241        }
242        return false;
243    }
244
245
246    public boolean contains(Class<? extends Interceptor> clazz) {
247        for (InterceptorWarpper warpper : warppers) {
248            if (warpper.interceptor.getClass() == clazz) {
249                return true;
250            }
251        }
252        return false;
253    }
254
255
256    public int getMinimalWeight() {
257        return minimalWeight;
258    }
259
260    public int getCurrentWeight() {
261        return currentWeight;
262    }
263
264
265    private Interceptor singleton(Class<? extends Interceptor> interceptorClass) {
266        return ClassUtil.singleton(interceptorClass, false);
267    }
268
269    public List<InterceptorWarpper> getWarppers() {
270        return warppers;
271    }
272
273    static class InterceptorWarpper {
274
275        private Interceptor interceptor;
276        private int weight;
277
278        public InterceptorWarpper(Interceptor interceptor, int weight) {
279            this.interceptor = Aop.inject(interceptor);
280            this.weight = weight;
281        }
282
283        public Interceptor getInterceptor() {
284            return interceptor;
285        }
286
287        public void setInterceptor(Interceptor interceptor) {
288            this.interceptor = interceptor;
289        }
290
291        public int getWeight() {
292            return weight;
293        }
294
295        public void setWeight(int weight) {
296            this.weight = weight;
297        }
298    }
299
300}