Add new indexing extractor method
This commit is contained in:
parent
27959614d8
commit
a5257f0fa8
|
@ -117,6 +117,23 @@ public class SearchParamExtractorR4Test {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExtractSearchParamTokenTest() {
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("sys").setValue("val");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam("Patient", Patient.SP_IDENTIFIER);
|
||||
assertNotNull(param);
|
||||
ISearchParamExtractor.SearchParamSet<BaseResourceIndexedSearchParam> params = extractor.extractSearchParamTokens(p, param);
|
||||
assertEquals(1, params.size());
|
||||
ResourceIndexedSearchParamToken paramValue = (ResourceIndexedSearchParamToken) params.iterator().next();
|
||||
assertEquals("identifier", paramValue.getParamName());
|
||||
assertEquals("sys", paramValue.getSystem());
|
||||
assertEquals("val", paramValue.getValue());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExtensionContainingReference() {
|
||||
String path = "Patient.extension('http://patext').value.as(Reference)";
|
||||
|
|
|
@ -186,7 +186,19 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
|
||||
@Override
|
||||
public SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamTokens(IBaseResource theResource) {
|
||||
IExtractor<BaseResourceIndexedSearchParam> extractor = createTokenExtractor(theResource);
|
||||
return extractSearchParams(theResource, extractor, RestSearchParameterTypeEnum.TOKEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamTokens(IBaseResource theResource, RuntimeSearchParam theSearchParam) {
|
||||
IExtractor<BaseResourceIndexedSearchParam> extractor = createTokenExtractor(theResource);
|
||||
SearchParamSet<BaseResourceIndexedSearchParam> setToPopulate = new SearchParamSet<>();
|
||||
extractSearchParam(theSearchParam, theResource, extractor, setToPopulate);
|
||||
return setToPopulate;
|
||||
}
|
||||
|
||||
private IExtractor<BaseResourceIndexedSearchParam> createTokenExtractor(IBaseResource theResource) {
|
||||
String resourceTypeName = toRootTypeName(theResource);
|
||||
String useSystem;
|
||||
if (getContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) {
|
||||
|
@ -204,85 +216,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
}
|
||||
}
|
||||
|
||||
IExtractor<BaseResourceIndexedSearchParam> extractor = (params, searchParam, value, path) -> {
|
||||
|
||||
// DSTU3+
|
||||
if (value instanceof IBaseEnumeration<?>) {
|
||||
IBaseEnumeration<?> obj = (IBaseEnumeration<?>) value;
|
||||
String system = extractSystem(obj);
|
||||
String code = obj.getValueAsString();
|
||||
createTokenIndexIfNotBlank(resourceTypeName, params, searchParam, system, code);
|
||||
return;
|
||||
}
|
||||
|
||||
// DSTU2 only
|
||||
if (value instanceof BoundCodeDt) {
|
||||
BoundCodeDt boundCode = (BoundCodeDt) value;
|
||||
Enum valueAsEnum = boundCode.getValueAsEnum();
|
||||
String system = null;
|
||||
if (valueAsEnum != null) {
|
||||
//noinspection unchecked
|
||||
system = boundCode.getBinder().toSystemString(valueAsEnum);
|
||||
}
|
||||
String code = boundCode.getValueAsString();
|
||||
createTokenIndexIfNotBlank(resourceTypeName, params, searchParam, system, code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof IPrimitiveType) {
|
||||
IPrimitiveType<?> nextValue = (IPrimitiveType<?>) value;
|
||||
String systemAsString = null;
|
||||
String valueAsString = nextValue.getValueAsString();
|
||||
if ("CodeSystem.concept.code".equals(path)) {
|
||||
systemAsString = useSystem;
|
||||
} else if ("ValueSet.codeSystem.concept.code".equals(path)) {
|
||||
systemAsString = useSystem;
|
||||
}
|
||||
|
||||
createTokenIndexIfNotBlank(resourceTypeName, params, searchParam, systemAsString, valueAsString);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (path) {
|
||||
case "Patient.communication":
|
||||
addToken_PatientCommunication(resourceTypeName, params, searchParam, value);
|
||||
return;
|
||||
case "Consent.source":
|
||||
// Consent#source-identifier has a path that isn't typed - This is a one-off to deal with that
|
||||
return;
|
||||
case "Location.position":
|
||||
addCoords_Position(resourceTypeName, params, searchParam, value);
|
||||
return;
|
||||
case "StructureDefinition.context":
|
||||
// TODO: implement this
|
||||
ourLog.warn("StructureDefinition context indexing not currently supported");
|
||||
return;
|
||||
case "CapabilityStatement.rest.security":
|
||||
addToken_CapabilityStatementRestSecurity(resourceTypeName, params, searchParam, value);
|
||||
return;
|
||||
}
|
||||
|
||||
String nextType = toRootTypeName(value);
|
||||
switch (nextType) {
|
||||
case "Identifier":
|
||||
addToken_Identifier(resourceTypeName, params, searchParam, value);
|
||||
break;
|
||||
case "CodeableConcept":
|
||||
addToken_CodeableConcept(resourceTypeName, params, searchParam, value);
|
||||
break;
|
||||
case "Coding":
|
||||
addToken_Coding(resourceTypeName, params, searchParam, value);
|
||||
break;
|
||||
case "ContactPoint":
|
||||
addToken_ContactPoint(resourceTypeName, params, searchParam, value);
|
||||
break;
|
||||
default:
|
||||
addUnexpectedDatatypeWarning(params, searchParam, value);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return extractSearchParams(theResource, extractor, RestSearchParameterTypeEnum.TOKEN);
|
||||
return new TokenExtractor(resourceTypeName, useSystem);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -798,25 +732,29 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
continue;
|
||||
}
|
||||
|
||||
String nextPathUnsplit = nextSpDef.getPath();
|
||||
if (isBlank(nextPathUnsplit)) {
|
||||
continue;
|
||||
}
|
||||
extractSearchParam(nextSpDef, theResource, theExtractor, retVal);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
String[] splitPaths = split(nextPathUnsplit);
|
||||
for (String nextPath : splitPaths) {
|
||||
nextPath = trim(nextPath);
|
||||
for (IBase nextObject : extractValues(nextPath, theResource)) {
|
||||
if (nextObject != null) {
|
||||
String typeName = toRootTypeName(nextObject);
|
||||
if (!myIgnoredForSearchDatatypes.contains(typeName)) {
|
||||
theExtractor.extract(retVal, nextSpDef, nextObject, nextPath);
|
||||
}
|
||||
private <T> void extractSearchParam(RuntimeSearchParam theSearchParameterDef, IBaseResource theResource, IExtractor<T> theExtractor, SearchParamSet<T> theSetToPopulate) {
|
||||
String nextPathUnsplit = theSearchParameterDef.getPath();
|
||||
if (isBlank(nextPathUnsplit)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] splitPaths = split(nextPathUnsplit);
|
||||
for (String nextPath : splitPaths) {
|
||||
nextPath = trim(nextPath);
|
||||
for (IBase nextObject : extractValues(nextPath, theResource)) {
|
||||
if (nextObject != null) {
|
||||
String typeName = toRootTypeName(nextObject);
|
||||
if (!myIgnoredForSearchDatatypes.contains(typeName)) {
|
||||
theExtractor.extract(theSetToPopulate, theSearchParameterDef, nextObject, nextPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private String toRootTypeName(IBase nextObject) {
|
||||
|
@ -1032,6 +970,95 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
|
||||
}
|
||||
|
||||
private class TokenExtractor implements IExtractor<BaseResourceIndexedSearchParam> {
|
||||
private final String myResourceTypeName;
|
||||
private final String myUseSystem;
|
||||
|
||||
public TokenExtractor(String theResourceTypeName, String theUseSystem) {
|
||||
myResourceTypeName = theResourceTypeName;
|
||||
myUseSystem = theUseSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extract(SearchParamSet<BaseResourceIndexedSearchParam> params, RuntimeSearchParam searchParam, IBase value, String path) {
|
||||
|
||||
// DSTU3+
|
||||
if (value instanceof IBaseEnumeration<?>) {
|
||||
IBaseEnumeration<?> obj = (IBaseEnumeration<?>) value;
|
||||
String system = extractSystem(obj);
|
||||
String code = obj.getValueAsString();
|
||||
BaseSearchParamExtractor.this.createTokenIndexIfNotBlank(myResourceTypeName, params, searchParam, system, code);
|
||||
return;
|
||||
}
|
||||
|
||||
// DSTU2 only
|
||||
if (value instanceof BoundCodeDt) {
|
||||
BoundCodeDt boundCode = (BoundCodeDt) value;
|
||||
Enum valueAsEnum = boundCode.getValueAsEnum();
|
||||
String system = null;
|
||||
if (valueAsEnum != null) {
|
||||
//noinspection unchecked
|
||||
system = boundCode.getBinder().toSystemString(valueAsEnum);
|
||||
}
|
||||
String code = boundCode.getValueAsString();
|
||||
BaseSearchParamExtractor.this.createTokenIndexIfNotBlank(myResourceTypeName, params, searchParam, system, code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof IPrimitiveType) {
|
||||
IPrimitiveType<?> nextValue = (IPrimitiveType<?>) value;
|
||||
String systemAsString = null;
|
||||
String valueAsString = nextValue.getValueAsString();
|
||||
if ("CodeSystem.concept.code".equals(path)) {
|
||||
systemAsString = myUseSystem;
|
||||
} else if ("ValueSet.codeSystem.concept.code".equals(path)) {
|
||||
systemAsString = myUseSystem;
|
||||
}
|
||||
|
||||
BaseSearchParamExtractor.this.createTokenIndexIfNotBlank(myResourceTypeName, params, searchParam, systemAsString, valueAsString);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (path) {
|
||||
case "Patient.communication":
|
||||
BaseSearchParamExtractor.this.addToken_PatientCommunication(myResourceTypeName, params, searchParam, value);
|
||||
return;
|
||||
case "Consent.source":
|
||||
// Consent#source-identifier has a path that isn't typed - This is a one-off to deal with that
|
||||
return;
|
||||
case "Location.position":
|
||||
BaseSearchParamExtractor.this.addCoords_Position(myResourceTypeName, params, searchParam, value);
|
||||
return;
|
||||
case "StructureDefinition.context":
|
||||
// TODO: implement this
|
||||
ourLog.warn("StructureDefinition context indexing not currently supported");
|
||||
return;
|
||||
case "CapabilityStatement.rest.security":
|
||||
BaseSearchParamExtractor.this.addToken_CapabilityStatementRestSecurity(myResourceTypeName, params, searchParam, value);
|
||||
return;
|
||||
}
|
||||
|
||||
String nextType = BaseSearchParamExtractor.this.toRootTypeName(value);
|
||||
switch (nextType) {
|
||||
case "Identifier":
|
||||
BaseSearchParamExtractor.this.addToken_Identifier(myResourceTypeName, params, searchParam, value);
|
||||
break;
|
||||
case "CodeableConcept":
|
||||
BaseSearchParamExtractor.this.addToken_CodeableConcept(myResourceTypeName, params, searchParam, value);
|
||||
break;
|
||||
case "Coding":
|
||||
BaseSearchParamExtractor.this.addToken_Coding(myResourceTypeName, params, searchParam, value);
|
||||
break;
|
||||
case "ContactPoint":
|
||||
BaseSearchParamExtractor.this.addToken_ContactPoint(myResourceTypeName, params, searchParam, value);
|
||||
break;
|
||||
default:
|
||||
BaseSearchParamExtractor.this.addUnexpectedDatatypeWarning(params, searchParam, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addIgnoredType(FhirContext theCtx, String theType, Set<String> theIgnoredTypes) {
|
||||
BaseRuntimeElementDefinition<?> elementDefinition = theCtx.getElementDefinition(theType);
|
||||
if (elementDefinition != null) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.searchparam.extractor;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.*;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
|
@ -42,6 +43,8 @@ public interface ISearchParamExtractor {
|
|||
|
||||
SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamTokens(IBaseResource theResource);
|
||||
|
||||
SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamTokens(IBaseResource theResource, RuntimeSearchParam theSearchParam);
|
||||
|
||||
SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamSpecial(IBaseResource theResource);
|
||||
|
||||
SearchParamSet<ResourceIndexedSearchParamUri> extractSearchParamUri(IBaseResource theResource);
|
||||
|
|
Loading…
Reference in New Issue