View Javadoc
1   package ca.uhn.fhir.jpa.sp;
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 java.util.*;
24  import java.util.Map.Entry;
25  import java.util.concurrent.ConcurrentHashMap;
26  
27  import ca.uhn.fhir.jpa.dao.DaoConfig;
28  import org.apache.commons.lang3.tuple.Pair;
29  import org.springframework.beans.factory.annotation.Autowired;
30  
31  import ca.uhn.fhir.jpa.dao.data.ISearchParamDao;
32  import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
33  import ca.uhn.fhir.jpa.entity.ResourceTable;
34  import ca.uhn.fhir.jpa.entity.SearchParam;
35  import ca.uhn.fhir.jpa.entity.SearchParamPresent;
36  
37  public class SearchParamPresenceSvcImpl implements ISearchParamPresenceSvc {
38  
39  	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamPresenceSvcImpl.class);
40  
41  	private Map<Pair<String, String>, SearchParam> myResourceTypeToSearchParamToEntity = new ConcurrentHashMap<Pair<String, String>, SearchParam>();
42  
43  	@Autowired
44  	private ISearchParamDao mySearchParamDao;
45  
46  	@Autowired
47  	private ISearchParamPresentDao mySearchParamPresentDao;
48  
49  	@Autowired
50  	private DaoConfig myDaoConfig;
51  
52  	@Override
53  	public void updatePresence(ResourceTable theResource, Map<String, Boolean> theParamNameToPresence) {
54  		if (myDaoConfig.getIndexMissingFields() == DaoConfig.IndexEnabledEnum.DISABLED) {
55  			return;
56  		}
57  
58  		Map<String, Boolean> presenceMap = new HashMap<String, Boolean>(theParamNameToPresence);
59  		List<SearchParamPresent> entitiesToSave = new ArrayList<SearchParamPresent>();
60  		List<SearchParamPresent> entitiesToDelete = new ArrayList<SearchParamPresent>();
61  
62  		Collection<SearchParamPresent> existing;
63  		existing = mySearchParamPresentDao.findAllForResource(theResource);
64  
65  		for (SearchParamPresent nextExistingEntity : existing) {
66  			String nextSearchParamName = nextExistingEntity.getSearchParam().getParamName();
67  			Boolean existingValue = presenceMap.remove(nextSearchParamName);
68  			if (existingValue == null) {
69  				entitiesToDelete.add(nextExistingEntity);
70  			} else if (existingValue.booleanValue() == nextExistingEntity.isPresent()) {
71  				ourLog.trace("No change for search param {}", nextSearchParamName);
72  			} else {
73  				nextExistingEntity.setPresent(existingValue);
74  				entitiesToSave.add(nextExistingEntity);
75  			}
76  		}
77  
78  		for (Entry<String, Boolean> next : presenceMap.entrySet()) {
79  			String resourceType = theResource.getResourceType();
80  			String paramName = next.getKey();
81  			Pair<String, String> key = Pair.of(resourceType, paramName);
82  
83  			SearchParam searchParam = myResourceTypeToSearchParamToEntity.get(key);
84  			if (searchParam == null) {
85  				searchParam = mySearchParamDao.findForResource(resourceType, paramName);
86  				if (searchParam != null) {
87  					myResourceTypeToSearchParamToEntity.put(key, searchParam);
88  				} else {
89  					searchParam = new SearchParam();
90  					searchParam.setResourceName(resourceType);
91  					searchParam.setParamName(paramName);
92  					searchParam = mySearchParamDao.save(searchParam);
93  					ourLog.info("Added search param {} with pid {}", paramName, searchParam.getId());
94  					// Don't add the newly saved entity to the map in case the save fails
95  				}
96  			}
97  
98  			SearchParamPresent present = new SearchParamPresent();
99  			present.setResource(theResource);
100 			present.setSearchParam(searchParam);
101 			present.setPresent(next.getValue());
102 			entitiesToSave.add(present);
103 
104 		}
105 
106 		mySearchParamPresentDao.deleteInBatch(entitiesToDelete);
107 		mySearchParamPresentDao.save(entitiesToSave);
108 
109 	}
110 
111 	@Override
112 	public void flushCachesForUnitTest() {
113 		myResourceTypeToSearchParamToEntity.clear();
114 	}
115 
116 }