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