View Javadoc
1   package ca.uhn.fhir.util;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 - 2019 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.*;
24  import ca.uhn.fhir.model.primitive.StringDt;
25  import org.apache.commons.lang3.StringUtils;
26  import org.apache.commons.lang3.Validate;
27  import org.hl7.fhir.instance.model.api.*;
28  
29  import java.util.ArrayList;
30  import java.util.Collection;
31  import java.util.List;
32  import java.util.Optional;
33  
34  /**
35   * Utilities for dealing with parameters resources in a version indepenedent way
36   */
37  public class ParametersUtil {
38  
39  	public static List<String> getNamedParameterValuesAsString(FhirContext theCtx, IBaseParameters theParameters, String theParameterName) {
40  		Validate.notNull(theParameters, "theParameters must not be null");
41  		RuntimeResourceDefinition resDef = theCtx.getResourceDefinition(theParameters.getClass());
42  		BaseRuntimeChildDefinition parameterChild = resDef.getChildByName("parameter");
43  		List<IBase> parameterReps = parameterChild.getAccessor().getValues(theParameters);
44  
45  		List<String> retVal = new ArrayList<>();
46  
47  		for (IBase nextParameter : parameterReps) {
48  			BaseRuntimeElementCompositeDefinition<?> nextParameterDef = (BaseRuntimeElementCompositeDefinition<?>) theCtx.getElementDefinition(nextParameter.getClass());
49  			BaseRuntimeChildDefinition nameChild = nextParameterDef.getChildByName("name");
50  			List<IBase> nameValues = nameChild.getAccessor().getValues(nextParameter);
51  			Optional<? extends IPrimitiveType<?>> nameValue = nameValues
52  				.stream()
53  				.filter(t -> t instanceof IPrimitiveType<?>)
54  				.map(t -> ((IPrimitiveType<?>) t))
55  				.findFirst();
56  			if (!nameValue.isPresent() || !theParameterName.equals(nameValue.get().getValueAsString())) {
57  				continue;
58  			}
59  
60  			BaseRuntimeChildDefinition valueChild = nextParameterDef.getChildByName("value[x]");
61  			List<IBase> valueValues = valueChild.getAccessor().getValues(nextParameter);
62  			valueValues
63  				.stream()
64  				.filter(t->t instanceof IPrimitiveType<?>)
65  				.map(t->((IPrimitiveType<?>)t).getValueAsString())
66  				.filter(StringUtils::isNotBlank)
67  				.forEach(retVal::add);
68  
69  		}
70  
71  		return retVal;
72  	}
73  
74  	private static void addClientParameter(FhirContext theContext, Object theValue, IBaseResource theTargetResource, BaseRuntimeChildDefinition paramChild, BaseRuntimeElementCompositeDefinition<?> paramChildElem, String theName) {
75  		if (theValue instanceof IBaseResource) {
76  			IBase parameter = createParameterRepetition(theContext, theTargetResource, paramChild, paramChildElem, theName);
77  			paramChildElem.getChildByName("resource").getMutator().addValue(parameter, (IBaseResource) theValue);
78  		} else if (theValue instanceof IBaseDatatype) {
79  			IBase parameter = createParameterRepetition(theContext, theTargetResource, paramChild, paramChildElem, theName);
80  			paramChildElem.getChildByName("value[x]").getMutator().addValue(parameter, (IBaseDatatype) theValue);
81  		} else if (theValue instanceof Collection) {
82  			Collection<?> collection = (Collection<?>) theValue;
83  			for (Object next : collection) {
84  				addClientParameter(theContext, next, theTargetResource, paramChild, paramChildElem, theName);
85  			}
86  		} else {
87  			throw new IllegalArgumentException("Don't know how to handle value of type " + theValue.getClass() + " for parameter " + theName);
88  		}
89  	}
90  
91  	/**
92  	 * Add a paratemer value to a Parameters resource
93  	 *
94  	 * @param theContext    The FhirContext
95  	 * @param theParameters The Parameters resource
96  	 * @param theName       The parametr name
97  	 * @param theValue      The parameter value (can be a {@link IBaseResource resource} or a {@link IBaseDatatype datatype})
98  	 */
99  	public static void addParameterToParameters(FhirContext theContext, IBaseParameters theParameters, String theName, Object theValue) {
100 		RuntimeResourceDefinition def = theContext.getResourceDefinition(theParameters);
101 		BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter");
102 		BaseRuntimeElementCompositeDefinition<?> paramChildElem = (BaseRuntimeElementCompositeDefinition<?>) paramChild.getChildByName("parameter");
103 
104 		addClientParameter(theContext, theValue, theParameters, paramChild, paramChildElem, theName);
105 	}
106 
107 	/**
108 	 * Add a paratemer value to a Parameters resource
109 	 *
110 	 * @param theContext    The FhirContext
111 	 * @param theParameters The Parameters resource
112 	 * @param theName       The parameter name
113 	 * @param thePrimitiveDatatype The datatype, e.g. "string", or "uri"
114 	 * @param theValue The value
115 	 */
116 	public static void addParameterToParameters(FhirContext theContext, IBaseParameters theParameters, String theName, String thePrimitiveDatatype, String theValue) {
117 		Validate.notBlank(thePrimitiveDatatype, "thePrimitiveDatatype must not be null or empty");
118 
119 		BaseRuntimeElementDefinition<?> datatypeDef = theContext.getElementDefinition(thePrimitiveDatatype);
120 		IPrimitiveType<?> value = (IPrimitiveType<?>) datatypeDef.newInstance();
121 		value.setValueAsString(theValue);
122 
123 		addParameterToParameters(theContext, theParameters, theName, value);
124 	}
125 
126 	private static IBase createParameterRepetition(FhirContext theContext, IBaseResource theTargetResource, BaseRuntimeChildDefinition paramChild, BaseRuntimeElementCompositeDefinition<?> paramChildElem, String theName) {
127 		IBase parameter = paramChildElem.newInstance();
128 		paramChild.getMutator().addValue(theTargetResource, parameter);
129 		IPrimitiveType<?> value;
130 		value = createString(theContext, theName);
131 		paramChildElem.getChildByName("name").getMutator().addValue(parameter, value);
132 		return parameter;
133 	}
134 
135 	public static IPrimitiveType<?> createString(FhirContext theContext, String theValue) {
136 		IPrimitiveType<?> value;
137 		if (theContext.getVersion().getVersion().isRi()) {
138 			value = (IPrimitiveType<?>) theContext.getElementDefinition("string").newInstance(theValue);
139 		} else {
140 			value = new StringDt(theValue);
141 		}
142 		return value;
143 	}
144 
145 	public static IBaseParameters newInstance(FhirContext theContext) {
146 		Validate.notNull(theContext, "theContext must not be null");
147 		return (IBaseParameters) theContext.getResourceDefinition("Parameters").newInstance();
148 	}
149 
150 }