001package ca.uhn.fhir.rest.server.method; 002 003/* 004 * #%L 005 * HAPI FHIR - Server Framework 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 */ 022import ca.uhn.fhir.i18n.Msg; 023import static org.apache.commons.lang3.StringUtils.isBlank; 024 025import java.lang.reflect.Method; 026import java.util.*; 027 028import ca.uhn.fhir.context.ConfigurationException; 029import ca.uhn.fhir.rest.api.Constants; 030import ca.uhn.fhir.rest.api.SummaryEnum; 031import ca.uhn.fhir.rest.api.server.RequestDetails; 032import ca.uhn.fhir.rest.param.binder.CollectionBinder; 033import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; 034import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; 035 036public class SummaryEnumParameter implements IParameter { 037 038 @SuppressWarnings("rawtypes") 039 private Class<? extends Collection> myInnerCollectionType; 040 041 042 @Override 043 @SuppressWarnings({ "rawtypes", "unchecked" }) 044 public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { 045 Set<SummaryEnum> value = getSummaryValueOrNull(theRequest); 046 if (value == null || value.isEmpty()) { 047 return null; 048 } 049 050 if (myInnerCollectionType == null) { 051 return value.iterator().next(); 052 } 053 054 try { 055 Collection retVal = myInnerCollectionType.newInstance(); 056 retVal.addAll(value); 057 return retVal; 058 } catch (InstantiationException e) { 059 throw new InternalErrorException(Msg.code(378) + "Failed to instantiate " + myInnerCollectionType, e); 060 } catch (IllegalAccessException e) { 061 throw new InternalErrorException(Msg.code(379) + "Failed to instantiate " + myInnerCollectionType, e); 062 } 063 } 064 065 public static Set<SummaryEnum> getSummaryValueOrNull(RequestDetails theRequest) { 066 String[] summary = theRequest.getParameters().get(Constants.PARAM_SUMMARY); 067 068 Set<SummaryEnum> retVal; 069 if (summary == null || summary.length == 0) { 070 retVal = null; 071 } else if (isBlank(summary[0])) { 072 retVal = null; 073 } else if (summary.length == 1 && summary[0].indexOf(',') == -1) { 074 retVal = toCollectionOrNull(SummaryEnum.fromCode(summary[0])); 075 if (retVal == null) { 076 retVal = toCollectionOrNull(SummaryEnum.fromCode(summary[0].toLowerCase())); 077 } 078 } else { 079 retVal = new HashSet<>(); 080 for (String nextParamValue : summary) { 081 for (String nextParamValueTok : nextParamValue.split(",")) { 082 SummaryEnum value = SummaryEnum.fromCode(nextParamValueTok); 083 if (value == null) { 084 value = SummaryEnum.fromCode(nextParamValueTok.toLowerCase()); 085 } 086 if (value != null) { 087 retVal.add(value); 088 } 089 } 090 } 091 } 092 093 if (retVal != null) { 094 if (retVal.contains(SummaryEnum.TEXT)) { 095 if (retVal.size() > 1) { 096 String msg = theRequest.getServer().getFhirContext().getLocalizer().getMessage(SummaryEnumParameter.class, "cantCombineText"); 097 throw new InvalidRequestException(Msg.code(380) + msg); 098 } 099 } 100 } 101 102 return retVal; 103 } 104 105 private static Set<SummaryEnum> toCollectionOrNull(SummaryEnum theFromCode) { 106 if (theFromCode == null) { 107 return null; 108 } 109 return Collections.singleton(theFromCode); 110 } 111 112 @Override 113 public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) { 114 if (theOuterCollectionType != null) { 115 throw new ConfigurationException(Msg.code(381) + "Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of type " + SummaryEnum.class + " but can not be a collection of collections"); 116 } 117 if (theInnerCollectionType != null) { 118 myInnerCollectionType = CollectionBinder.getInstantiableCollectionType(theInnerCollectionType, SummaryEnum.class.getSimpleName()); 119 } 120 } 121 122}