001package ca.uhn.fhir.util; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2018 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 ca.uhn.fhir.context.BaseRuntimeChildDefinition; 024import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; 025import ca.uhn.fhir.context.FhirContext; 026import ca.uhn.fhir.context.RuntimeResourceDefinition; 027import ca.uhn.fhir.model.primitive.StringDt; 028import org.apache.commons.lang3.StringUtils; 029import org.apache.commons.lang3.Validate; 030import org.hl7.fhir.instance.model.api.*; 031 032import java.util.ArrayList; 033import java.util.Collection; 034import java.util.List; 035import java.util.Optional; 036 037/** 038 * Utilities for dealing with parameters resources in a version indepenedent way 039 */ 040public class ParametersUtil { 041 042 public static List<String> getNamedParameterValuesAsString(FhirContext theCtx, IBaseParameters theParameters, String theParameterName) { 043 Validate.notNull(theParameters, "theParameters must not be null"); 044 RuntimeResourceDefinition resDef = theCtx.getResourceDefinition(theParameters.getClass()); 045 BaseRuntimeChildDefinition parameterChild = resDef.getChildByName("parameter"); 046 List<IBase> parameterReps = parameterChild.getAccessor().getValues(theParameters); 047 048 List<String> retVal = new ArrayList<>(); 049 050 for (IBase nextParameter : parameterReps) { 051 BaseRuntimeElementCompositeDefinition<?> nextParameterDef = (BaseRuntimeElementCompositeDefinition<?>) theCtx.getElementDefinition(nextParameter.getClass()); 052 BaseRuntimeChildDefinition nameChild = nextParameterDef.getChildByName("name"); 053 List<IBase> nameValues = nameChild.getAccessor().getValues(nextParameter); 054 Optional<? extends IPrimitiveType<?>> nameValue = nameValues 055 .stream() 056 .filter(t -> t instanceof IPrimitiveType<?>) 057 .map(t -> ((IPrimitiveType<?>) t)) 058 .findFirst(); 059 if (!nameValue.isPresent() || !theParameterName.equals(nameValue.get().getValueAsString())) { 060 continue; 061 } 062 063 BaseRuntimeChildDefinition valueChild = nextParameterDef.getChildByName("value[x]"); 064 List<IBase> valueValues = valueChild.getAccessor().getValues(nextParameter); 065 valueValues 066 .stream() 067 .filter(t->t instanceof IPrimitiveType<?>) 068 .map(t->((IPrimitiveType<?>)t).getValueAsString()) 069 .filter(StringUtils::isNotBlank) 070 .forEach(retVal::add); 071 072 } 073 074 return retVal; 075 } 076 077 private static void addClientParameter(FhirContext theContext, Object theValue, IBaseResource theTargetResource, BaseRuntimeChildDefinition paramChild, BaseRuntimeElementCompositeDefinition<?> paramChildElem, String theName) { 078 if (theValue instanceof IBaseResource) { 079 IBase parameter = createParameterRepetition(theContext, theTargetResource, paramChild, paramChildElem, theName); 080 paramChildElem.getChildByName("resource").getMutator().addValue(parameter, (IBaseResource) theValue); 081 } else if (theValue instanceof IBaseDatatype) { 082 IBase parameter = createParameterRepetition(theContext, theTargetResource, paramChild, paramChildElem, theName); 083 paramChildElem.getChildByName("value[x]").getMutator().addValue(parameter, (IBaseDatatype) theValue); 084 } else if (theValue instanceof Collection) { 085 Collection<?> collection = (Collection<?>) theValue; 086 for (Object next : collection) { 087 addClientParameter(theContext, next, theTargetResource, paramChild, paramChildElem, theName); 088 } 089 } else { 090 throw new IllegalArgumentException("Don't know how to handle value of type " + theValue.getClass() + " for parameter " + theName); 091 } 092 } 093 094 /** 095 * Add a paratemer value to a Parameters resource 096 * 097 * @param theContext The FhirContext 098 * @param theParameters The Parameters resource 099 * @param theName The parametr name 100 * @param theValue The parameter value (can be a {@link IBaseResource resource} or a {@link IBaseDatatype datatype}) 101 */ 102 public static void addParameterToParameters(FhirContext theContext, IBaseParameters theParameters, String theName, Object theValue) { 103 RuntimeResourceDefinition def = theContext.getResourceDefinition(theParameters); 104 BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter"); 105 BaseRuntimeElementCompositeDefinition<?> paramChildElem = (BaseRuntimeElementCompositeDefinition<?>) paramChild.getChildByName("parameter"); 106 107 addClientParameter(theContext, theValue, theParameters, paramChild, paramChildElem, theName); 108 } 109 110 private static IBase createParameterRepetition(FhirContext theContext, IBaseResource theTargetResource, BaseRuntimeChildDefinition paramChild, BaseRuntimeElementCompositeDefinition<?> paramChildElem, String theName) { 111 IBase parameter = paramChildElem.newInstance(); 112 paramChild.getMutator().addValue(theTargetResource, parameter); 113 IPrimitiveType<?> value; 114 value = createString(theContext, theName); 115 paramChildElem.getChildByName("name").getMutator().addValue(parameter, value); 116 return parameter; 117 } 118 119 public static IPrimitiveType<?> createString(FhirContext theContext, String theValue) { 120 IPrimitiveType<?> value; 121 if (theContext.getVersion().getVersion().isRi()) { 122 value = (IPrimitiveType<?>) theContext.getElementDefinition("string").newInstance(theValue); 123 } else { 124 value = new StringDt(theValue); 125 } 126 return value; 127 } 128 129 public static IBaseParameters newInstance(FhirContext theContext) { 130 Validate.notNull(theContext, "theContext must not be null"); 131 return (IBaseParameters) theContext.getResourceDefinition("Parameters").newInstance(); 132 } 133 134}