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