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