001/*-
002 * #%L
003 * HAPI FHIR - Core Library
004 * %%
005 * Copyright (C) 2014 - 2023 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.interceptor.executor;
021
022import ca.uhn.fhir.interceptor.api.Hook;
023import ca.uhn.fhir.interceptor.api.HookParams;
024import ca.uhn.fhir.interceptor.api.IAnonymousInterceptor;
025import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
026import ca.uhn.fhir.interceptor.api.IInterceptorService;
027import ca.uhn.fhir.interceptor.api.Interceptor;
028import ca.uhn.fhir.interceptor.api.Pointcut;
029import com.google.common.annotations.VisibleForTesting;
030import org.apache.commons.lang3.Validate;
031
032import java.lang.reflect.Method;
033import java.util.Optional;
034
035public class InterceptorService extends BaseInterceptorService<Pointcut> implements IInterceptorService, IInterceptorBroadcaster {
036
037        /**
038         * Constructor which uses a default name of "default"
039         */
040        public InterceptorService() {
041                this("default");
042        }
043
044        /**
045         * Constructor
046         *
047         * @param theName The name for this registry (useful for troubleshooting)
048         */
049        public InterceptorService(String theName) {
050                super(Pointcut.class, theName);
051        }
052
053        @Override
054        protected Optional<HookDescriptor> scanForHook(Method nextMethod) {
055                return findAnnotation(nextMethod, Hook.class).map(t -> new HookDescriptor(t.value(), t.order()));
056        }
057
058
059        @Override
060        @VisibleForTesting
061        public void registerAnonymousInterceptor(Pointcut thePointcut, IAnonymousInterceptor theInterceptor) {
062                registerAnonymousInterceptor(thePointcut, Interceptor.DEFAULT_ORDER, theInterceptor);
063        }
064
065        @Override
066        public void registerAnonymousInterceptor(Pointcut thePointcut, int theOrder, IAnonymousInterceptor theInterceptor) {
067                Validate.notNull(thePointcut);
068                Validate.notNull(theInterceptor);
069                BaseInvoker invoker = new AnonymousLambdaInvoker(thePointcut, theInterceptor, theOrder);
070                registerAnonymousInterceptor(thePointcut, theInterceptor, invoker);
071        }
072
073
074        private static class AnonymousLambdaInvoker extends BaseInvoker {
075                private final IAnonymousInterceptor myHook;
076                private final Pointcut myPointcut;
077
078                public AnonymousLambdaInvoker(Pointcut thePointcut, IAnonymousInterceptor theHook, int theOrder) {
079                        super(theHook, theOrder);
080                        myHook = theHook;
081                        myPointcut = thePointcut;
082                }
083
084                @Override
085                Object invoke(HookParams theParams) {
086                        myHook.invoke(myPointcut, theParams);
087                        return true;
088                }
089        }
090
091
092}