Allow runtime query of bound enum type
This commit is contained in:
parent
82c6d82444
commit
ab4deb406c
|
@ -47,14 +47,18 @@ public abstract class BaseRuntimeChildDatatypeDefinition extends BaseRuntimeDecl
|
|||
myDatatype = theDatatype;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this child has a bound type, this method will return the Enum type that
|
||||
* it is bound to. Otherwise, will return <code>null</code>.
|
||||
*/
|
||||
public Class<? extends Enum<?>> getBoundEnumType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getChildNameByDatatype(Class<? extends IBase> theDatatype) {
|
||||
Class<?> nextType = theDatatype;
|
||||
while (nextType.equals(Object.class) == false) {
|
||||
if (myDatatype.equals(nextType)) {
|
||||
return getElementName();
|
||||
}
|
||||
nextType = nextType.getSuperclass();
|
||||
public BaseRuntimeElementDefinition<?> getChildByName(String theName) {
|
||||
if (getElementName().equals(theName)) {
|
||||
return myElementDefinition;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -72,9 +76,13 @@ public abstract class BaseRuntimeChildDatatypeDefinition extends BaseRuntimeDecl
|
|||
}
|
||||
|
||||
@Override
|
||||
public BaseRuntimeElementDefinition<?> getChildByName(String theName) {
|
||||
if (getElementName().equals(theName)) {
|
||||
return myElementDefinition;
|
||||
public String getChildNameByDatatype(Class<? extends IBase> theDatatype) {
|
||||
Class<?> nextType = theDatatype;
|
||||
while (nextType.equals(Object.class) == false) {
|
||||
if (myDatatype.equals(nextType)) {
|
||||
return getElementName();
|
||||
}
|
||||
nextType = nextType.getSuperclass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -576,9 +576,10 @@ class ModelScanner {
|
|||
if (IPrimitiveType.class.isAssignableFrom(nextElementType)) {
|
||||
if (nextElementType.equals(BoundCodeDt.class)) {
|
||||
IValueSetEnumBinder<Enum<?>> binder = getBoundCodeBinder(next);
|
||||
def = new RuntimeChildPrimitiveBoundCodeDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder);
|
||||
Class<? extends Enum<?>> enumType = determineEnumTypeForBoundField(next);
|
||||
def = new RuntimeChildPrimitiveBoundCodeDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder, enumType);
|
||||
} else if (IBaseEnumeration.class.isAssignableFrom(nextElementType)) {
|
||||
Class<?> binderType = ReflectionUtil.getGenericCollectionTypeOfFieldWithSecondOrderForList(next);
|
||||
Class<? extends Enum<?>> binderType = determineEnumTypeForBoundField(next);
|
||||
def = new RuntimeChildPrimitiveEnumerationDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binderType);
|
||||
} else {
|
||||
def = new RuntimeChildPrimitiveDatatypeDefinition(next, elementName, descriptionAnnotation, childAnnotation, nextDatatype);
|
||||
|
@ -588,7 +589,8 @@ class ModelScanner {
|
|||
} else {
|
||||
if (IBoundCodeableConcept.class.isAssignableFrom(nextElementType)) {
|
||||
IValueSetEnumBinder<Enum<?>> binder = getBoundCodeBinder(next);
|
||||
def = new RuntimeChildCompositeBoundDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder);
|
||||
Class<? extends Enum<?>> enumType = determineEnumTypeForBoundField(next);
|
||||
def = new RuntimeChildCompositeBoundDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder, enumType);
|
||||
} else if (BaseNarrativeDt.class.isAssignableFrom(nextElementType) || INarrative.class.isAssignableFrom(nextElementType)) {
|
||||
def = new RuntimeChildNarrativeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype);
|
||||
} else {
|
||||
|
@ -618,6 +620,12 @@ class ModelScanner {
|
|||
}
|
||||
}
|
||||
|
||||
private Class<? extends Enum<?>> determineEnumTypeForBoundField(Field next) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends Enum<?>> enumType = (Class<? extends Enum<?>>) ReflectionUtil.getGenericCollectionTypeOfFieldWithSecondOrderForList(next);
|
||||
return enumType;
|
||||
}
|
||||
|
||||
private String scanPrimitiveDatatype(Class<? extends IPrimitiveType<?>> theClass, DatatypeDef theDatatypeDefinition) {
|
||||
ourLog.debug("Scanning resource class: {}", theClass.getName());
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.context;
|
|||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
|
||||
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||
|
@ -31,13 +32,15 @@ import ca.uhn.fhir.model.api.annotation.Description;
|
|||
public class RuntimeChildCompositeBoundDatatypeDefinition extends RuntimeChildCompositeDatatypeDefinition {
|
||||
|
||||
private IValueSetEnumBinder<Enum<?>> myBinder;
|
||||
private Class<? extends Enum<?>> myEnumType;
|
||||
|
||||
public RuntimeChildCompositeBoundDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype, IValueSetEnumBinder<Enum<?>> theBinder) {
|
||||
public RuntimeChildCompositeBoundDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype, IValueSetEnumBinder<Enum<?>> theBinder, Class<? extends Enum<?>> theEnumType) {
|
||||
super(theField, theElementName, theChildAnnotation, theDescriptionAnnotation, theDatatype);
|
||||
Validate.notNull(theBinder, "theBinder must not be null");
|
||||
Validate.notNull(theEnumType, "theEnumType must not be null");
|
||||
|
||||
myBinder = theBinder;
|
||||
if (theBinder==null) {
|
||||
throw new IllegalArgumentException("Binder must not be null");
|
||||
}
|
||||
myEnumType = theEnumType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -45,4 +48,9 @@ public class RuntimeChildCompositeBoundDatatypeDefinition extends RuntimeChildCo
|
|||
return myBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Enum<?>> getBoundEnumType() {
|
||||
return myEnumType;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,11 +30,18 @@ import ca.uhn.fhir.model.api.annotation.Description;
|
|||
public class RuntimeChildPrimitiveBoundCodeDatatypeDefinition extends RuntimeChildPrimitiveDatatypeDefinition {
|
||||
|
||||
private Object myBinder;
|
||||
private Class<? extends Enum<?>> myEnumType;
|
||||
|
||||
public RuntimeChildPrimitiveBoundCodeDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype, Object theBinder) {
|
||||
public RuntimeChildPrimitiveBoundCodeDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype, Object theBinder, Class<? extends Enum<?>> theEnumType) {
|
||||
super(theField, theElementName, theDescriptionAnnotation, theChildAnnotation, theDatatype);
|
||||
|
||||
myBinder = theBinder;
|
||||
myEnumType = theEnumType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Enum<?>> getBoundEnumType() {
|
||||
return myEnumType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,19 +30,24 @@ import ca.uhn.fhir.model.api.annotation.Description;
|
|||
public class RuntimeChildPrimitiveEnumerationDatatypeDefinition extends RuntimeChildPrimitiveDatatypeDefinition {
|
||||
|
||||
private Object myBinder;
|
||||
private Class<?> myEnumerationType;
|
||||
private Class<? extends Enum<?>> myEnumType;
|
||||
|
||||
public RuntimeChildPrimitiveEnumerationDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype, Class<?> theBinderType) {
|
||||
public RuntimeChildPrimitiveEnumerationDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype, Class<? extends Enum<?>> theBinderType) {
|
||||
super(theField, theElementName, theDescriptionAnnotation, theChildAnnotation, theDatatype);
|
||||
|
||||
myEnumerationType = theBinderType;
|
||||
myEnumType = theBinderType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Enum<?>> getBoundEnumType() {
|
||||
return myEnumType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInstanceConstructorArguments() {
|
||||
Object retVal = myBinder;
|
||||
if (retVal == null) {
|
||||
retVal = toEnumFactory(myEnumerationType);
|
||||
retVal = toEnumFactory(myEnumType);
|
||||
myBinder = retVal;
|
||||
}
|
||||
return retVal;
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package ca.uhn.fhir.ctx;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.BaseRuntimeChildDatatypeDefinition;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.MaritalStatusCodesEnum;
|
||||
|
||||
public class FhirContextDstu2Test {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirContextDstu2Test.class);
|
||||
|
||||
private FhirContext ourCtx = FhirContext.forDstu2();
|
||||
|
||||
@Test
|
||||
public void testQueryBoundCode() {
|
||||
RuntimeResourceDefinition patientType = ourCtx.getResourceDefinition(Patient.class);
|
||||
String childName = "gender";
|
||||
BaseRuntimeChildDatatypeDefinition genderChild = (BaseRuntimeChildDatatypeDefinition) patientType.getChildByName(childName);
|
||||
ourLog.trace(genderChild.getClass().getName());
|
||||
|
||||
assertEquals(AdministrativeGenderEnum.class, genderChild.getBoundEnumType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryBoundCodeableConcept() {
|
||||
RuntimeResourceDefinition patientType = ourCtx.getResourceDefinition(Patient.class);
|
||||
String childName = "maritalStatus";
|
||||
BaseRuntimeChildDatatypeDefinition genderChild = (BaseRuntimeChildDatatypeDefinition) patientType.getChildByName(childName);
|
||||
ourLog.trace(genderChild.getClass().getName());
|
||||
|
||||
assertEquals(MaritalStatusCodesEnum.class, genderChild.getBoundEnumType());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package org.hl7.fhir.dstu3.hapi.ctx;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.BaseRuntimeChildDatatypeDefinition;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
|
||||
public class FhirContextDstu3Test {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirContextDstu3Test.class);
|
||||
|
||||
private FhirContext ourCtx = FhirContext.forDstu3();
|
||||
|
||||
@Test
|
||||
public void testQueryBoundCode() {
|
||||
RuntimeResourceDefinition patientType = ourCtx.getResourceDefinition(Patient.class);
|
||||
String childName = "gender";
|
||||
BaseRuntimeChildDatatypeDefinition genderChild = (BaseRuntimeChildDatatypeDefinition) patientType.getChildByName(childName);
|
||||
ourLog.trace(genderChild.getClass().getName());
|
||||
|
||||
assertEquals(AdministrativeGender.class, genderChild.getBoundEnumType());
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue