WIP on choice specialization
This commit is contained in:
parent
a5eddc3837
commit
e824085330
|
@ -46,13 +46,15 @@ public class RuntimeChildAny extends RuntimeChildChoiceDefinition {
|
|||
void sealAndInitialize(
|
||||
FhirContext theContext,
|
||||
Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||
List<Class<? extends IBase>> choiceTypes = new ArrayList<Class<? extends IBase>>();
|
||||
List<Class<? extends IBase>> choiceTypes = new ArrayList<>();
|
||||
List<Class<? extends IBase>> spacializationChoiceTypes = new ArrayList<>();
|
||||
|
||||
for (Class<? extends IBase> next : theClassToElementDefinitions.keySet()) {
|
||||
if (next.equals(XhtmlDt.class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean isSpecialization = false;
|
||||
BaseRuntimeElementDefinition<?> nextDef = theClassToElementDefinitions.get(next);
|
||||
if (nextDef instanceof IRuntimeDatatypeDefinition) {
|
||||
if (((IRuntimeDatatypeDefinition) nextDef).isSpecialization()) {
|
||||
|
@ -60,36 +62,44 @@ public class RuntimeChildAny extends RuntimeChildChoiceDefinition {
|
|||
* Things like BoundCodeDt shoudn't be considered as valid options for an "any" choice, since
|
||||
* we'll already have CodeDt as an option
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
isSpecialization = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (IResource.class.isAssignableFrom(next)
|
||||
|| IDatatype.class.isAssignableFrom(next)
|
||||
|| IBaseDatatype.class.isAssignableFrom(next)
|
||||
|| IBaseReference.class.isAssignableFrom(next)) {
|
||||
choiceTypes.add(next);
|
||||
}
|
||||
}
|
||||
Collections.sort(choiceTypes, new Comparator<Class<?>>() {
|
||||
@Override
|
||||
public int compare(Class<?> theO1, Class<?> theO2) {
|
||||
boolean o1res = IResource.class.isAssignableFrom(theO1);
|
||||
boolean o2res = IResource.class.isAssignableFrom(theO2);
|
||||
if (o1res && o2res) {
|
||||
return theO1.getSimpleName().compareTo(theO2.getSimpleName());
|
||||
} else if (o1res) {
|
||||
return -1;
|
||||
} else if (o1res == false && o2res == false) {
|
||||
return 0;
|
||||
if (isSpecialization) {
|
||||
spacializationChoiceTypes.add(next);
|
||||
} else {
|
||||
return 1;
|
||||
choiceTypes.add(next);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setChoiceTypes(choiceTypes);
|
||||
choiceTypes.sort(new ResourceTypeNameComparator());
|
||||
spacializationChoiceTypes.sort(new ResourceTypeNameComparator());
|
||||
|
||||
setChoiceTypes(choiceTypes, spacializationChoiceTypes);
|
||||
|
||||
super.sealAndInitialize(theContext, theClassToElementDefinitions);
|
||||
}
|
||||
|
||||
private static class ResourceTypeNameComparator implements Comparator<Class<?>> {
|
||||
@Override
|
||||
public int compare(Class<?> theO1, Class<?> theO2) {
|
||||
boolean o1res = IResource.class.isAssignableFrom(theO1);
|
||||
boolean o2res = IResource.class.isAssignableFrom(theO2);
|
||||
if (o1res && o2res) {
|
||||
return theO1.getSimpleName().compareTo(theO2.getSimpleName());
|
||||
} else if (o1res) {
|
||||
return -1;
|
||||
} else if (o1res == false && o2res == false) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,14 @@ package ca.uhn.fhir.context;
|
|||
import ca.uhn.fhir.i18n.Msg;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import jakarta.annotation.Nonnull;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.thymeleaf.util.Validate;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
|
@ -45,6 +47,7 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myDatatypeToElementDefinition;
|
||||
private String myReferenceSuffix;
|
||||
private List<Class<? extends IBaseResource>> myResourceTypes;
|
||||
private List<Class<? extends IBase>> mySpecializationChoiceTypes = List.of();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -70,8 +73,11 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
|
||||
}
|
||||
|
||||
void setChoiceTypes(List<Class<? extends IBase>> theChoiceTypes) {
|
||||
void setChoiceTypes(@Nonnull List<Class<? extends IBase>> theChoiceTypes, @Nonnull List<Class<? extends IBase>> theSpecializationChoiceTypes) {
|
||||
Validate.notNull(theChoiceTypes, "theChoiceTypes must not be null");
|
||||
Validate.notNull(theSpecializationChoiceTypes, "theSpecializationChoiceTypes must not be null");
|
||||
myChoiceTypes = Collections.unmodifiableList(theChoiceTypes);
|
||||
mySpecializationChoiceTypes = Collections.unmodifiableList(theSpecializationChoiceTypes);
|
||||
}
|
||||
|
||||
public List<Class<? extends IBase>> getChoices() {
|
||||
|
@ -96,14 +102,24 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
void sealAndInitialize(
|
||||
FhirContext theContext,
|
||||
Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||
myNameToChildDefinition = new HashMap<String, BaseRuntimeElementDefinition<?>>();
|
||||
myDatatypeToElementName = new HashMap<Class<? extends IBase>, String>();
|
||||
myDatatypeToElementDefinition = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
|
||||
myResourceTypes = new ArrayList<Class<? extends IBaseResource>>();
|
||||
myNameToChildDefinition = new HashMap<>();
|
||||
myDatatypeToElementName = new HashMap<>();
|
||||
myDatatypeToElementDefinition = new HashMap<>();
|
||||
myResourceTypes = new ArrayList<>();
|
||||
|
||||
myReferenceSuffix = "Reference";
|
||||
|
||||
for (Class<? extends IBase> next : myChoiceTypes) {
|
||||
sealAndInitializeChoiceTypes(theContext, theClassToElementDefinitions, mySpecializationChoiceTypes, true);
|
||||
sealAndInitializeChoiceTypes(theContext, theClassToElementDefinitions, myChoiceTypes, false);
|
||||
|
||||
myNameToChildDefinition = Collections.unmodifiableMap(myNameToChildDefinition);
|
||||
myDatatypeToElementName = Collections.unmodifiableMap(myDatatypeToElementName);
|
||||
myDatatypeToElementDefinition = Collections.unmodifiableMap(myDatatypeToElementDefinition);
|
||||
myResourceTypes = Collections.unmodifiableList(myResourceTypes);
|
||||
}
|
||||
|
||||
private void sealAndInitializeChoiceTypes(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions, List<Class<? extends IBase>> choiceTypes, boolean theIsSpecilization) {
|
||||
for (Class<? extends IBase> next : choiceTypes) {
|
||||
|
||||
String elementName = null;
|
||||
BaseRuntimeElementDefinition<?> nextDef;
|
||||
|
@ -112,8 +128,10 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
elementName = getElementName() + StringUtils.capitalize(next.getSimpleName());
|
||||
nextDef = findResourceReferenceDefinition(theClassToElementDefinitions);
|
||||
|
||||
myNameToChildDefinition.put(getElementName() + "Reference", nextDef);
|
||||
myNameToChildDefinition.put(getElementName() + "Resource", nextDef);
|
||||
if (!theIsSpecilization) {
|
||||
myNameToChildDefinition.put(getElementName() + "Reference", nextDef);
|
||||
myNameToChildDefinition.put(getElementName() + "Resource", nextDef);
|
||||
}
|
||||
|
||||
myResourceTypes.add((Class<? extends IBaseResource>) next);
|
||||
|
||||
|
@ -147,21 +165,23 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
}
|
||||
|
||||
// I don't see how elementName could be null here, but eclipse complains..
|
||||
if (elementName != null) {
|
||||
if (myNameToChildDefinition.containsKey(elementName) == false || !nonPreferred) {
|
||||
if (!theIsSpecilization) {
|
||||
if (elementName != null) {
|
||||
if (myNameToChildDefinition.containsKey(elementName) == false || !nonPreferred) {
|
||||
myNameToChildDefinition.put(elementName, nextDef);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a resource reference, the element name is "fooNameReference"
|
||||
*/
|
||||
if (IBaseResource.class.isAssignableFrom(next) || IBaseReference.class.isAssignableFrom(next)) {
|
||||
next = theContext.getVersion().getResourceReferenceType();
|
||||
elementName = getElementName() + myReferenceSuffix;
|
||||
myNameToChildDefinition.put(elementName, nextDef);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a resource reference, the element name is "fooNameReference"
|
||||
*/
|
||||
if (IBaseResource.class.isAssignableFrom(next) || IBaseReference.class.isAssignableFrom(next)) {
|
||||
next = theContext.getVersion().getResourceReferenceType();
|
||||
elementName = getElementName() + myReferenceSuffix;
|
||||
myNameToChildDefinition.put(elementName, nextDef);
|
||||
}
|
||||
|
||||
myDatatypeToElementDefinition.put(next, nextDef);
|
||||
|
||||
if (myDatatypeToElementName.containsKey(next)) {
|
||||
|
@ -175,11 +195,6 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
myDatatypeToElementName.put(next, elementName);
|
||||
}
|
||||
}
|
||||
|
||||
myNameToChildDefinition = Collections.unmodifiableMap(myNameToChildDefinition);
|
||||
myDatatypeToElementName = Collections.unmodifiableMap(myDatatypeToElementName);
|
||||
myDatatypeToElementDefinition = Collections.unmodifiableMap(myDatatypeToElementDefinition);
|
||||
myResourceTypes = Collections.unmodifiableList(myResourceTypes);
|
||||
}
|
||||
|
||||
public List<Class<? extends IBaseResource>> getResourceTypes() {
|
||||
|
|
|
@ -82,7 +82,7 @@ public class RuntimeChildDeclaredExtensionDefinition extends RuntimeChildChoiceD
|
|||
choiceTypes.add(theChildType);
|
||||
}
|
||||
|
||||
setChoiceTypes(choiceTypes);
|
||||
setChoiceTypes(choiceTypes, List.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -120,7 +120,7 @@ class ValidatorWrapper {
|
|||
try {
|
||||
v = new InstanceValidator(theWorkerContext, evaluationCtx, xverManager);
|
||||
} catch (Exception e) {
|
||||
throw new ConfigurationException(Msg.code(648) + e);
|
||||
throw new ConfigurationException(Msg.code(648) + e.getMessage(), e);
|
||||
}
|
||||
|
||||
v.setAssumeValidRestReferences(isAssumeValidRestReferences());
|
||||
|
|
Loading…
Reference in New Issue