Add support for _lanugage SP (#5300)
* Add support for _lanugage SP * Add changelog * Formatting fix * Add to JPA * Add validator * Validate language SP * Assign new code * Fixes
This commit is contained in:
parent
d4717a08d6
commit
2da8aafad0
|
@ -182,6 +182,11 @@ public class Constants {
|
|||
public static final String PARAM_HAS = "_has";
|
||||
public static final String PARAM_HISTORY = "_history";
|
||||
public static final String PARAM_INCLUDE = "_include";
|
||||
/**
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public static final String PARAM_LANGUAGE = "_language";
|
||||
|
||||
public static final String PARAM_INCLUDE_QUALIFIER_RECURSE = ":recurse";
|
||||
public static final String PARAM_INCLUDE_RECURSE = "_include" + PARAM_INCLUDE_QUALIFIER_RECURSE;
|
||||
public static final String PARAM_INCLUDE_QUALIFIER_ITERATE = ":iterate";
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
type: fix
|
||||
issue: 5300
|
||||
title: "A bug in DefaultProfileValidationSupport in R5 mode caused it to return duplicates
|
||||
in the lists returned by `fetchAllStructureDefinitions()`, `fetchAllSearchParameters()`, etc.
|
||||
This has been corrected."
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: add
|
||||
issue: 5300
|
||||
title: "A new configuration option has been added to `StorageSettings` which enables
|
||||
support in the JPA server for the `_language` SearchParameter."
|
|
@ -138,6 +138,13 @@ public class StorageSettings {
|
|||
* Since 6.4.0
|
||||
*/
|
||||
private boolean myQualifySubscriptionMatchingChannelName = true;
|
||||
/**
|
||||
* Should the {@literal _lamguage} SearchParameter be supported
|
||||
* on this server?
|
||||
*
|
||||
* @since 7.0.0
|
||||
*/
|
||||
private boolean myLanguageSearchParameterEnabled = false;
|
||||
|
||||
/**
|
||||
* If set to true, the server will prevent the creation of Subscriptions which cannot be evaluated IN-MEMORY. This can improve
|
||||
|
@ -1295,6 +1302,23 @@ public class StorageSettings {
|
|||
return myQualifySubscriptionMatchingChannelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Should the {@literal _lamguage} SearchParameter be supported on this server? Defaults to {@literal false}.
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public boolean isLanguageSearchParameterEnabled() {
|
||||
return myLanguageSearchParameterEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the {@literal _lamguage} SearchParameter be supported on this server? Defaults to {@literal false}.
|
||||
*
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public void setLanguageSearchParameterEnabled(boolean theLanguageSearchParameterEnabled) {
|
||||
myLanguageSearchParameterEnabled = theLanguageSearchParameterEnabled;
|
||||
}
|
||||
|
||||
private static void validateTreatBaseUrlsAsLocal(String theUrl) {
|
||||
Validate.notBlank(theUrl, "Base URL must not be null or empty");
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ public class MatchUrlService {
|
|||
IQueryParameterAnd<?> param = JpaParamUtil.parseQueryParams(
|
||||
myFhirContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList);
|
||||
paramMap.add(nextParamName, param);
|
||||
} else if (nextParamName.startsWith("_")) {
|
||||
} else if (nextParamName.startsWith("_") && !Constants.PARAM_LANGUAGE.equals(nextParamName)) {
|
||||
// ignore these since they aren't search params (e.g. _sort)
|
||||
} else {
|
||||
RuntimeSearchParam paramDef =
|
||||
|
|
|
@ -32,6 +32,8 @@ import ca.uhn.fhir.jpa.cache.IResourceChangeListenerRegistry;
|
|||
import ca.uhn.fhir.jpa.cache.ResourceChangeResult;
|
||||
import ca.uhn.fhir.jpa.model.entity.StorageSettings;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
|
||||
|
@ -193,6 +195,31 @@ public class SearchParamRegistryImpl
|
|||
long overriddenCount = overrideBuiltinSearchParamsWithActiveJpaSearchParams(searchParams, theJpaSearchParams);
|
||||
ourLog.trace("Have overridden {} built-in search parameters", overriddenCount);
|
||||
removeInactiveSearchParams(searchParams);
|
||||
|
||||
/*
|
||||
* The _language SearchParameter is a weird exception - It is actually just a normal
|
||||
* token SP, but we explcitly ban SPs from registering themselves with a prefix
|
||||
* of "_" since that's system reserved so we put this one behind a settings toggle
|
||||
*/
|
||||
if (myStorageSettings.isLanguageSearchParameterEnabled()) {
|
||||
IIdType id = myFhirContext.getVersion().newIdType();
|
||||
id.setValue("SearchParameter/Resource-language");
|
||||
RuntimeSearchParam sp = new RuntimeSearchParam(
|
||||
id,
|
||||
"http://hl7.org/fhir/SearchParameter/Resource-language",
|
||||
Constants.PARAM_LANGUAGE,
|
||||
"Language of the resource content",
|
||||
"language",
|
||||
RestSearchParameterTypeEnum.TOKEN,
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet(),
|
||||
RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE,
|
||||
myFhirContext.getResourceTypes());
|
||||
for (String baseResourceType : sp.getBase()) {
|
||||
searchParams.add(baseResourceType, sp.getName(), sp);
|
||||
}
|
||||
}
|
||||
|
||||
myActiveSearchParams = searchParams;
|
||||
|
||||
myJpaSearchParamCache.populateActiveSearchParams(
|
||||
|
@ -282,7 +309,13 @@ public class SearchParamRegistryImpl
|
|||
|
||||
@Override
|
||||
public void forceRefresh() {
|
||||
RuntimeSearchParamCache activeSearchParams = myActiveSearchParams;
|
||||
myResourceChangeListenerCache.forceRefresh();
|
||||
|
||||
// If the refresh didn't trigger a change, proceed with one anyway
|
||||
if (myActiveSearchParams == activeSearchParams) {
|
||||
rebuildActiveSearchParams();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,8 +40,10 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
@ContextConfiguration(classes = TestHSearchAddInConfig.NoFT.class)
|
||||
|
@ -51,7 +53,10 @@ public class FhirResourceDaoR5SearchNoFtTest extends BaseJpaR5Test {
|
|||
|
||||
@AfterEach
|
||||
public void after() {
|
||||
myStorageSettings.setIndexMissingFields(new JpaStorageSettings().getIndexMissingFields());
|
||||
JpaStorageSettings defaults = new JpaStorageSettings();
|
||||
myStorageSettings.setIndexMissingFields(defaults.getIndexMissingFields());
|
||||
myStorageSettings.setLanguageSearchParameterEnabled(defaults.isLanguageSearchParameterEnabled());
|
||||
mySearchParamRegistry.forceRefresh();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -79,6 +84,7 @@ public class FhirResourceDaoR5SearchNoFtTest extends BaseJpaR5Test {
|
|||
IBundleProvider outcome = myPractitionerDao.search(params);
|
||||
assertEquals(1, outcome.getResources(0, 1).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasWithTargetReferenceQualified() {
|
||||
Organization org = new Organization();
|
||||
|
@ -208,7 +214,7 @@ public class FhirResourceDaoR5SearchNoFtTest extends BaseJpaR5Test {
|
|||
|
||||
ClinicalUseDefinition def2 = new ClinicalUseDefinition();
|
||||
def2.getContraindication().getDiseaseSymptomProcedure().setConcept(new CodeableConcept().addCoding(new Coding("http://foo", "bar", "baz")));
|
||||
String id =myClinicalUseDefinitionDao.create(def2, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
String id = myClinicalUseDefinitionDao.create(def2, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
// Test
|
||||
|
||||
|
@ -334,5 +340,33 @@ public class FhirResourceDaoR5SearchNoFtTest extends BaseJpaR5Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLanguageSearchParameter_DefaultDisabled() {
|
||||
createObservation(withId("A"), withLanguage("en"));
|
||||
createObservation(withId("B"), withLanguage("fr"));
|
||||
|
||||
logAllTokenIndexes();
|
||||
runInTransaction(() -> assertEquals(0, myResourceIndexedSearchParamTokenDao.count()));
|
||||
|
||||
SearchParameterMap params = SearchParameterMap.newSynchronous();
|
||||
params.add(Constants.PARAM_LANGUAGE, new TokenParam("en"));
|
||||
assertThrows(InvalidRequestException.class, () -> myObservationDao.search(params, mySrd));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLanguageSearchParameter_Enabled() {
|
||||
myStorageSettings.setLanguageSearchParameterEnabled(true);
|
||||
mySearchParamRegistry.forceRefresh();
|
||||
|
||||
createObservation(withId("A"), withLanguage("en"));
|
||||
createObservation(withId("B"), withLanguage("fr"));
|
||||
|
||||
logAllTokenIndexes();
|
||||
runInTransaction(() -> assertEquals(2, myResourceIndexedSearchParamTokenDao.count()));
|
||||
|
||||
SearchParameterMap params = SearchParameterMap.newSynchronous();
|
||||
params.add(Constants.PARAM_LANGUAGE, new TokenParam("en"));
|
||||
assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(params, mySrd)), contains("Observation/A"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,19 +46,6 @@ import static org.mockito.Mockito.lenient;
|
|||
@ExtendWith(MockitoExtension.class)
|
||||
public class SearchParameterDaoValidatorTest {
|
||||
|
||||
@Spy
|
||||
private FhirContext myFhirContext = FhirContext.forR5Cached();
|
||||
@Mock
|
||||
private ISearchParamRegistry mySearchParamRegistry;
|
||||
@Spy
|
||||
private JpaStorageSettings myStorageSettings = new JpaStorageSettings();
|
||||
@InjectMocks
|
||||
private SearchParameterDaoValidator mySvc;
|
||||
|
||||
private final VersionCanonicalizer myVersionCanonicalizer = new VersionCanonicalizer(myFhirContext);
|
||||
|
||||
private final SearchParameterCanonicalizer mySearchParameterCanonicalizer = new SearchParameterCanonicalizer(myFhirContext);
|
||||
|
||||
private static final String SP_COMPONENT_DEFINITION_OF_TYPE_TOKEN = "SearchParameter/observation-code";
|
||||
private static final String SP_COMPONENT_DEFINITION_OF_TYPE_REFERENCE = "SearchParameter/observation-patient";
|
||||
private static final String SP_COMPONENT_DEFINITION_OF_TYPE_STRING = "SearchParameter/observation-markdown";
|
||||
|
@ -66,6 +53,16 @@ public class SearchParameterDaoValidatorTest {
|
|||
private static final String SP_COMPONENT_DEFINITION_OF_TYPE_QUANTITY = "SearchParameter/observation-code";
|
||||
private static final String SP_COMPONENT_DEFINITION_OF_TYPE_URI = "SearchParameter/component-value-canonical";
|
||||
private static final String SP_COMPONENT_DEFINITION_OF_TYPE_NUMBER = "SearchParameter/component-value-number";
|
||||
@Spy
|
||||
private FhirContext myFhirContext = FhirContext.forR5Cached();
|
||||
private final VersionCanonicalizer myVersionCanonicalizer = new VersionCanonicalizer(myFhirContext);
|
||||
private final SearchParameterCanonicalizer mySearchParameterCanonicalizer = new SearchParameterCanonicalizer(myFhirContext);
|
||||
@Mock
|
||||
private ISearchParamRegistry mySearchParamRegistry;
|
||||
@Spy
|
||||
private JpaStorageSettings myStorageSettings = new JpaStorageSettings();
|
||||
@InjectMocks
|
||||
private SearchParameterDaoValidator mySvc;
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
|
|
|
@ -6,5 +6,6 @@ public class CommonJpaStorageSettingsConfigurer {
|
|||
public CommonJpaStorageSettingsConfigurer(JpaStorageSettings theStorageSettings) {
|
||||
theStorageSettings.setIndexOnUpliftedRefchains(true);
|
||||
theStorageSettings.setMarkResourcesForReindexingUponSearchParameterChange(false);
|
||||
theStorageSettings.setLanguageSearchParameterEnabled(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,10 +98,12 @@ public class SearchParameterDaoValidator {
|
|||
return;
|
||||
}
|
||||
|
||||
// Search parameters must have a base
|
||||
if (isCompositeWithoutBase(searchParameter)) {
|
||||
throw new UnprocessableEntityException(Msg.code(1113) + "SearchParameter.base is missing");
|
||||
}
|
||||
|
||||
// Do we have a valid expression
|
||||
if (isCompositeWithoutExpression(searchParameter)) {
|
||||
|
||||
// this is ok
|
||||
|
|
|
@ -80,6 +80,13 @@ public interface ITestDataBuilder {
|
|||
return t -> __setPrimitiveChild(getFhirContext(), t, "active", "boolean", "false");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Resource.language
|
||||
*/
|
||||
default ICreationArgument withLanguage(String theLanguage) {
|
||||
return t -> __setPrimitiveChild(getFhirContext(), t, "language", "string", theLanguage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Patient.gender
|
||||
*/
|
||||
|
|
|
@ -16,12 +16,14 @@ import org.hl7.fhir.r4.model.ValueSet;
|
|||
|
||||
import java.util.ArrayList;
|
||||
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.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -34,10 +36,14 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
public class PrePopulatedValidationSupport extends BaseStaticResourceValidationSupport
|
||||
implements IValidationSupport, ILockable {
|
||||
|
||||
private final Map<String, IBaseResource> myCodeSystems;
|
||||
private final Map<String, IBaseResource> myStructureDefinitions;
|
||||
private final Map<String, IBaseResource> mySearchParameters;
|
||||
private final Map<String, IBaseResource> myValueSets;
|
||||
private final Map<String, IBaseResource> myUrlToCodeSystems;
|
||||
private final Map<String, IBaseResource> myUrlToStructureDefinitions;
|
||||
private final Map<String, IBaseResource> myUrlToSearchParameters;
|
||||
private final Map<String, IBaseResource> myUrlToValueSets;
|
||||
private final List<IBaseResource> myCodeSystems;
|
||||
private final List<IBaseResource> myStructureDefinitions;
|
||||
private final List<IBaseResource> mySearchParameters;
|
||||
private final List<IBaseResource> myValueSets;
|
||||
private final Map<String, byte[]> myBinaries;
|
||||
private boolean myLocked;
|
||||
|
||||
|
@ -51,51 +57,67 @@ public class PrePopulatedValidationSupport extends BaseStaticResourceValidationS
|
|||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theStructureDefinitions The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
|
||||
* @param theUrlToStructureDefinitions The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
|
||||
* values are the resource itself.
|
||||
* @param theValueSets The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
|
||||
* @param theUrlToValueSets The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
|
||||
* the resource itself.
|
||||
* @param theCodeSystems The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
|
||||
* @param theUrlToCodeSystems The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
|
||||
* the resource itself.
|
||||
**/
|
||||
public PrePopulatedValidationSupport(
|
||||
FhirContext theFhirContext,
|
||||
Map<String, IBaseResource> theStructureDefinitions,
|
||||
Map<String, IBaseResource> theValueSets,
|
||||
Map<String, IBaseResource> theCodeSystems) {
|
||||
this(theFhirContext, theStructureDefinitions, theValueSets, theCodeSystems, new HashMap<>(), new HashMap<>());
|
||||
Map<String, IBaseResource> theUrlToStructureDefinitions,
|
||||
Map<String, IBaseResource> theUrlToValueSets,
|
||||
Map<String, IBaseResource> theUrlToCodeSystems) {
|
||||
this(
|
||||
theFhirContext,
|
||||
theUrlToStructureDefinitions,
|
||||
theUrlToValueSets,
|
||||
theUrlToCodeSystems,
|
||||
new HashMap<>(),
|
||||
new HashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theStructureDefinitions The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
|
||||
* @param theUrlToStructureDefinitions The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
|
||||
* values are the resource itself.
|
||||
* @param theValueSets The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
|
||||
* @param theUrlToValueSets The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
|
||||
* the resource itself.
|
||||
* @param theCodeSystems The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
|
||||
* @param theUrlToCodeSystems The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
|
||||
* the resource itself.
|
||||
* @param theBinaries The binary files to be returned by this module. Keys are the unique filename for the binary, and values
|
||||
* are the contents of the file as a byte array.
|
||||
*/
|
||||
public PrePopulatedValidationSupport(
|
||||
FhirContext theFhirContext,
|
||||
Map<String, IBaseResource> theStructureDefinitions,
|
||||
Map<String, IBaseResource> theValueSets,
|
||||
Map<String, IBaseResource> theCodeSystems,
|
||||
Map<String, IBaseResource> theSearchParameters,
|
||||
Map<String, IBaseResource> theUrlToStructureDefinitions,
|
||||
Map<String, IBaseResource> theUrlToValueSets,
|
||||
Map<String, IBaseResource> theUrlToCodeSystems,
|
||||
Map<String, IBaseResource> theUrlToSearchParameters,
|
||||
Map<String, byte[]> theBinaries) {
|
||||
super(theFhirContext);
|
||||
Validate.notNull(theFhirContext, "theFhirContext must not be null");
|
||||
Validate.notNull(theStructureDefinitions, "theStructureDefinitions must not be null");
|
||||
Validate.notNull(theValueSets, "theValueSets must not be null");
|
||||
Validate.notNull(theCodeSystems, "theCodeSystems must not be null");
|
||||
Validate.notNull(theSearchParameters, "theSearchParameters must not be null");
|
||||
Validate.notNull(theUrlToStructureDefinitions, "theStructureDefinitions must not be null");
|
||||
Validate.notNull(theUrlToValueSets, "theValueSets must not be null");
|
||||
Validate.notNull(theUrlToCodeSystems, "theCodeSystems must not be null");
|
||||
Validate.notNull(theUrlToSearchParameters, "theSearchParameters must not be null");
|
||||
Validate.notNull(theBinaries, "theBinaries must not be null");
|
||||
myStructureDefinitions = theStructureDefinitions;
|
||||
myValueSets = theValueSets;
|
||||
myCodeSystems = theCodeSystems;
|
||||
mySearchParameters = theSearchParameters;
|
||||
myUrlToStructureDefinitions = theUrlToStructureDefinitions;
|
||||
myStructureDefinitions =
|
||||
theUrlToStructureDefinitions.values().stream().distinct().collect(Collectors.toList());
|
||||
|
||||
myUrlToValueSets = theUrlToValueSets;
|
||||
myValueSets = theUrlToValueSets.values().stream().distinct().collect(Collectors.toList());
|
||||
|
||||
myUrlToCodeSystems = theUrlToCodeSystems;
|
||||
myCodeSystems = theUrlToCodeSystems.values().stream().distinct().collect(Collectors.toList());
|
||||
|
||||
myUrlToSearchParameters = theUrlToSearchParameters;
|
||||
mySearchParameters =
|
||||
theUrlToSearchParameters.values().stream().distinct().collect(Collectors.toList());
|
||||
|
||||
myBinaries = theBinaries;
|
||||
}
|
||||
|
||||
|
@ -127,7 +149,7 @@ public class PrePopulatedValidationSupport extends BaseStaticResourceValidationS
|
|||
public void addCodeSystem(IBaseResource theCodeSystem) {
|
||||
validateNotLocked();
|
||||
Set<String> urls = processResourceAndReturnUrls(theCodeSystem, "CodeSystem");
|
||||
addToMap(theCodeSystem, myCodeSystems, urls);
|
||||
addToMap(theCodeSystem, myCodeSystems, myUrlToCodeSystems, urls);
|
||||
}
|
||||
|
||||
private Set<String> processResourceAndReturnUrls(IBaseResource theResource, String theResourceName) {
|
||||
|
@ -185,16 +207,18 @@ public class PrePopulatedValidationSupport extends BaseStaticResourceValidationS
|
|||
public void addStructureDefinition(IBaseResource theStructureDefinition) {
|
||||
validateNotLocked();
|
||||
Set<String> url = processResourceAndReturnUrls(theStructureDefinition, "StructureDefinition");
|
||||
addToMap(theStructureDefinition, myStructureDefinitions, url);
|
||||
addToMap(theStructureDefinition, myStructureDefinitions, myUrlToStructureDefinitions, url);
|
||||
}
|
||||
|
||||
public void addSearchParameter(IBaseResource theSearchParameter) {
|
||||
validateNotLocked();
|
||||
Set<String> url = processResourceAndReturnUrls(theSearchParameter, "SearchParameter");
|
||||
addToMap(theSearchParameter, mySearchParameters, url);
|
||||
addToMap(theSearchParameter, mySearchParameters, myUrlToSearchParameters, url);
|
||||
}
|
||||
|
||||
private <T extends IBaseResource> void addToMap(T theResource, Map<String, T> theMap, Collection<String> theUrls) {
|
||||
private <T extends IBaseResource> void addToMap(
|
||||
T theResource, List<T> theList, Map<String, T> theMap, Collection<String> theUrls) {
|
||||
theList.add(theResource);
|
||||
for (String urls : theUrls) {
|
||||
if (isNotBlank(urls)) {
|
||||
theMap.put(urls, theResource);
|
||||
|
@ -228,7 +252,7 @@ public class PrePopulatedValidationSupport extends BaseStaticResourceValidationS
|
|||
public void addValueSet(IBaseResource theValueSet) {
|
||||
validateNotLocked();
|
||||
Set<String> urls = processResourceAndReturnUrls(theValueSet, "ValueSet");
|
||||
addToMap(theValueSet, myValueSets, urls);
|
||||
addToMap(theValueSet, myValueSets, myUrlToValueSets, urls);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -259,36 +283,38 @@ public class PrePopulatedValidationSupport extends BaseStaticResourceValidationS
|
|||
@Override
|
||||
public List<IBaseResource> fetchAllConformanceResources() {
|
||||
ArrayList<IBaseResource> retVal = new ArrayList<>();
|
||||
retVal.addAll(myCodeSystems.values());
|
||||
retVal.addAll(myStructureDefinitions.values());
|
||||
retVal.addAll(myValueSets.values());
|
||||
retVal.addAll(myCodeSystems);
|
||||
retVal.addAll(myStructureDefinitions);
|
||||
retVal.addAll(myValueSets);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
@Override
|
||||
public <T extends IBaseResource> List<T> fetchAllSearchParameters() {
|
||||
return toList(mySearchParameters);
|
||||
return (List<T>) Collections.unmodifiableList(mySearchParameters);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IBaseResource> List<T> fetchAllStructureDefinitions() {
|
||||
return toList(myStructureDefinitions);
|
||||
return (List<T>) Collections.unmodifiableList(myStructureDefinitions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBaseResource fetchCodeSystem(String theSystem) {
|
||||
return myCodeSystems.get(theSystem);
|
||||
return myUrlToCodeSystems.get(theSystem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBaseResource fetchValueSet(String theUri) {
|
||||
return myValueSets.get(theUri);
|
||||
return myUrlToValueSets.get(theUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBaseResource fetchStructureDefinition(String theUrl) {
|
||||
return myStructureDefinitions.get(theUrl);
|
||||
return myUrlToStructureDefinitions.get(theUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -298,19 +324,23 @@ public class PrePopulatedValidationSupport extends BaseStaticResourceValidationS
|
|||
|
||||
@Override
|
||||
public boolean isCodeSystemSupported(ValidationSupportContext theValidationSupportContext, String theSystem) {
|
||||
return myCodeSystems.containsKey(theSystem);
|
||||
return myUrlToCodeSystems.containsKey(theSystem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValueSetSupported(ValidationSupportContext theValidationSupportContext, String theValueSetUrl) {
|
||||
return myValueSets.containsKey(theValueSetUrl);
|
||||
return myUrlToValueSets.containsKey(theValueSetUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a count of all known resources
|
||||
*/
|
||||
public int countAll() {
|
||||
return myBinaries.size() + myCodeSystems.size() + myStructureDefinitions.size() + myValueSets.size();
|
||||
return myBinaries.size()
|
||||
+ myCodeSystems.size()
|
||||
+ myStructureDefinitions.size()
|
||||
+ myValueSets.size()
|
||||
+ myStructureDefinitions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,7 +2,6 @@ package org.hl7.fhir.dstu3.hapi.validation;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.CodeSystem;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -10,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
public class DefaultProfileValidationSupportTest {
|
||||
public class DefaultProfileValidationSupportR4Test {
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forR4Cached();
|
||||
private DefaultProfileValidationSupport mySvc = new DefaultProfileValidationSupport(ourCtx);
|
|
@ -0,0 +1,29 @@
|
|||
package org.hl7.fhir.dstu3.hapi.validation;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class DefaultProfileValidationSupportR5Test {
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forR5Cached();
|
||||
private DefaultProfileValidationSupport mySvc = new DefaultProfileValidationSupport(ourCtx);
|
||||
|
||||
@Test
|
||||
public void testNoDuplicates() {
|
||||
List<IBaseResource> allSds = mySvc.fetchAllStructureDefinitions()
|
||||
.stream()
|
||||
.map(t->(StructureDefinition)t)
|
||||
.filter(t->t.getUrl().equals("http://hl7.org/fhir/StructureDefinition/language"))
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(1, allSds.size());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue