View Javadoc
1   package ca.uhn.fhir.jpa.provider.dstu3;
2   
3   /*
4    * #%L
5    * HAPI FHIR JPA Server
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.RuntimeResourceDefinition;
24  import ca.uhn.fhir.context.RuntimeSearchParam;
25  import ca.uhn.fhir.jpa.dao.DaoConfig;
26  import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
27  import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
28  import ca.uhn.fhir.rest.server.RestfulServer;
29  import ca.uhn.fhir.util.CoverageIgnore;
30  import ca.uhn.fhir.util.ExtensionConstants;
31  import org.hl7.fhir.dstu3.model.*;
32  import org.hl7.fhir.dstu3.model.CapabilityStatement.*;
33  import org.hl7.fhir.dstu3.model.Enumerations.SearchParamType;
34  
35  import javax.servlet.http.HttpServletRequest;
36  import java.util.Collection;
37  import java.util.Collections;
38  import java.util.Map;
39  
40  import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
41  
42  public class JpaConformanceProviderDstu3 extends org.hl7.fhir.dstu3.hapi.rest.server.ServerCapabilityStatementProvider {
43  
44  	private volatile CapabilityStatement myCachedValue;
45  	private DaoConfig myDaoConfig;
46  	private ISearchParamRegistry mySearchParamRegistry;
47  	private String myImplementationDescription;
48  	private boolean myIncludeResourceCounts;
49  	private RestfulServer myRestfulServer;
50  	private IFhirSystemDao<Bundle, Meta> mySystemDao;
51  	/**
52  	 * Constructor
53  	 */
54  	@CoverageIgnore
55  	public JpaConformanceProviderDstu3() {
56  		super();
57  		super.setCache(false);
58  		setIncludeResourceCounts(true);
59  	}
60  
61  	/**
62  	 * Constructor
63  	 */
64  	public JpaConformanceProviderDstu3(RestfulServer theRestfulServer, IFhirSystemDao<Bundle, Meta> theSystemDao, DaoConfig theDaoConfig) {
65  		super(theRestfulServer);
66  		myRestfulServer = theRestfulServer;
67  		mySystemDao = theSystemDao;
68  		myDaoConfig = theDaoConfig;
69  		super.setCache(false);
70  		setSearchParamRegistry(theSystemDao.getSearchParamRegistry());
71  		setIncludeResourceCounts(true);
72  	}
73  
74  	public void setSearchParamRegistry(ISearchParamRegistry theSearchParamRegistry) {
75  		mySearchParamRegistry = theSearchParamRegistry;
76  	}
77  
78  	@Override
79  	public CapabilityStatement getServerConformance(HttpServletRequest theRequest) {
80  		CapabilityStatement retVal = myCachedValue;
81  
82  		Map<String, Long> counts = null;
83  		if (myIncludeResourceCounts) {
84  			counts = mySystemDao.getResourceCountsFromCache();
85  		}
86  		counts = defaultIfNull(counts, Collections.emptyMap());
87  
88  		retVal = super.getServerConformance(theRequest);
89  		for (CapabilityStatementRestComponent nextRest : retVal.getRest()) {
90  
91  			for (CapabilityStatementRestResourceComponent nextResource : nextRest.getResource()) {
92  
93  				nextResource.setVersioning(ResourceVersionPolicy.VERSIONEDUPDATE);
94  
95  				ConditionalDeleteStatus conditionalDelete = nextResource.getConditionalDelete();
96  				if (conditionalDelete == ConditionalDeleteStatus.MULTIPLE && myDaoConfig.isAllowMultipleDelete() == false) {
97  					nextResource.setConditionalDelete(ConditionalDeleteStatus.SINGLE);
98  				}
99  
100 				// Add resource counts
101 				Long count = counts.get(nextResource.getTypeElement().getValueAsString());
102 				if (count != null) {
103 					nextResource.addExtension(new Extension(ExtensionConstants.CONF_RESOURCE_COUNT, new DecimalType(count)));
104 				}
105 
106 				nextResource.getSearchParam().clear();
107 				String resourceName = nextResource.getType();
108 				RuntimeResourceDefinition resourceDef = myRestfulServer.getFhirContext().getResourceDefinition(resourceName);
109 				Collection<RuntimeSearchParam> searchParams = mySearchParamRegistry.getSearchParamsByResourceType(resourceDef);
110 				for (RuntimeSearchParam runtimeSp : searchParams) {
111 					CapabilityStatementRestResourceSearchParamComponent confSp = nextResource.addSearchParam();
112 
113 					confSp.setName(runtimeSp.getName());
114 					confSp.setDocumentation(runtimeSp.getDescription());
115 					confSp.setDefinition(runtimeSp.getUri());
116 					switch (runtimeSp.getParamType()) {
117 						case COMPOSITE:
118 							confSp.setType(SearchParamType.COMPOSITE);
119 							break;
120 						case DATE:
121 							confSp.setType(SearchParamType.DATE);
122 							break;
123 						case NUMBER:
124 							confSp.setType(SearchParamType.NUMBER);
125 							break;
126 						case QUANTITY:
127 							confSp.setType(SearchParamType.QUANTITY);
128 							break;
129 						case REFERENCE:
130 							confSp.setType(SearchParamType.REFERENCE);
131 							break;
132 						case STRING:
133 							confSp.setType(SearchParamType.STRING);
134 							break;
135 						case TOKEN:
136 							confSp.setType(SearchParamType.TOKEN);
137 							break;
138 						case URI:
139 							confSp.setType(SearchParamType.URI);
140 							break;
141 						case HAS:
142 							// Shouldn't happen
143 							break;
144 					}
145 
146 				}
147 
148 			}
149 		}
150 
151 		massage(retVal);
152 
153 		retVal.getImplementation().setDescription(myImplementationDescription);
154 		myCachedValue = retVal;
155 		return retVal;
156 	}
157 
158 	public boolean isIncludeResourceCounts() {
159 		return myIncludeResourceCounts;
160 	}
161 
162 	public void setIncludeResourceCounts(boolean theIncludeResourceCounts) {
163 		myIncludeResourceCounts = theIncludeResourceCounts;
164 	}
165 
166 	/**
167 	 * Subclasses may override
168 	 */
169 	protected void massage(CapabilityStatement theStatement) {
170 		// nothing
171 	}
172 
173 	public void setDaoConfig(DaoConfig myDaoConfig) {
174 		this.myDaoConfig = myDaoConfig;
175 	}
176 
177 	@CoverageIgnore
178 	public void setImplementationDescription(String theImplDesc) {
179 		myImplementationDescription = theImplDesc;
180 	}
181 
182 	@Override
183 	public void setRestfulServer(RestfulServer theRestfulServer) {
184 		this.myRestfulServer = theRestfulServer;
185 		super.setRestfulServer(theRestfulServer);
186 	}
187 
188 	@CoverageIgnore
189 	public void setSystemDao(IFhirSystemDao<Bundle, Meta> mySystemDao) {
190 		this.mySystemDao = mySystemDao;
191 	}
192 }