001/*- 002 * #%L 003 * HAPI FHIR - Core Library 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.interceptor.api; 021 022import com.google.common.collect.ArrayListMultimap; 023import com.google.common.collect.ListMultimap; 024import com.google.common.collect.Multimaps; 025import jakarta.annotation.Nonnull; 026import org.apache.commons.lang3.Validate; 027 028import java.util.Collection; 029import java.util.Collections; 030import java.util.List; 031import java.util.function.Supplier; 032import java.util.stream.Collectors; 033 034public class HookParams { 035 036 private ListMultimap<Class<?>, Object> myParams = ArrayListMultimap.create(); 037 038 /** 039 * Constructor 040 */ 041 public HookParams() {} 042 043 /** 044 * Constructor 045 */ 046 public HookParams(Object... theParams) { 047 for (Object next : theParams) { 048 add(next); 049 } 050 } 051 052 @SuppressWarnings("unchecked") 053 public <T> HookParams add(@Nonnull T theNext) { 054 Class<T> nextClass = (Class<T>) theNext.getClass(); 055 add(nextClass, theNext); 056 return this; 057 } 058 059 public <T> HookParams add(Class<T> theType, T theParam) { 060 return doAdd(theType, theParam); 061 } 062 063 // /** 064 // * This is useful for providing a lazy-loaded (generally expensive to create) 065 // * parameters 066 // */ 067 // public <T> HookParams addSupplier(Class<T> theType, Supplier<T> theParam) { 068 // return doAdd(theType, theParam); 069 // } 070 071 private <T> HookParams doAdd(Class<T> theType, Object theParam) { 072 Validate.isTrue(theType.equals(Supplier.class) == false, "Can not add parameters of type Supplier"); 073 myParams.put(theType, theParam); 074 return this; 075 } 076 077 public <T> T get(Class<T> theParamType) { 078 return get(theParamType, 0); 079 } 080 081 @SuppressWarnings("unchecked") 082 public <T> T get(Class<T> theParamType, int theIndex) { 083 List<Object> objects = myParams.get(theParamType); 084 Object retVal = null; 085 if (objects.size() > theIndex) { 086 retVal = objects.get(theIndex); 087 } 088 089 retVal = unwrapValue(retVal); 090 091 return (T) retVal; 092 } 093 094 private Object unwrapValue(Object theValue) { 095 if (theValue instanceof Supplier) { 096 theValue = ((Supplier) theValue).get(); 097 } 098 return theValue; 099 } 100 101 /** 102 * Returns an unmodifiable multimap of the params, where the 103 * key is the param type and the value is the actual instance 104 */ 105 public ListMultimap<Class<?>, Object> getParamsForType() { 106 ArrayListMultimap<Class<?>, Object> retVal = ArrayListMultimap.create(); 107 myParams.entries().forEach(entry -> retVal.put(entry.getKey(), unwrapValue(entry.getValue()))); 108 return Multimaps.unmodifiableListMultimap(retVal); 109 } 110 111 public Collection<Object> values() { 112 return Collections.unmodifiableCollection(myParams.values()).stream() 113 .map(t -> unwrapValue(t)) 114 .collect(Collectors.toList()); 115 } 116 117 @SuppressWarnings("unchecked") 118 public <T> HookParams addIfMatchesType(Class<T> theType, Object theParam) { 119 if (theParam == null) { 120 add(theType, null); 121 } else { 122 if (theType.isAssignableFrom(theParam.getClass())) { 123 T param = (T) theParam; 124 add(theType, param); 125 } else { 126 add(theType, null); 127 } 128 } 129 return this; 130 } 131 132 @Override 133 public String toString() { 134 StringBuilder b = new StringBuilder(); 135 myParams.forEach((key, value) -> { 136 b.append(" ") 137 .append(key.getSimpleName()) 138 .append(": ") 139 .append(value) 140 .append("\n"); 141 }); 142 return b.toString(); 143 } 144}