
001package ca.uhn.fhir.interceptor.api; 002 003/*- 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import com.google.common.collect.ArrayListMultimap; 024import com.google.common.collect.ListMultimap; 025import com.google.common.collect.Multimaps; 026import org.apache.commons.lang3.Validate; 027import org.apache.commons.lang3.builder.ToStringBuilder; 028import org.apache.commons.lang3.builder.ToStringStyle; 029 030import javax.annotation.Nonnull; 031import java.util.Collection; 032import java.util.Collections; 033import java.util.List; 034import java.util.function.Supplier; 035import java.util.stream.Collectors; 036 037public class HookParams { 038 039 private ListMultimap<Class<?>, Object> myParams = ArrayListMultimap.create(); 040 041 /** 042 * Constructor 043 */ 044 public HookParams() { 045 } 046 047 /** 048 * Constructor 049 */ 050 public HookParams(Object... theParams) { 051 for (Object next : theParams) { 052 add(next); 053 } 054 } 055 056 @SuppressWarnings("unchecked") 057 public <T> HookParams add(@Nonnull T theNext) { 058 Class<T> nextClass = (Class<T>) theNext.getClass(); 059 add(nextClass, theNext); 060 return this; 061 } 062 063 public <T> HookParams add(Class<T> theType, T theParam) { 064 return doAdd(theType, theParam); 065 } 066 067// /** 068// * This is useful for providing a lazy-loaded (generally expensive to create) 069// * parameters 070// */ 071// public <T> HookParams addSupplier(Class<T> theType, Supplier<T> theParam) { 072// return doAdd(theType, theParam); 073// } 074 075 private <T> HookParams doAdd(Class<T> theType, Object theParam) { 076 Validate.isTrue(theType.equals(Supplier.class) == false, "Can not add parameters of type Supplier"); 077 myParams.put(theType, theParam); 078 return this; 079 } 080 081 public <T> T get(Class<T> theParamType) { 082 return get(theParamType, 0); 083 } 084 085 @SuppressWarnings("unchecked") 086 public <T> T get(Class<T> theParamType, int theIndex) { 087 List<Object> objects = myParams.get(theParamType); 088 Object retVal = null; 089 if (objects.size() > theIndex) { 090 retVal = objects.get(theIndex); 091 } 092 093 retVal = unwrapValue(retVal); 094 095 return (T) retVal; 096 } 097 098 private Object unwrapValue(Object theValue) { 099 if (theValue instanceof Supplier) { 100 theValue = ((Supplier) theValue).get(); 101 } 102 return theValue; 103 } 104 105 /** 106 * Returns an unmodifiable multimap of the params, where the 107 * key is the param type and the value is the actual instance 108 */ 109 public ListMultimap<Class<?>, Object> getParamsForType() { 110 ArrayListMultimap<Class<?>, Object> retVal = ArrayListMultimap.create(); 111 myParams.entries().forEach(entry -> retVal.put(entry.getKey(), unwrapValue(entry.getValue()))); 112 return Multimaps.unmodifiableListMultimap(retVal); 113 } 114 115 public Collection<Object> values() { 116 return 117 Collections.unmodifiableCollection(myParams.values()) 118 .stream() 119 .map(t -> unwrapValue(t)) 120 .collect(Collectors.toList()); 121 } 122 123 @SuppressWarnings("unchecked") 124 public <T> HookParams addIfMatchesType(Class<T> theType, Object theParam) { 125 if (theParam == null) { 126 add(theType, null); 127 } else { 128 if (theType.isAssignableFrom(theParam.getClass())) { 129 T param = (T) theParam; 130 add(theType, param); 131 } else { 132 add(theType, null); 133 } 134 } 135 return this; 136 } 137 138 @Override 139 public String toString() { 140 return new ToStringBuilder(this, ToStringStyle.SIMPLE_STYLE) 141 .append("params", myParams) 142 .toString(); 143 } 144}