add remove method to field list mutator (#4088)

* add remove method to field list mutator

* add test and Msg.code

* test passes

Co-authored-by: Ken Stevens <ken@smilecdr.com>
This commit is contained in:
Ken Stevens 2022-09-27 21:37:51 -04:00 committed by GitHub
parent bcdbb51fde
commit d63d71e879
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 3 deletions

View File

@ -89,6 +89,15 @@ public abstract class BaseRuntimeChildDefinition {
void addValue(IBase theTarget, IBase theValue); void addValue(IBase theTarget, IBase theValue);
void setValue(IBase theTarget, IBase theValue); void setValue(IBase theTarget, IBase theValue);
/**
* Remove an item from a list of values
* @param theTarget field to remove the item from (e.g. patient.name)
* @param theIndex the index of the item to be removed (e.g. 1 for patient.name[1])
*/
default void remove(IBase theTarget, int theIndex) {
// implemented in subclasses
}
} }
BaseRuntimeElementDefinition<?> findResourceReferenceDefinition(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) { BaseRuntimeElementDefinition<?> findResourceReferenceDefinition(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {

View File

@ -177,6 +177,18 @@ public abstract class BaseRuntimeDeclaredChildDefinition extends BaseRuntimeChil
public void setValue(IBase theTarget, IBase theValue) { public void setValue(IBase theTarget, IBase theValue) {
addValue(theTarget, theValue, true); addValue(theTarget, theValue, true);
} }
@Override
public void remove(IBase theTarget, int theIndex) {
List<IBase> existingList = (List<IBase>) getFieldValue(theTarget, myField);
if (existingList == null) {
throw new IndexOutOfBoundsException(Msg.code(2143) + "Can not remove element at index " + theIndex + " from list - List is null");
}
if (theIndex >= existingList.size()) {
throw new IndexOutOfBoundsException(Msg.code(2144) + "Can not remove element at index " + theIndex + " from list - List size is " + existingList.size());
}
existingList.remove(theIndex);
}
} }
private final class FieldPlainAccessor implements IAccessor { private final class FieldPlainAccessor implements IAccessor {
@ -205,6 +217,11 @@ public abstract class BaseRuntimeDeclaredChildDefinition extends BaseRuntimeChil
public void setValue(IBase theTarget, IBase theValue) { public void setValue(IBase theTarget, IBase theValue) {
addValue(theTarget, theValue); addValue(theTarget, theValue);
} }
@Override
public void remove(IBase theTarget, int theIndex) {
throw new UnsupportedOperationException(Msg.code(2142) + "Remove by index can only be called on a list-valued field. '" + myField.getName() + "' is a single-valued field.");
}
} }
private static void setFieldValue(IBase theTarget, Object theValue, Field theField) { private static void setFieldValue(IBase theTarget, Object theValue, Field theField) {

View File

@ -1,17 +1,21 @@
package ca.uhn.fhir.context; package ca.uhn.fhir.context;
import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.i18n.Msg;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
public class BaseRuntimeElementDefinitionTest { public class BaseRuntimeElementDefinitionTest {
private static FhirContext ourFhirContext = FhirContext.forR4Cached();
@Test @Test
public void testNewInstance_InvalidArgumentType() { public void testNewInstance_InvalidArgumentType() {
FhirContext ctx = FhirContext.forR4();
BaseRuntimeElementDefinition<?> def = ctx.getElementDefinition("string"); BaseRuntimeElementDefinition<?> def = ourFhirContext.getElementDefinition("string");
try { try {
def.newInstance(123); def.newInstance(123);
@ -21,4 +25,36 @@ public class BaseRuntimeElementDefinitionTest {
} }
} }
@Test
void mutator_remove() {
Patient patient = new Patient();
patient.addName().setFamily("A1");
patient.addName().setFamily("A2");
assertEquals(2, patient.getName().size());
assertEquals("A1", patient.getName().get(0).getFamily());
RuntimeResourceDefinition def = ourFhirContext.getResourceDefinition(patient);
BaseRuntimeChildDefinition child = def.getChildByName("name");
BaseRuntimeChildDefinition.IMutator mutator = child.getMutator();
mutator.remove(patient, 0);
assertEquals(1, patient.getName().size());
assertEquals("A2", patient.getName().get(0).getFamily());
}
@Test
void mutator_remov_nonList() {
Patient patient = new Patient();
patient.setGender(Enumerations.AdministrativeGender.MALE);
RuntimeResourceDefinition def = ourFhirContext.getResourceDefinition(patient);
BaseRuntimeChildDefinition child = def.getChildByName("gender");
BaseRuntimeChildDefinition.IMutator mutator = child.getMutator();
try {
mutator.remove(patient, 0);
fail();
} catch (UnsupportedOperationException e) {
assertEquals("HAPI-2142: Remove by index can only be called on a list-valued field. 'gender' is a single-valued field.", e.getMessage());
}
}
} }