View Javadoc
1   package ca.uhn.fhir.jpa.provider.dstu3;
2   
3   /*
4    * #%L
5    * HAPI FHIR JPA Server
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.jpa.dao.IFhirResourceDaoValueSet;
24  import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult;
25  import ca.uhn.fhir.jpa.util.JpaConstants;
26  import ca.uhn.fhir.rest.annotation.IdParam;
27  import ca.uhn.fhir.rest.annotation.Operation;
28  import ca.uhn.fhir.rest.annotation.OperationParam;
29  import ca.uhn.fhir.rest.api.server.RequestDetails;
30  import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
31  import org.hl7.fhir.dstu3.model.*;
32  
33  import javax.servlet.http.HttpServletRequest;
34  
35  import static org.apache.commons.lang3.StringUtils.isNotBlank;
36  
37  public class BaseJpaResourceProviderValueSetDstu3 extends JpaResourceProviderDstu3<ValueSet> {
38  
39  	@Operation(name = JpaConstants.OPERATION_EXPAND, idempotent = true)
40  	public ValueSet expand(
41  		HttpServletRequest theServletRequest,
42  		@IdParam(optional = true) IdType theId,
43  		@OperationParam(name = "valueSet", min = 0, max = 1) ValueSet theValueSet,
44  		// Note: url is correct and identifier is not, but identifier was only added as
45  		// of 3.1.0 so we'll leave url for now. See: https://groups.google.com/d/msgid/hapi-fhir/CAN2Cfy8kW%2BAOkgC6VjPsU3gRCpExCNZBmJdi-k5R_TWeyWH4tA%40mail.gmail.com?utm_medium=email&utm_source=footer
46  		@OperationParam(name = "url", min = 0, max = 1) UriType theUrl,
47  		@OperationParam(name = "identifier", min = 0, max = 1) UriType theIdentifier,
48  		@OperationParam(name = "filter", min = 0, max = 1) StringType theFilter,
49  		RequestDetails theRequestDetails) {
50  
51  		boolean haveId = theId != null && theId.hasIdPart();
52  		UriType url = theIdentifier;
53  		if (theUrl != null && isNotBlank(theUrl.getValue())) {
54  			url = theUrl;
55  		}
56  
57  		boolean haveIdentifier = url != null && isNotBlank(url.getValue());
58  		boolean haveValueSet = theValueSet != null && theValueSet.isEmpty() == false;
59  
60  		if (!haveId && !haveIdentifier && !haveValueSet) {
61  			throw new InvalidRequestException("$expand operation at the type level (no ID specified) requires an identifier or a valueSet as a part of the request");
62  		}
63  
64  		if (moreThanOneTrue(haveId, haveIdentifier, haveValueSet)) {
65  			throw new InvalidRequestException("$expand must EITHER be invoked at the instance level, or have an identifier specified, or have a ValueSet specified. Can not combine these options.");
66  		}
67  
68  		startRequest(theServletRequest);
69  		try {
70  			IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> dao = (IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept>) getDao();
71  			if (haveId) {
72  				return dao.expand(theId, toFilterString(theFilter), theRequestDetails);
73  			} else if (haveIdentifier) {
74  				return dao.expandByIdentifier(url.getValue(), toFilterString(theFilter));
75  			} else {
76  				return dao.expand(theValueSet, toFilterString(theFilter));
77  			}
78  
79  		} finally {
80  			endRequest(theServletRequest);
81  		}
82  	}
83  
84  
85  	private String toFilterString(StringType theFilter) {
86  		return theFilter != null ? theFilter.getValue() : null;
87  	}
88  
89  
90  	@SuppressWarnings("unchecked")
91  	@Operation(name = JpaConstants.OPERATION_VALIDATE_CODE, idempotent = true, returnParameters = {
92  		@OperationParam(name = "result", type = BooleanType.class, min = 1),
93  		@OperationParam(name = "message", type = StringType.class),
94  		@OperationParam(name = "display", type = StringType.class)
95  	})
96  	public Parameters validateCode(
97  		HttpServletRequest theServletRequest,
98  		@IdParam(optional = true) IdType theId,
99  		@OperationParam(name = "identifier", min = 0, max = 1) UriType theValueSetIdentifier,
100 		@OperationParam(name = "url", min = 0, max = 1) UriType theValueSetUrl,
101 		@OperationParam(name = "code", min = 0, max = 1) CodeType theCode,
102 		@OperationParam(name = "system", min = 0, max = 1) UriType theSystem,
103 		@OperationParam(name = "display", min = 0, max = 1) StringType theDisplay,
104 		@OperationParam(name = "coding", min = 0, max = 1) Coding theCoding,
105 		@OperationParam(name = "codeableConcept", min = 0, max = 1) CodeableConcept theCodeableConcept,
106 		RequestDetails theRequestDetails
107 	) {
108 
109 		UriType url = theValueSetIdentifier;
110 		if (theValueSetUrl != null && isNotBlank(theValueSetUrl.getValue())) {
111 			url = theValueSetUrl;
112 		}
113 
114 		startRequest(theServletRequest);
115 		try {
116 			IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> dao = (IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept>) getDao();
117 			ValidateCodeResult result = dao.validateCode(url, theId, theCode, theSystem, theDisplay, theCoding, theCodeableConcept, theRequestDetails);
118 			Parameters retVal = new Parameters();
119 			retVal.addParameter().setName("result").setValue(new BooleanType(result.isResult()));
120 			if (isNotBlank(result.getMessage())) {
121 				retVal.addParameter().setName("message").setValue(new StringType(result.getMessage()));
122 			}
123 			if (isNotBlank(result.getDisplay())) {
124 				retVal.addParameter().setName("display").setValue(new StringType(result.getDisplay()));
125 			}
126 			return retVal;
127 		} finally {
128 			endRequest(theServletRequest);
129 		}
130 	}
131 
132 
133 	private static boolean moreThanOneTrue(boolean... theBooleans) {
134 		boolean haveOne = false;
135 		for (boolean next : theBooleans) {
136 			if (next) {
137 				if (haveOne) {
138 					return true;
139 				} else {
140 					haveOne = true;
141 				}
142 			}
143 		}
144 		return false;
145 	}
146 
147 
148 }