ca.uhn.fhir.jpa.api.dao.DaoRegistry Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hapi-fhir-storage Show documentation
Show all versions of hapi-fhir-storage Show documentation
This project provides services useful for fhir repository storage. Actual repository storage services
are not in this project, just the api and helper libraries.
The newest version!
/*-
* #%L
* HAPI FHIR Storage api
* %%
* Copyright (C) 2014 - 2024 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.jpa.api.dao;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.IDaoRegistry;
import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import jakarta.annotation.Nullable;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class DaoRegistry implements ApplicationContextAware, IDaoRegistry {
private ApplicationContext myAppCtx;
@Autowired
private FhirContext myContext;
private volatile Map> myResourceNameToResourceDao;
private volatile IFhirSystemDao, ?> mySystemDao;
private Set mySupportedResourceTypes;
/**
* Constructor
*/
public DaoRegistry() {
this(null);
}
/**
* Constructor
*/
public DaoRegistry(FhirContext theFhirContext) {
super();
myContext = theFhirContext;
}
public void setSupportedResourceTypes(Collection theSupportedResourceTypes) {
HashSet supportedResourceTypes = new HashSet<>();
if (theSupportedResourceTypes != null) {
supportedResourceTypes.addAll(theSupportedResourceTypes);
}
mySupportedResourceTypes = supportedResourceTypes;
myResourceNameToResourceDao = null;
}
@Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myAppCtx = theApplicationContext;
}
public IFhirSystemDao getSystemDao() {
IFhirSystemDao retVal = mySystemDao;
if (retVal == null) {
retVal = myAppCtx.getBean(IFhirSystemDao.class);
mySystemDao = retVal;
}
return retVal;
}
/**
* @throws InvalidRequestException If the given resource type is not supported
*/
public IFhirResourceDao getResourceDao(String theResourceName) {
IFhirResourceDao retVal = getResourceDaoOrNull(theResourceName);
if (retVal == null) {
List supportedResourceTypes =
myResourceNameToResourceDao.keySet().stream().sorted().collect(Collectors.toList());
throw new InvalidRequestException(Msg.code(572)
+ "Unable to process request, this server does not know how to handle resources of type "
+ theResourceName + " - Can handle: " + supportedResourceTypes);
}
return retVal;
}
@SuppressWarnings("unchecked")
public IFhirResourceDao getResourceDao(R theResource) {
return (IFhirResourceDao) getResourceDao(theResource.getClass());
}
public IFhirResourceDao getResourceDao(Class theResourceType) {
IFhirResourceDao retVal = getResourceDaoIfExists(theResourceType);
Validate.notNull(
retVal, "No DAO exists for resource type %s - Have: %s", theResourceType, myResourceNameToResourceDao);
return retVal;
}
/**
* Use getResourceDaoOrNull
*/
@Deprecated
public IFhirResourceDao getResourceDaoIfExists(Class theResourceType) {
return getResourceDaoOrNull(theResourceType);
}
@Nullable
public IFhirResourceDao getResourceDaoOrNull(Class theResourceType) {
String resourceName = myContext.getResourceType(theResourceType);
try {
return (IFhirResourceDao) getResourceDao(resourceName);
} catch (InvalidRequestException e) {
return null;
}
}
/**
* Use getResourceDaoOrNull
*/
@Deprecated
public IFhirResourceDao getResourceDaoIfExists(String theResourceType) {
return getResourceDaoOrNull(theResourceType);
}
@Nullable
public IFhirResourceDao getResourceDaoOrNull(String theResourceName) {
init();
return (IFhirResourceDao) myResourceNameToResourceDao.get(theResourceName);
}
@Override
public boolean isResourceTypeSupported(String theResourceType) {
if (mySupportedResourceTypes == null) {
return getResourceDaoOrNull(theResourceType) != null;
}
return mySupportedResourceTypes.contains(theResourceType);
}
private void init() {
if (myResourceNameToResourceDao != null && !myResourceNameToResourceDao.isEmpty()) {
return;
}
Map resourceDaos = myAppCtx.getBeansOfType(IFhirResourceDao.class);
initializeMaps(resourceDaos.values());
}
private void initializeMaps(Collection theResourceDaos) {
myResourceNameToResourceDao = new HashMap<>();
for (IFhirResourceDao nextResourceDao : theResourceDaos) {
Class resourceType = nextResourceDao.getResourceType();
assert resourceType != null;
RuntimeResourceDefinition nextResourceDef = myContext.getResourceDefinition(resourceType);
if (mySupportedResourceTypes == null || mySupportedResourceTypes.contains(nextResourceDef.getName())) {
myResourceNameToResourceDao.put(nextResourceDef.getName(), nextResourceDao);
}
}
}
public void register(IFhirResourceDao theResourceDao) {
RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(theResourceDao.getResourceType());
String resourceName = resourceDef.getName();
myResourceNameToResourceDao.put(resourceName, theResourceDao);
}
public IFhirResourceDao getDaoOrThrowException(Class extends IBaseResource> theClass) {
IFhirResourceDao retVal = getResourceDao(theClass);
if (retVal == null) {
List supportedResourceNames = myResourceNameToResourceDao.keySet().stream()
.map(t -> myContext.getResourceType(t))
.sorted()
.collect(Collectors.toList());
throw new InvalidRequestException(Msg.code(573)
+ "Unable to process request, this server does not know how to handle resources of type "
+ myContext.getResourceType(theClass) + " - Can handle: " + supportedResourceNames);
}
return retVal;
}
public void setResourceDaos(Collection theResourceDaos) {
initializeMaps(theResourceDaos);
}
public IFhirResourceDao getSubscriptionDao() {
return getResourceDao(ResourceTypeEnum.SUBSCRIPTION.getCode());
}
public void setSupportedResourceTypes(String... theResourceTypes) {
setSupportedResourceTypes(toCollection(theResourceTypes));
}
private List toCollection(String[] theResourceTypes) {
List retVal = null;
if (theResourceTypes != null && theResourceTypes.length > 0) {
retVal = Arrays.asList(theResourceTypes);
}
return retVal;
}
public Set getRegisteredDaoTypes() {
return Collections.unmodifiableSet(myResourceNameToResourceDao.keySet());
}
}