From e96500d54f643021bf8857e716afdf49c79109de Mon Sep 17 00:00:00 2001 From: James Agnew Date: Wed, 30 Oct 2019 15:51:46 -0400 Subject: [PATCH] Add a test --- ...ntimeChildPrimitiveDatatypeDefinition.java | 40 +-- .../uhn/fhir/jpa/config/r5/BaseR5Config.java | 4 +- .../extractor/BaseSearchParamExtractor.java | 17 +- .../extractor/SearchParamExtractorDstu2.java | 12 + .../extractor/SearchParamExtractorDstu3.java | 1 + .../extractor/SearchParamExtractorR4.java | 1 + .../extractor/SearchParamExtractorR5.java | 15 +- .../SearchParamExtractorMegaTest.java | 286 ++++++++++++++++++ 8 files changed, 323 insertions(+), 53 deletions(-) create mode 100644 hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorMegaTest.java diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildPrimitiveDatatypeDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildPrimitiveDatatypeDefinition.java index 08a5321c65e..61cb14d4546 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildPrimitiveDatatypeDefinition.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildPrimitiveDatatypeDefinition.java @@ -28,47 +28,9 @@ import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Description; public class RuntimeChildPrimitiveDatatypeDefinition extends BaseRuntimeChildDatatypeDefinition { -// private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RuntimeChildPrimitiveDatatypeDefinition.class); -// private IMutator myReferenceMutator; - + public RuntimeChildPrimitiveDatatypeDefinition(Field theField, String theElementName, Description theDescriptionAnnotation, Child theChildAnnotation, Class theDatatype) { super(theField, theElementName, theChildAnnotation, theDescriptionAnnotation, theDatatype); } -// @Override -// void sealAndInitialize(FhirContext theContext, Map, BaseRuntimeElementDefinition> theClassToElementDefinitions) { -// super.sealAndInitialize(theContext, theClassToElementDefinitions); -// -// if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) { -// if (IReference.class.isAssignableFrom(getDatatype())) { -// String fieldName = getField().getName() + "Target"; -// try { -// Field targetField = getField().getDeclaringClass().getField(fieldName); -// if (List.class.isAssignableFrom(targetField.getType())) { -// myReferenceMutator = new FieldListMutator(); -// } else if (IBaseResource.class.isAssignableFrom(targetField.getType())) { -// myReferenceMutator = new FieldPlainMutator(); -// } -// } catch (Exception e) { -// ourLog.debug("Unable to find target field named {}", fieldName); -// } -// } -// } else { -// if (BaseResourceReferenceDt.class.isAssignableFrom(getDatatype())) { -// myReferenceMutator = new IMutator() { -// @Override -// public void addValue(Object theTarget, IBase theValue) { -// BaseResourceReferenceDt dt = (BaseResourceReferenceDt)theTarget; -// dt.setResource((IBaseResource) theValue); -// }}; -// } -// } -// -// } -// -// public IMutator getReferenceMutator() { -// return myReferenceMutator; -// } - - } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r5/BaseR5Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r5/BaseR5Config.java index 07dd15325b6..5471013d9f9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r5/BaseR5Config.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r5/BaseR5Config.java @@ -2,7 +2,6 @@ package ca.uhn.fhir.jpa.config.r5; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.ParserOptions; -import ca.uhn.fhir.jpa.config.BaseConfig; import ca.uhn.fhir.jpa.config.BaseConfigDstu3Plus; import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl; import ca.uhn.fhir.jpa.dao.IFhirSystemDao; @@ -20,7 +19,6 @@ import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc; import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainR5; import ca.uhn.fhir.validation.IInstanceValidatorModule; -import ca.uhn.fhir.validation.IValidatorModule; import org.apache.commons.lang3.time.DateUtils; import org.hl7.fhir.r5.hapi.ctx.DefaultProfileValidationSupport; import org.hl7.fhir.r5.hapi.ctx.IValidationSupport; @@ -139,7 +137,7 @@ public class BaseR5Config extends BaseConfigDstu3Plus { @Bean(autowire = Autowire.BY_TYPE) public SearchParamExtractorR5 searchParamExtractor() { - return new SearchParamExtractorR5(); + return new SearchParamExtractorR5(ctx, new DefaultProfileValidationSupport(), searchParamRegistry); } @Bean diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java index ed542155f4a..370b4ba849c 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java @@ -34,6 +34,7 @@ import org.hl7.fhir.instance.model.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import javax.annotation.Nullable; import javax.annotation.PostConstruct; import javax.measure.quantity.Quantity; import javax.measure.unit.NonSI; @@ -110,7 +111,6 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor BaseSearchParamExtractor(FhirContext theCtx, ISearchParamRegistry theSearchParamRegistry) { myContext = theCtx; mySearchParamRegistry = theSearchParamRegistry; - start(); } @Override @@ -536,7 +536,6 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor for (IBase nextValue : values) { addToken_CodeableConcept(theResourceType, theParams, theSearchParam, nextValue); } - } private void addDate_Period(String theResourceType, Set theParams, RuntimeSearchParam theSearchParam, IBase theValue) { @@ -859,12 +858,14 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor myAddressCountryValueChild = addressDefinition.getChildByName("country"); myAddressPostalCodeValueChild = addressDefinition.getChildByName("postalCode"); - BaseRuntimeElementCompositeDefinition capabilityStatementDefinition = getContext().getResourceDefinition("CapabilityStatement"); - BaseRuntimeChildDefinition capabilityStatementRestChild = capabilityStatementDefinition.getChildByName("rest"); - BaseRuntimeElementCompositeDefinition capabilityStatementRestDefinition = (BaseRuntimeElementCompositeDefinition) capabilityStatementRestChild.getChildByName("rest"); - BaseRuntimeChildDefinition capabilityStatementRestSecurityValueChild = capabilityStatementRestDefinition.getChildByName("security"); - BaseRuntimeElementCompositeDefinition capabilityStatementRestSecurityDefinition = (BaseRuntimeElementCompositeDefinition) capabilityStatementRestSecurityValueChild.getChildByName("security"); - myCapabilityStatementRestSecurityServiceValueChild = capabilityStatementRestSecurityDefinition.getChildByName("service"); + if (getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) { + BaseRuntimeElementCompositeDefinition capabilityStatementDefinition = getContext().getResourceDefinition("CapabilityStatement"); + BaseRuntimeChildDefinition capabilityStatementRestChild = capabilityStatementDefinition.getChildByName("rest"); + BaseRuntimeElementCompositeDefinition capabilityStatementRestDefinition = (BaseRuntimeElementCompositeDefinition) capabilityStatementRestChild.getChildByName("rest"); + BaseRuntimeChildDefinition capabilityStatementRestSecurityValueChild = capabilityStatementRestDefinition.getChildByName("security"); + BaseRuntimeElementCompositeDefinition capabilityStatementRestSecurityDefinition = (BaseRuntimeElementCompositeDefinition) capabilityStatementRestSecurityValueChild.getChildByName("security"); + myCapabilityStatementRestSecurityServiceValueChild = capabilityStatementRestSecurityDefinition.getChildByName("service"); + } BaseRuntimeElementCompositeDefinition periodDefinition = (BaseRuntimeElementCompositeDefinition) getContext().getElementDefinition("Period"); myPeriodStartValueChild = periodDefinition.getChildByName("start"); diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java index 373ff4f97a0..f14f5994763 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java @@ -20,6 +20,8 @@ package ca.uhn.fhir.jpa.searchparam.extractor; * #L% */ +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.model.dstu2.composite.ContactPointDt; import ca.uhn.fhir.util.FhirTerser; import org.hl7.fhir.instance.model.api.IBase; @@ -32,6 +34,16 @@ import java.util.List; public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implements ISearchParamExtractor { + public SearchParamExtractorDstu2() { + } + + /** + * Constructor for unit tests + */ + SearchParamExtractorDstu2(FhirContext theCtx, ISearchParamRegistry theSearchParamRegistry) { + super(theCtx, theSearchParamRegistry); + start(); + } @Override protected IValueExtractor getPathValueExtractor(IBaseResource theResource, String theSinglePath) { diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java index 56ca8d14e30..235596aae03 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java @@ -61,6 +61,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen super(theCtx, theSearchParamRegistry); myValidationSupport = theValidationSupport; start(null); + start(); } @Override diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java index 775d86cc184..a54e3c24789 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java @@ -57,6 +57,7 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements super(theCtx, theSearchParamRegistry); myValidationSupport = theValidationSupport; initFhirPath(); + start(); } @Override diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java index 6b2826d3827..6af6e523965 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java @@ -20,10 +20,13 @@ package ca.uhn.fhir.jpa.searchparam.extractor; * #L% */ +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.PathEngineException; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.r5.context.IWorkerContext; +import org.hl7.fhir.r5.hapi.ctx.DefaultProfileValidationSupport; import org.hl7.fhir.r5.hapi.ctx.HapiWorkerContext; import org.hl7.fhir.r5.hapi.ctx.IValidationSupport; import org.hl7.fhir.r5.model.*; @@ -44,13 +47,19 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements private IValidationSupport myValidationSupport; private FHIRPathEngine myFhirPathEngine; - /** - * Constructor - */ public SearchParamExtractorR5() { super(); } + /** + * Constructor for unit tests + */ + public SearchParamExtractorR5(FhirContext theCtx, DefaultProfileValidationSupport theDefaultProfileValidationSupport, ISearchParamRegistry theSearchParamRegistry) { + super(theCtx, theSearchParamRegistry); + myValidationSupport = theDefaultProfileValidationSupport; + start(); + } + @Override @PostConstruct public void start() { diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorMegaTest.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorMegaTest.java new file mode 100644 index 00000000000..da6dacf4bf4 --- /dev/null +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorMegaTest.java @@ -0,0 +1,286 @@ +package ca.uhn.fhir.jpa.searchparam.extractor; + +import ca.uhn.fhir.context.*; +import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import org.hl7.fhir.dstu3.hapi.ctx.DefaultProfileValidationSupport; +import org.hl7.fhir.instance.model.api.IBase; +import org.hl7.fhir.instance.model.api.IBaseEnumeration; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IPrimitiveType; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.Assert.assertEquals; + +public class SearchParamExtractorMegaTest { + + private static final Logger ourLog = LoggerFactory.getLogger(SearchParamExtractorMegaTest.class); + + /** + * This test is my magnum opus :P + * + * It navigates almost every possible path in every FHIR resource in every version of FHIR, + * and creates a resource with that path populated, just to ensure that we can index it + * without generating any warnings. + */ + @Test + public void testAllCombinations() throws Exception { + + FhirContext ctx = FhirContext.forDstu2(); + ISearchParamRegistry searchParamRegistry = new MySearchParamRegistry(ctx); + process(ctx, new SearchParamExtractorDstu2(ctx, searchParamRegistry)); + + ctx = FhirContext.forDstu3(); + searchParamRegistry = new MySearchParamRegistry(ctx); + process(ctx, new SearchParamExtractorDstu3(null, ctx, new DefaultProfileValidationSupport(), searchParamRegistry)); + + ctx = FhirContext.forR4(); + searchParamRegistry = new MySearchParamRegistry(ctx); + process(ctx, new SearchParamExtractorR4(null, ctx, new org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport(), searchParamRegistry)); + + ctx = FhirContext.forR5(); + searchParamRegistry = new MySearchParamRegistry(ctx); + process(ctx, new SearchParamExtractorR5(ctx, new org.hl7.fhir.r5.hapi.ctx.DefaultProfileValidationSupport(), searchParamRegistry)); + } + + private void process(FhirContext theCtx, BaseSearchParamExtractor theExtractor) throws Exception { + AtomicInteger indexesCounter = new AtomicInteger(); + + for (String nextResourceName : theCtx.getResourceNames()) { + RuntimeResourceDefinition resourceDefinition = theCtx.getResourceDefinition(nextResourceName); + + List elementStack = new ArrayList<>(); + List childStack = new ArrayList<>(); + + processElement(theCtx, theExtractor, resourceDefinition, elementStack, childStack, indexesCounter); + } + + ourLog.info("Found {} indexes", indexesCounter.get()); + } + + private void processElement(FhirContext theCtx, BaseSearchParamExtractor theExtractor, BaseRuntimeElementDefinition theElementDef, List theElementStack, List theChildStack, AtomicInteger theIndexesCounter) throws Exception { + if (theElementDef.getName().equals("ElementDefinition")) { + return; + } + + + + theElementStack.add(theElementDef); + + if (theElementDef instanceof BaseRuntimeElementCompositeDefinition) { + BaseRuntimeElementCompositeDefinition composite = (BaseRuntimeElementCompositeDefinition) theElementDef; + + for (BaseRuntimeChildDefinition nextChild : composite.getChildren()) { + if (theChildStack.contains(nextChild)) { + continue; + } + + theChildStack.add(nextChild); + + if (nextChild instanceof RuntimeChildResourceBlockDefinition) { + BaseRuntimeElementDefinition def = nextChild.getChildByName(nextChild.getElementName()); + processElement(theCtx, theExtractor, def, theElementStack, theChildStack, theIndexesCounter); + } else if (nextChild instanceof BaseRuntimeChildDatatypeDefinition) { + BaseRuntimeElementDefinition def = nextChild.getChildByName(nextChild.getElementName()); + processElement(theCtx, theExtractor, def, theElementStack, theChildStack, theIndexesCounter); + } else if (nextChild instanceof RuntimeChildExtension) { + // ignore extensions + } else if (nextChild instanceof RuntimeChildContainedResources) { + // ignore extensions + } else if (nextChild instanceof RuntimeChildResourceDefinition) { + // ignore extensions + } else if (nextChild instanceof RuntimeChildChoiceDefinition) { + RuntimeChildChoiceDefinition choice = (RuntimeChildChoiceDefinition) nextChild; + for (String nextOption : choice.getValidChildNames()) { + BaseRuntimeElementDefinition def = nextChild.getChildByName(nextOption); + processElement(theCtx, theExtractor, def, theElementStack, theChildStack, theIndexesCounter); + } + } else if (nextChild instanceof RuntimeChildDirectResource) { + // ignore + } else { + throw new Exception("Unexpected child type: " + nextChild.getClass()); + } + + theChildStack.remove(theChildStack.size() - 1); + } + } else if (theElementDef instanceof RuntimePrimitiveDatatypeDefinition) { + handlePathToPrimitive(theCtx, theExtractor, theElementStack, theChildStack, theIndexesCounter); + } else if (theElementDef instanceof RuntimePrimitiveDatatypeNarrativeDefinition) { + // ignore + } else if (theElementDef instanceof RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition) { + // ignore + } else { + throw new Exception("Unexpected def type: " + theElementDef.getClass()); + } + + theElementStack.remove(theElementStack.size() - 1); + } + + private void handlePathToPrimitive(FhirContext theCtx, BaseSearchParamExtractor theExtractor, List theElementStack, List theChildStack, AtomicInteger theIndexesCounter) { + IBase previousObject = null; + IBaseResource resource = null; + StringBuilder path = new StringBuilder(theElementStack.get(0).getName()); + Object previousChildArguments = null; + for (int i = 0; i < theElementStack.size(); i++) { + BaseRuntimeElementDefinition nextElement = theElementStack.get(i); + + if (i > 0) { + previousChildArguments = theChildStack.get(i-1).getInstanceConstructorArguments(); + } + + IBase nextObject = nextElement.newInstance(previousChildArguments); + if (i == 0) { + resource = (IBaseResource) nextObject; + } else { + BaseRuntimeChildDefinition child = theChildStack.get(i - 1); + child.getMutator().addValue(previousObject, nextObject); + path.append(".").append(child.getChildNameByDatatype(nextObject.getClass())); + } + + previousObject = nextObject; + } + + IPrimitiveType leaf = (IPrimitiveType) previousObject; + + if (leaf instanceof IBaseEnumeration) { + return; + } + + String typeName = theCtx.getElementDefinition(leaf.getClass()).getRootParentDefinition().getName(); + switch (typeName) { + case "boolean": + leaf.setValueAsString("true"); + break; + case "date": + leaf.setValueAsString("2019-10-10"); + break; + case "dateTime": + case "instant": + leaf.setValueAsString("2019-10-10T11:11:11Z"); + break; + case "integer": + case "decimal": + leaf.setValueAsString("1"); + break; + default: + leaf.setValueAsString("a"); + break; + } + + ourLog.info("Found path: {}", path); + + + ISearchParamExtractor.SearchParamSet set; + + set = theExtractor.extractSearchParamCoords(resource); + assertEquals(0, set.getWarnings().size()); + theIndexesCounter.addAndGet(set.size()); + + set = theExtractor.extractSearchParamDates(resource); + assertEquals(0, set.getWarnings().size()); + theIndexesCounter.addAndGet(set.size()); + + set = theExtractor.extractSearchParamNumber(resource); + assertEquals(0, set.getWarnings().size()); + theIndexesCounter.addAndGet(set.size()); + + set = theExtractor.extractSearchParamStrings(resource); + assertEquals(0, set.getWarnings().size()); + theIndexesCounter.addAndGet(set.size()); + + set = theExtractor.extractSearchParamQuantity(resource); + assertEquals(0, set.getWarnings().size()); + theIndexesCounter.addAndGet(set.size()); + + set = theExtractor.extractSearchParamTokens(resource); + assertEquals(0, set.getWarnings().size()); + theIndexesCounter.addAndGet(set.size()); + + set = theExtractor.extractSearchParamUri(resource); + assertEquals(0, set.getWarnings().size()); + theIndexesCounter.addAndGet(set.size()); + + } + + private static class MySearchParamRegistry implements ISearchParamRegistry { + + private final FhirContext myCtx; + private List myAddedSearchParams = new ArrayList<>(); + + private MySearchParamRegistry(FhirContext theCtx) { + myCtx = theCtx; + } + + public void addSearchParam(RuntimeSearchParam... theSearchParam) { + myAddedSearchParams.clear(); + for (RuntimeSearchParam next : theSearchParam) { + myAddedSearchParams.add(next); + } + } + + @Override + public void forceRefresh() { + // nothing + } + + @Override + public RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean refreshCacheIfNecessary() { + // nothing + return false; + } + + @Override + public Map> getActiveSearchParams() { + throw new UnsupportedOperationException(); + } + + @Override + public Map getActiveSearchParams(String theResourceName) { + RuntimeResourceDefinition nextResDef = myCtx.getResourceDefinition(theResourceName); + Map sps = new HashMap<>(); + for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) { + sps.put(nextSp.getName(), nextSp); + } + for (RuntimeSearchParam next : myAddedSearchParams) { + sps.put(next.getName(), next); + } + return sps; + } + + @Override + public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + throw new UnsupportedOperationException(); + } + + @Override + public List getActiveUniqueSearchParams(String theResourceName) { + throw new UnsupportedOperationException(); + } + + @Override + public void requestRefresh() { + // nothing + } + + @Override + public RuntimeSearchParam getSearchParamByName(RuntimeResourceDefinition theResourceDef, String theParamName) { + return null; + } + + @Override + public Collection getSearchParamsByResourceType(RuntimeResourceDefinition theResourceDef) { + return null; + } + } + +}