View Javadoc
1   package ca.uhn.fhir.rest.param;
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  import static org.apache.commons.lang3.StringUtils.isBlank;
23  import static org.apache.commons.lang3.StringUtils.isNotBlank;
24  
25  import java.math.BigDecimal;
26  
27  import org.apache.commons.lang3.builder.ToStringBuilder;
28  import org.apache.commons.lang3.builder.ToStringStyle;
29  import org.hl7.fhir.instance.model.api.IBaseResource;
30  
31  import ca.uhn.fhir.context.FhirContext;
32  import ca.uhn.fhir.model.primitive.IdDt;
33  import ca.uhn.fhir.util.CoverageIgnore;
34  
35  public class ReferenceParam extends BaseParam /*implements IQueryParameterType*/ {
36  
37  	private String myChain;
38  
39  	private final IdDt myId = new IdDt();
40  	/**
41  	 * Constructor
42  	 */
43  	public ReferenceParam() {
44  		super();
45  	}
46  
47  	/**
48  	 * Constructor
49  	 */
50  	public ReferenceParam(String theValue) {
51  		setValueAsQueryToken(null, null, null, theValue);
52  	}
53  
54  	/**
55  	 * Constructor
56  	 */
57  	public ReferenceParam(String theChain, String theValue) {
58  		setValueAsQueryToken(null, null, null, theValue);
59  		setChain(theChain);
60  	}
61  
62  	/**
63  	 * Constructor
64  	 */
65  	public ReferenceParam(String theResourceType, String theChain, String theValue) {
66  		if (isNotBlank(theResourceType)) {
67  			setValue(theResourceType + "/" + theValue);
68  		} else {
69  			setValue(theValue);
70  		}
71  		setChain(theChain);
72  	}
73  
74  	@Override
75  	String doGetQueryParameterQualifier() {
76  		StringBuilder b = new StringBuilder();
77  		if (isNotBlank(myChain)) {
78  			if (isNotBlank(getResourceType())) {
79  				b.append(':');
80  				b.append(getResourceType());
81  			}
82  			b.append('.');
83  			b.append(myChain);
84  		}
85  		if (b.length() != 0) {
86  			return b.toString();
87  		}
88  		return null;
89  	}
90  
91  	@Override
92  	String doGetValueAsQueryToken(FhirContext theContext) {
93  		if (isBlank(myId.getResourceType())) {
94  			return myId.getValue(); // e.g. urn:asdjd or 123 or cid:wieiuru or #1
95  		} else {
96  			if (isBlank(getChain())) {
97  				return getResourceType() + "/" + myId.getIdPart();
98  			}
99  			return myId.getIdPart();
100 		}
101 	}
102 
103 	@Override
104 	void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
105 		String q = theQualifier;
106 		String resourceType = null;
107 		boolean skipSetValue = false;
108 		if (isNotBlank(q)) {
109 			if (q.startsWith(":")) {
110 				int nextIdx = q.indexOf('.');
111 				if (nextIdx != -1) {
112 					resourceType = q.substring(1, nextIdx);
113 					myChain = q.substring(nextIdx + 1);
114 					// type is explicitly defined so use it
115 					myId.setParts(null, resourceType, theValue, null);
116 					skipSetValue = true;
117 				} else {
118 					resourceType = q.substring(1);
119 				}
120 			} else if (q.startsWith(".")) {
121 				myChain = q.substring(1);
122 				// type not defined but this is a chain, so treat value as opaque
123 				myId.setParts(null, null, theValue, null);
124 				skipSetValue = true;
125 			}
126 		}
127 
128 		if (!skipSetValue) {
129 			setValue(theValue);
130 
131 			if (isNotBlank(resourceType) && isBlank(getResourceType())) {
132 				setValue(resourceType + '/' + theValue);
133 			}
134 		}
135 	}
136 
137 
138 
139 	@CoverageIgnore
140 	public String getBaseUrl() {
141 		return myId.getBaseUrl();
142 	}
143 
144 
145 	public String getChain() {
146 		return myChain;
147 	}
148 
149 
150 	@CoverageIgnore
151 	public String getIdPart() {
152 		return myId.getIdPart();
153 	}
154 
155 	@CoverageIgnore
156 	public BigDecimal getIdPartAsBigDecimal() {
157 		return myId.getIdPartAsBigDecimal();
158 	}
159 	
160 	@CoverageIgnore
161 	public Long getIdPartAsLong() {
162 		return myId.getIdPartAsLong();
163 	}
164 
165 	public String getResourceType() {
166 		return myId.getResourceType();
167 	}
168 
169 	public Class<? extends IBaseResource> getResourceType(FhirContext theCtx) {
170 		if (isBlank(getResourceType())) {
171 			return null;
172 		}
173 		return theCtx.getResourceDefinition(getResourceType()).getImplementingClass();
174 	}
175 
176 	public String getValue() {
177 		return myId.getValue();
178 	}
179 
180 	public boolean hasResourceType() {
181 		return myId.hasResourceType();
182 	}
183 
184 	@Override
185 	protected boolean isSupportsChain() {
186 		return true;
187 	}
188 
189 	public ReferenceParam setChain(String theChain) {
190 		myChain = theChain;
191 		return this;
192 	}
193 
194 	public ReferenceParam setValue(String theValue) {
195 		myId.setValue(theValue);
196 		return this;
197 	}
198 
199 	/**
200 	 * Returns a new param containing the same value as this param, but with the type copnverted
201 	 * to {@link DateParam}. This is useful if you are using reference parameters and want to handle
202 	 * chained parameters of different types in a single method.
203 	 * <p>
204 	 * See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
205 	 * in the HAPI FHIR documentation for an example of how to use this method.
206 	 * </p>
207 	 */
208 	public DateParam toDateParam(FhirContext theContext) {
209 		DateParam retVal = new DateParam();
210 		retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
211 		return retVal;
212 	}
213 
214 	/**
215 	 * Returns a new param containing the same value as this param, but with the type copnverted
216 	 * to {@link NumberParam}. This is useful if you are using reference parameters and want to handle
217 	 * chained parameters of different types in a single method.
218 	 * <p>
219 	 * See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
220 	 * in the HAPI FHIR documentation for an example of how to use this method.
221 	 * </p>
222 	 */
223 	public NumberParam toNumberParam(FhirContext theContext) {
224 		NumberParam retVal = new NumberParam();
225 		retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
226 		return retVal;
227 	}
228 
229 	/**
230 	 * Returns a new param containing the same value as this param, but with the type copnverted
231 	 * to {@link QuantityParam}. This is useful if you are using reference parameters and want to handle
232 	 * chained parameters of different types in a single method.
233 	 * <p>
234 	 * See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
235 	 * in the HAPI FHIR documentation for an example of how to use this method.
236 	 * </p>
237 	 */
238 	public QuantityParam toQuantityParam(FhirContext theContext) {
239 		QuantityParam retVal = new QuantityParam();
240 		retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
241 		return retVal;
242 	}
243 
244 	@Override
245 	public String toString() {
246 		ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
247 		if (isNotBlank(myChain)) {
248 			b.append("chain", myChain);
249 		}
250 		b.append("value", getValue());
251 		return b.build();
252 	}
253 
254 	/**
255 	 * Returns a new param containing the same value as this param, but with the type copnverted
256 	 * to {@link StringParam}. This is useful if you are using reference parameters and want to handle
257 	 * chained parameters of different types in a single method.
258 	 * <p>
259 	 * See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
260 	 * in the HAPI FHIR documentation for an example of how to use this method.
261 	 * </p>
262 	 */
263 	public StringParam toStringParam(FhirContext theContext) {
264 		StringParam retVal = new StringParam();
265 		retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
266 		return retVal;
267 	}
268 
269 	/**
270 	 * Returns a new param containing the same value as this param, but with the type copnverted
271 	 * to {@link TokenParam}. This is useful if you are using reference parameters and want to handle
272 	 * chained parameters of different types in a single method.
273 	 * <p>
274 	 * See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
275 	 * in the HAPI FHIR documentation for an example of how to use this method.
276 	 * </p>
277 	 */
278 	public TokenParam toTokenParam(FhirContext theContext) {
279 		TokenParam retVal = new TokenParam();
280 		retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
281 		return retVal;
282 	}
283 }