001/*- 002 * #%L 003 * HAPI FHIR - Server Framework 004 * %% 005 * Copyright (C) 2014 - 2024 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.rest.server.util; 021 022import ca.uhn.fhir.interceptor.api.HookParams; 023import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; 024import ca.uhn.fhir.interceptor.api.Pointcut; 025import ca.uhn.fhir.rest.api.server.RequestDetails; 026import jakarta.annotation.Nullable; 027 028public class CompositeInterceptorBroadcaster { 029 030 /** 031 * Non instantiable 032 */ 033 private CompositeInterceptorBroadcaster() { 034 // nothing 035 } 036 037 /** 038 * Broadcast hooks to both the interceptor service associated with the request, as well 039 * as the one associated with the JPA module. 040 */ 041 public static boolean doCallHooks( 042 IInterceptorBroadcaster theInterceptorBroadcaster, 043 @Nullable RequestDetails theRequestDetails, 044 Pointcut thePointcut, 045 HookParams theParams) { 046 return newCompositeBroadcaster(theInterceptorBroadcaster, theRequestDetails) 047 .callHooks(thePointcut, theParams); 048 } 049 050 /** 051 * Broadcast hooks to both the interceptor service associated with the request, as well 052 * as the one associated with the JPA module. 053 */ 054 public static Object doCallHooksAndReturnObject( 055 IInterceptorBroadcaster theInterceptorBroadcaster, 056 RequestDetails theRequestDetails, 057 Pointcut thePointcut, 058 HookParams theParams) { 059 return newCompositeBroadcaster(theInterceptorBroadcaster, theRequestDetails) 060 .callHooksAndReturnObject(thePointcut, theParams); 061 } 062 063 // TODO: JA - Refactor to make thePointcut the last argument in order to be consistent with thr other methods here 064 public static boolean hasHooks( 065 Pointcut thePointcut, IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequestDetails) { 066 return newCompositeBroadcaster(theInterceptorBroadcaster, theRequestDetails) 067 .hasHooks(thePointcut); 068 } 069 070 /** 071 * @since 5.5.0 072 */ 073 public static IInterceptorBroadcaster newCompositeBroadcaster( 074 IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequestDetails) { 075 return new IInterceptorBroadcaster() { 076 @Override 077 public boolean callHooks(Pointcut thePointcut, HookParams theParams) { 078 boolean retVal = true; 079 if (theInterceptorBroadcaster != null) { 080 retVal = theInterceptorBroadcaster.callHooks(thePointcut, theParams); 081 } 082 if (theRequestDetails != null && theRequestDetails.getInterceptorBroadcaster() != null && retVal) { 083 IInterceptorBroadcaster interceptorBroadcaster = theRequestDetails.getInterceptorBroadcaster(); 084 interceptorBroadcaster.callHooks(thePointcut, theParams); 085 } 086 return retVal; 087 } 088 089 @Override 090 public Object callHooksAndReturnObject(Pointcut thePointcut, HookParams theParams) { 091 Object retVal = true; 092 if (theInterceptorBroadcaster != null) { 093 retVal = theInterceptorBroadcaster.callHooksAndReturnObject(thePointcut, theParams); 094 } 095 if (theRequestDetails != null 096 && theRequestDetails.getInterceptorBroadcaster() != null 097 && retVal == null) { 098 IInterceptorBroadcaster interceptorBroadcaster = theRequestDetails.getInterceptorBroadcaster(); 099 retVal = interceptorBroadcaster.callHooksAndReturnObject(thePointcut, theParams); 100 } 101 return retVal; 102 } 103 104 @Override 105 public boolean hasHooks(Pointcut thePointcut) { 106 if (theInterceptorBroadcaster != null && theInterceptorBroadcaster.hasHooks(thePointcut)) { 107 return true; 108 } 109 return theRequestDetails != null 110 && theRequestDetails.getInterceptorBroadcaster() != null 111 && theRequestDetails.getInterceptorBroadcaster().hasHooks(thePointcut); 112 } 113 }; 114 } 115}