001/** 002 * Copyright (C) 2006-2021 Talend Inc. - www.talend.com 003 * 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 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 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 org.talend.sdk.component.api.service.interceptor; 017 018import java.lang.annotation.Annotation; 019import java.lang.reflect.Method; 020import java.util.Optional; 021import java.util.stream.Stream; 022 023/** 024 * The hook used to implement an interceptor. 025 * It can be associated to a {@link Intercepts} 026 * marker. 027 * 028 * IMPORTANT: if you want a delegate instance you have to provide a constructor 029 * taking an object as parameter. Alternatively you can use a {@literal BiFunction<Method, Object[], Object>} 030 * constructor parameter to be able to delegate the invocation. Else you must provide a default constructor. 031 * 032 * NOTE: if your interceptor doesn't take an invoker as parameter 033 * ({@literal java.util.function.BiFunction<Method, Object[], Object>}) 034 * then the interceptor chain can be broken if you invoke yourself a method. It is recommended to respect it. 035 */ 036public interface InterceptorHandler { 037 038 /** 039 * Called instead of the delegate method. 040 * 041 * @param method th emethod being invoked. 042 * @param args the parameters of the method. 043 * @return the returned value of the method. 044 */ 045 Object invoke(Method method, Object[] args); 046 047 default <T extends Annotation> Optional<T> findAnnotation(final Method method, final Class<T> type) { 048 return Optional 049 .ofNullable((T) Stream 050 .of(method.getAnnotations()) 051 .filter(a -> a.annotationType() == type) 052 .findFirst() 053 .orElseGet(() -> Stream 054 .of(method.getDeclaringClass().getAnnotations()) 055 .filter(a -> a.annotationType() == type) 056 .findFirst() 057 .orElse(null))); 058 } 059}