View Javadoc
1   package ca.uhn.fhir.util;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 - 2018 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
24  import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
25  import ca.uhn.fhir.context.FhirContext;
26  import ca.uhn.fhir.context.RuntimeResourceDefinition;
27  import ca.uhn.fhir.model.primitive.StringDt;
28  import org.apache.commons.lang3.StringUtils;
29  import org.apache.commons.lang3.Validate;
30  import org.hl7.fhir.instance.model.api.*;
31  
32  import java.util.ArrayList;
33  import java.util.Collection;
34  import java.util.List;
35  import java.util.Optional;
36  
37  /**
38   * Utilities for dealing with parameters resources in a version indepenedent way
39   */
40  public class ParametersUtil {
41  
42  	public static List<String> getNamedParameterValuesAsString(FhirContext theCtx, IBaseParameters theParameters, String theParameterName) {
43  		Validate.notNull(theParameters, "theParameters must not be null");
44  		RuntimeResourceDefinition resDef = theCtx.getResourceDefinition(theParameters.getClass());
45  		BaseRuntimeChildDefinition parameterChild = resDef.getChildByName("parameter");
46  		List<IBase> parameterReps = parameterChild.getAccessor().getValues(theParameters);
47  
48  		List<String> retVal = new ArrayList<>();
49  
50  		for (IBase nextParameter : parameterReps) {
51  			BaseRuntimeElementCompositeDefinition<?> nextParameterDef = (BaseRuntimeElementCompositeDefinition<?>) theCtx.getElementDefinition(nextParameter.getClass());
52  			BaseRuntimeChildDefinition nameChild = nextParameterDef.getChildByName("name");
53  			List<IBase> nameValues = nameChild.getAccessor().getValues(nextParameter);
54  			Optional<? extends IPrimitiveType<?>> nameValue = nameValues
55  				.stream()
56  				.filter(t -> t instanceof IPrimitiveType<?>)
57  				.map(t -> ((IPrimitiveType<?>) t))
58  				.findFirst();
59  			if (!nameValue.isPresent() || !theParameterName.equals(nameValue.get().getValueAsString())) {
60  				continue;
61  			}
62  
63  			BaseRuntimeChildDefinition valueChild = nextParameterDef.getChildByName("value[x]");
64  			List<IBase> valueValues = valueChild.getAccessor().getValues(nextParameter);
65  			valueValues
66  				.stream()
67  				.filter(t->t instanceof IPrimitiveType<?>)
68  				.map(t->((IPrimitiveType<?>)t).getValueAsString())
69  				.filter(StringUtils::isNotBlank)
70  				.forEach(retVal::add);
71  
72  		}
73  
74  		return retVal;
75  	}
76  
77  	private static void addClientParameter(FhirContext theContext, Object theValue, IBaseResource theTargetResource, BaseRuntimeChildDefinition paramChild, BaseRuntimeElementCompositeDefinition<?> paramChildElem, String theName) {
78  		if (theValue instanceof IBaseResource) {
79  			IBase parameter = createParameterRepetition(theContext, theTargetResource, paramChild, paramChildElem, theName);
80  			paramChildElem.getChildByName("resource").getMutator().addValue(parameter, (IBaseResource) theValue);
81  		} else if (theValue instanceof IBaseDatatype) {
82  			IBase parameter = createParameterRepetition(theContext, theTargetResource, paramChild, paramChildElem, theName);
83  			paramChildElem.getChildByName("value[x]").getMutator().addValue(parameter, (IBaseDatatype) theValue);
84  		} else if (theValue instanceof Collection) {
85  			Collection<?> collection = (Collection<?>) theValue;
86  			for (Object next : collection) {
87  				addClientParameter(theContext, next, theTargetResource, paramChild, paramChildElem, theName);
88  			}
89  		} else {
90  			throw new IllegalArgumentException("Don't know how to handle value of type " + theValue.getClass() + " for paramater " + theName);
91  		}
92  	}
93  
94  	/**
95  	 * Add a paratemer value to a Parameters resource
96  	 *
97  	 * @param theContext    The FhirContext
98  	 * @param theParameters The Parameters resource
99  	 * @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 }