Fix #423 - Encode custom types with custom type fields correctly
This commit is contained in:
parent
779b66c5e4
commit
b0d19c3a65
|
@ -1,29 +0,0 @@
|
|||
package ca.uhn.fhir.context;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class MultiVersionModelScannerTest {
|
||||
|
||||
@Test
|
||||
public void testScan() {
|
||||
FhirContext ctx = FhirContext.forDstu1();
|
||||
|
||||
RuntimeResourceDefinition def;
|
||||
def = ctx.getResourceDefinition(ca.uhn.fhir.model.dstu2.resource.Patient.class);
|
||||
assertEquals(FhirVersionEnum.DSTU2, def.getStructureVersion());
|
||||
|
||||
def = ctx.getResourceDefinition(new ca.uhn.fhir.model.dstu2.resource.Patient());
|
||||
assertEquals(FhirVersionEnum.DSTU2, def.getStructureVersion());
|
||||
|
||||
def = ctx.getResourceDefinition("Patient");
|
||||
assertEquals(FhirVersionEnum.DSTU1, def.getStructureVersion());
|
||||
assertEquals(ca.uhn.fhir.model.dstu.resource.Patient.class, def.getImplementingClass());
|
||||
|
||||
def = ctx.getResourceDefinition(FhirVersionEnum.DSTU2, "Patient");
|
||||
assertEquals(FhirVersionEnum.DSTU2, def.getStructureVersion());
|
||||
assertEquals(ca.uhn.fhir.model.dstu2.resource.Patient.class, def.getImplementingClass());
|
||||
}
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@ import org.hamcrest.Matchers;
|
|||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
|
@ -64,14 +65,14 @@ public class MultiVersionXmlParserTest {
|
|||
try {
|
||||
ourCtxDstu1.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Patient.class, res);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("This parser is for FHIR version DSTU1 - Can not parse a structure for version DSTU2", e.getMessage());
|
||||
} catch (ConfigurationException e) {
|
||||
assertEquals("This context is for FHIR version \"DSTU1\" but the class \"ca.uhn.fhir.model.dstu2.resource.Patient\" is for version \"DSTU2\"", e.getMessage());
|
||||
}
|
||||
try {
|
||||
ourCtxDstu2.newXmlParser().parseResource(ca.uhn.fhir.model.dstu.resource.Patient.class, res);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("This parser is for FHIR version DSTU2 - Can not parse a structure for version DSTU1", e.getMessage());
|
||||
} catch (ConfigurationException e) {
|
||||
assertEquals("This context is for FHIR version \"DSTU2\" but the class \"ca.uhn.fhir.model.dstu.resource.Patient\" is for version \"DSTU1\"", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,27 +10,12 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
|
|||
|
||||
public class FhirContextTest {
|
||||
|
||||
@Test
|
||||
public void testWrongVersionDoesntGetInContext1() {
|
||||
@Test
|
||||
public void testWrongVersionDoesntGetInContext1() {
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu1();
|
||||
RuntimeResourceDefinition def = ctx.getResourceDefinition("Patient");
|
||||
assertEquals(Patient.class, def.getImplementingClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongVersionDoesntGetInContext2() {
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu1();
|
||||
RuntimeResourceDefinition def = ctx.getResourceDefinition("Patient");
|
||||
assertEquals(Patient.class, def.getImplementingClass());
|
||||
|
||||
ctx = FhirContext.forDstu1();
|
||||
def = ctx.getResourceDefinition(ca.uhn.fhir.model.dstu2.resource.Patient.class);
|
||||
assertEquals(ca.uhn.fhir.model.dstu2.resource.Patient.class, def.getImplementingClass());
|
||||
def = ctx.getResourceDefinition("Patient");
|
||||
assertEquals(Patient.class, def.getImplementingClass());
|
||||
|
||||
}
|
||||
FhirContext ctx = FhirContext.forDstu1();
|
||||
RuntimeResourceDefinition def = ctx.getResourceDefinition("Patient");
|
||||
assertEquals(Patient.class, def.getImplementingClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -72,19 +72,59 @@ import ca.uhn.fhir.util.ReflectionUtil;
|
|||
public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> extends BaseRuntimeElementDefinition<T> {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseRuntimeElementCompositeDefinition.class);
|
||||
private Map<String, Integer> forcedOrder = null;
|
||||
private List<BaseRuntimeChildDefinition> myChildren = new ArrayList<BaseRuntimeChildDefinition>();
|
||||
private List<BaseRuntimeChildDefinition> myChildrenAndExtensions;
|
||||
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions;
|
||||
private FhirContext myContext;
|
||||
private Map<String, BaseRuntimeChildDefinition> myNameToChild = new HashMap<String, BaseRuntimeChildDefinition>();
|
||||
|
||||
private List<ScannedField> myScannedFields = new ArrayList<BaseRuntimeElementCompositeDefinition.ScannedField>();
|
||||
private volatile boolean mySealed;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public BaseRuntimeElementCompositeDefinition(String theName, Class<? extends T> theImplementingClass, boolean theStandardType, FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||
super(theName, theImplementingClass, theStandardType);
|
||||
|
||||
myContext = theContext;
|
||||
myClassToElementDefinitions = theClassToElementDefinitions;
|
||||
|
||||
/*
|
||||
* We scan classes for annotated fields in the class but also all of its superclasses
|
||||
*/
|
||||
Class<? extends IBase> current = theImplementingClass;
|
||||
LinkedList<Class<? extends IBase>> classes = new LinkedList<Class<? extends IBase>>();
|
||||
do {
|
||||
if (forcedOrder == null) {
|
||||
ChildOrder childOrder = current.getAnnotation(ChildOrder.class);
|
||||
if (childOrder != null) {
|
||||
forcedOrder = new HashMap<String, Integer>();
|
||||
for (int i = 0; i < childOrder.names().length; i++) {
|
||||
forcedOrder.put(childOrder.names()[i], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
classes .push(current);
|
||||
if (IBase.class.isAssignableFrom(current.getSuperclass())) {
|
||||
current = (Class<? extends IBase>) current.getSuperclass();
|
||||
} else {
|
||||
current = null;
|
||||
}
|
||||
} while (current != null);
|
||||
|
||||
Set<Field> fields = new HashSet<Field>();
|
||||
for (Class<? extends IBase> nextClass : classes) {
|
||||
int fieldIndexInClass = 0;
|
||||
for (Field next : nextClass.getDeclaredFields()) {
|
||||
if (fields.add(next)) {
|
||||
ScannedField scannedField = new ScannedField(next, theImplementingClass, fieldIndexInClass == 0);
|
||||
if (scannedField.getChildAnnotation() != null) {
|
||||
myScannedFields.add(scannedField);
|
||||
fieldIndexInClass++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void addChild(BaseRuntimeChildDefinition theNext) {
|
||||
|
@ -116,13 +156,14 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
validateSealed();
|
||||
return myChildren;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<BaseRuntimeChildDefinition> getChildrenAndExtension() {
|
||||
validateSealed();
|
||||
return myChildrenAndExtensions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Has this class been sealed
|
||||
*/
|
||||
|
@ -130,41 +171,28 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
return mySealed;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void scanCompositeElementForChildren(Class<? extends IBase> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition) {
|
||||
void populateScanAlso(Set<Class<? extends IBase>> theScanAlso) {
|
||||
for (ScannedField next : myScannedFields) {
|
||||
if (IBase.class.isAssignableFrom(next.getElementType())) {
|
||||
if (next.getElementType().isInterface() == false && Modifier.isAbstract(next.getElementType().getModifiers()) == false) {
|
||||
theScanAlso.add((Class<? extends IBase>) next.getElementType());
|
||||
}
|
||||
}
|
||||
for (Class<? extends IBase> nextChildType : next.getChoiceTypes()) {
|
||||
if (nextChildType.isInterface() == false && Modifier.isAbstract(nextChildType.getModifiers()) == false) {
|
||||
theScanAlso.add(nextChildType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scanCompositeElementForChildren() {
|
||||
Set<String> elementNames = new HashSet<String>();
|
||||
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> orderToElementDef = new TreeMap<Integer, BaseRuntimeDeclaredChildDefinition>();
|
||||
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> orderToExtensionDef = new TreeMap<Integer, BaseRuntimeDeclaredChildDefinition>();
|
||||
|
||||
LinkedList<Class<? extends IBase>> classes = new LinkedList<Class<? extends IBase>>();
|
||||
|
||||
/*
|
||||
* We scan classes for annotated fields in the class but also all of its superclasses
|
||||
*/
|
||||
Class<? extends IBase> current = theClass;
|
||||
Map<String, Integer> forcedOrder = null;
|
||||
do {
|
||||
if (forcedOrder == null) {
|
||||
ChildOrder childOrder = current.getAnnotation(ChildOrder.class);
|
||||
if (childOrder != null) {
|
||||
forcedOrder = new HashMap<String, Integer>();
|
||||
for (int i = 0; i < childOrder.names().length; i++) {
|
||||
forcedOrder.put(childOrder.names()[i], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
classes.push(current);
|
||||
if (IBase.class.isAssignableFrom(current.getSuperclass())) {
|
||||
current = (Class<? extends IBase>) current.getSuperclass();
|
||||
} else {
|
||||
current = null;
|
||||
}
|
||||
} while (current != null);
|
||||
|
||||
for (Class<? extends IBase> next : classes) {
|
||||
scanCompositeElementForChildren(next, elementNames, orderToElementDef, orderToExtensionDef);
|
||||
}
|
||||
scanCompositeElementForChildren(elementNames, orderToElementDef, orderToExtensionDef);
|
||||
|
||||
if (forcedOrder != null) {
|
||||
/*
|
||||
|
@ -207,42 +235,38 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
for (Integer i : orders) {
|
||||
BaseRuntimeChildDefinition nextChild = orderToElementDef.get(i);
|
||||
if (nextChild != null) {
|
||||
theDefinition.addChild(nextChild);
|
||||
this.addChild(nextChild);
|
||||
}
|
||||
BaseRuntimeDeclaredChildDefinition nextExt = orderToExtensionDef.get(i);
|
||||
if (nextExt != null) {
|
||||
theDefinition.addExtension((RuntimeChildDeclaredExtensionDefinition) nextExt);
|
||||
this.addExtension((RuntimeChildDeclaredExtensionDefinition) nextExt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void scanCompositeElementForChildren(Class<? extends IBase> theClass, Set<String> elementNames, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToElementDef,
|
||||
private void scanCompositeElementForChildren(Set<String> elementNames, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToElementDef,
|
||||
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToExtensionDef) {
|
||||
int baseElementOrder = theOrderToElementDef.isEmpty() ? 0 : theOrderToElementDef.lastEntry().getKey() + 1;
|
||||
int baseElementOrder = 0;
|
||||
|
||||
for (Field next : theClass.getDeclaredFields()) {
|
||||
|
||||
if (Modifier.isFinal(next.getModifiers())) {
|
||||
ourLog.trace("Ignoring constant {} on target type {}", next.getName(), theClass);
|
||||
continue;
|
||||
for (ScannedField next : myScannedFields) {
|
||||
if (next.isFirstFieldInNewClass()) {
|
||||
baseElementOrder = theOrderToElementDef.isEmpty() ? 0 : theOrderToElementDef.lastEntry().getKey() + 1;
|
||||
}
|
||||
|
||||
Class<?> declaringClass = next.getField().getDeclaringClass();
|
||||
|
||||
Child childAnnotation = ModelScanner.pullAnnotation(next, Child.class);
|
||||
if (childAnnotation == null) {
|
||||
ourLog.trace("Ignoring non @Child field {} on target type {}", next.getName(), theClass);
|
||||
continue;
|
||||
}
|
||||
|
||||
Description descriptionAnnotation = ModelScanner.pullAnnotation(next, Description.class);
|
||||
Description descriptionAnnotation = ModelScanner.pullAnnotation(next.getField(), Description.class);
|
||||
|
||||
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> orderMap = theOrderToElementDef;
|
||||
Extension extensionAttr = ModelScanner.pullAnnotation(next, Extension.class);
|
||||
Extension extensionAttr = ModelScanner.pullAnnotation(next.getField(), Extension.class);
|
||||
if (extensionAttr != null) {
|
||||
orderMap = theOrderToExtensionDef;
|
||||
}
|
||||
|
||||
Child childAnnotation = next.getChildAnnotation();
|
||||
Field nextField = next.getField();
|
||||
String elementName = childAnnotation.name();
|
||||
int order = childAnnotation.order();
|
||||
boolean childIsChoiceType = false;
|
||||
|
@ -265,8 +289,8 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
}
|
||||
}
|
||||
if (order == Child.REPLACE_PARENT) {
|
||||
throw new ConfigurationException("Field " + next.getName() + "' on target type " + theClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT
|
||||
+ ") but no parent element with extension URL " + extensionAttr.url() + " could be found on type " + next.getDeclaringClass().getSimpleName());
|
||||
throw new ConfigurationException("Field " + nextField.getName() + "' on target type " + declaringClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT
|
||||
+ ") but no parent element with extension URL " + extensionAttr.url() + " could be found on type " + nextField.getDeclaringClass().getSimpleName());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -291,8 +315,8 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
}
|
||||
}
|
||||
if (order == Child.REPLACE_PARENT) {
|
||||
throw new ConfigurationException("Field " + next.getName() + "' on target type " + theClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT
|
||||
+ ") but no parent element with name " + elementName + " could be found on type " + next.getDeclaringClass().getSimpleName());
|
||||
throw new ConfigurationException("Field " + nextField.getName() + "' on target type " + declaringClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT
|
||||
+ ") but no parent element with name " + elementName + " could be found on type " + nextField.getDeclaringClass().getSimpleName());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -300,7 +324,7 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
}
|
||||
|
||||
if (order < 0 && order != Child.ORDER_UNKNOWN) {
|
||||
throw new ConfigurationException("Invalid order '" + order + "' on @Child for field '" + next.getName() + "' on target type: " + theClass);
|
||||
throw new ConfigurationException("Invalid order '" + order + "' on @Child for field '" + nextField.getName() + "' on target type: " + declaringClass);
|
||||
}
|
||||
|
||||
if (order != Child.ORDER_UNKNOWN && !orderIsReplaceParent) {
|
||||
|
@ -319,40 +343,37 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
}
|
||||
}
|
||||
|
||||
List<Class<? extends IBase>> choiceTypes = new ArrayList<Class<? extends IBase>>();
|
||||
for (Class<? extends IBase> nextChoiceType : childAnnotation.type()) {
|
||||
choiceTypes.add(nextChoiceType);
|
||||
}
|
||||
|
||||
List<Class<? extends IBase>> choiceTypes = next.getChoiceTypes();
|
||||
|
||||
if (orderMap.containsKey(order)) {
|
||||
throw new ConfigurationException("Detected duplicate field order '" + childAnnotation.order() + "' for element named '" + elementName + "' in type '" + theClass.getCanonicalName() + "' - Already had: " + orderMap.get(order).getElementName());
|
||||
throw new ConfigurationException("Detected duplicate field order '" + childAnnotation.order() + "' for element named '" + elementName + "' in type '" + declaringClass.getCanonicalName() + "' - Already had: " + orderMap.get(order).getElementName());
|
||||
}
|
||||
|
||||
if (elementNames.contains(elementName)) {
|
||||
throw new ConfigurationException("Detected duplicate field name '" + elementName + "' in type '" + theClass.getCanonicalName() + "'");
|
||||
throw new ConfigurationException("Detected duplicate field name '" + elementName + "' in type '" + declaringClass.getCanonicalName() + "'");
|
||||
}
|
||||
|
||||
Class<?> nextElementType = ModelScanner.determineElementType(next);
|
||||
Class<?> nextElementType = next.getElementType();
|
||||
|
||||
BaseRuntimeDeclaredChildDefinition def;
|
||||
if (childAnnotation.name().equals("extension") && IBaseExtension.class.isAssignableFrom(nextElementType)) {
|
||||
def = new RuntimeChildExtension(next, childAnnotation.name(), childAnnotation, descriptionAnnotation);
|
||||
def = new RuntimeChildExtension(nextField, childAnnotation.name(), childAnnotation, descriptionAnnotation);
|
||||
} else if (childAnnotation.name().equals("modifierExtension") && IBaseExtension.class.isAssignableFrom(nextElementType)) {
|
||||
def = new RuntimeChildExtension(next, childAnnotation.name(), childAnnotation, descriptionAnnotation);
|
||||
def = new RuntimeChildExtension(nextField, childAnnotation.name(), childAnnotation, descriptionAnnotation);
|
||||
} else if (BaseContainedDt.class.isAssignableFrom(nextElementType) || (childAnnotation.name().equals("contained") && IBaseResource.class.isAssignableFrom(nextElementType))) {
|
||||
/*
|
||||
* Child is contained resources
|
||||
*/
|
||||
def = new RuntimeChildContainedResources(next, childAnnotation, descriptionAnnotation, elementName);
|
||||
def = new RuntimeChildContainedResources(nextField, childAnnotation, descriptionAnnotation, elementName);
|
||||
} else if (IAnyResource.class.isAssignableFrom(nextElementType) || IResource.class.equals(nextElementType)) {
|
||||
/*
|
||||
* Child is a resource as a direct child, as in Bundle.entry.resource
|
||||
*/
|
||||
def = new RuntimeChildDirectResource(next, childAnnotation, descriptionAnnotation, elementName);
|
||||
def = new RuntimeChildDirectResource(nextField, childAnnotation, descriptionAnnotation, elementName);
|
||||
} else {
|
||||
childIsChoiceType |= choiceTypes.size() > 1;
|
||||
if (childIsChoiceType && !BaseResourceReferenceDt.class.isAssignableFrom(nextElementType) && !IBaseReference.class.isAssignableFrom(nextElementType)) {
|
||||
def = new RuntimeChildChoiceDefinition(next, elementName, childAnnotation, descriptionAnnotation, choiceTypes);
|
||||
def = new RuntimeChildChoiceDefinition(nextField, elementName, childAnnotation, descriptionAnnotation, choiceTypes);
|
||||
} else if (extensionAttr != null) {
|
||||
/*
|
||||
* Child is an extension
|
||||
|
@ -361,13 +382,13 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
|
||||
Object binder = null;
|
||||
if (BoundCodeDt.class.isAssignableFrom(nextElementType) || IBoundCodeableConcept.class.isAssignableFrom(nextElementType)) {
|
||||
binder = ModelScanner.getBoundCodeBinder(next);
|
||||
binder = ModelScanner.getBoundCodeBinder(nextField);
|
||||
}
|
||||
|
||||
def = new RuntimeChildDeclaredExtensionDefinition(next, childAnnotation, descriptionAnnotation, extensionAttr, elementName, extensionAttr.url(), et, binder);
|
||||
def = new RuntimeChildDeclaredExtensionDefinition(nextField, childAnnotation, descriptionAnnotation, extensionAttr, elementName, extensionAttr.url(), et, binder);
|
||||
|
||||
if (IBaseEnumeration.class.isAssignableFrom(nextElementType)) {
|
||||
((RuntimeChildDeclaredExtensionDefinition)def).setEnumerationType(ReflectionUtil.getGenericCollectionTypeOfFieldWithSecondOrderForList(next));
|
||||
((RuntimeChildDeclaredExtensionDefinition)def).setEnumerationType(ReflectionUtil.getGenericCollectionTypeOfFieldWithSecondOrderForList(nextField));
|
||||
}
|
||||
} else if (BaseResourceReferenceDt.class.isAssignableFrom(nextElementType) || IBaseReference.class.isAssignableFrom(nextElementType)) {
|
||||
/*
|
||||
|
@ -379,11 +400,11 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
refTypesList.add(myContext.getVersion().getVersion().isRi() ? IAnyResource.class : IResource.class);
|
||||
continue;
|
||||
} else if (IBaseResource.class.isAssignableFrom(nextType) == false) {
|
||||
throw new ConfigurationException("Field '" + next.getName() + "' in class '" + next.getDeclaringClass().getCanonicalName() + "' is of type " + BaseResourceReferenceDt.class + " but contains a non-resource type: " + nextType.getCanonicalName());
|
||||
throw new ConfigurationException("Field '" + nextField.getName() + "' in class '" + nextField.getDeclaringClass().getCanonicalName() + "' is of type " + BaseResourceReferenceDt.class + " but contains a non-resource type: " + nextType.getCanonicalName());
|
||||
}
|
||||
refTypesList.add((Class<? extends IBaseResource>) nextType);
|
||||
}
|
||||
def = new RuntimeChildResourceDefinition(next, elementName, childAnnotation, descriptionAnnotation, refTypesList);
|
||||
def = new RuntimeChildResourceDefinition(nextField, elementName, childAnnotation, descriptionAnnotation, refTypesList);
|
||||
|
||||
} else if (IResourceBlock.class.isAssignableFrom(nextElementType) || IBaseBackboneElement.class.isAssignableFrom(nextElementType)
|
||||
|| IBaseDatatypeElement.class.isAssignableFrom(nextElementType)) {
|
||||
|
@ -392,43 +413,43 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
*/
|
||||
|
||||
Class<? extends IBase> blockDef = (Class<? extends IBase>) nextElementType;
|
||||
def = new RuntimeChildResourceBlockDefinition(myContext, next, childAnnotation, descriptionAnnotation, elementName, blockDef);
|
||||
def = new RuntimeChildResourceBlockDefinition(myContext, nextField, childAnnotation, descriptionAnnotation, elementName, blockDef);
|
||||
} else if (IDatatype.class.equals(nextElementType) || IElement.class.equals(nextElementType) || "Type".equals(nextElementType.getSimpleName())
|
||||
|| IBaseDatatype.class.equals(nextElementType)) {
|
||||
|
||||
def = new RuntimeChildAny(next, elementName, childAnnotation, descriptionAnnotation);
|
||||
def = new RuntimeChildAny(nextField, elementName, childAnnotation, descriptionAnnotation);
|
||||
} else if (IDatatype.class.isAssignableFrom(nextElementType) || IPrimitiveType.class.isAssignableFrom(nextElementType) || ICompositeType.class.isAssignableFrom(nextElementType)
|
||||
|| IBaseDatatype.class.isAssignableFrom(nextElementType) || IBaseExtension.class.isAssignableFrom(nextElementType)) {
|
||||
Class<? extends IBase> nextDatatype = (Class<? extends IBase>) nextElementType;
|
||||
|
||||
if (IPrimitiveType.class.isAssignableFrom(nextElementType)) {
|
||||
if (nextElementType.equals(BoundCodeDt.class)) {
|
||||
IValueSetEnumBinder<Enum<?>> binder = ModelScanner.getBoundCodeBinder(next);
|
||||
Class<? extends Enum<?>> enumType = ModelScanner.determineEnumTypeForBoundField(next);
|
||||
def = new RuntimeChildPrimitiveBoundCodeDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder, enumType);
|
||||
IValueSetEnumBinder<Enum<?>> binder = ModelScanner.getBoundCodeBinder(nextField);
|
||||
Class<? extends Enum<?>> enumType = ModelScanner.determineEnumTypeForBoundField(nextField);
|
||||
def = new RuntimeChildPrimitiveBoundCodeDatatypeDefinition(nextField, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder, enumType);
|
||||
} else if (IBaseEnumeration.class.isAssignableFrom(nextElementType)) {
|
||||
Class<? extends Enum<?>> binderType = ModelScanner.determineEnumTypeForBoundField(next);
|
||||
def = new RuntimeChildPrimitiveEnumerationDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binderType);
|
||||
Class<? extends Enum<?>> binderType = ModelScanner.determineEnumTypeForBoundField(nextField);
|
||||
def = new RuntimeChildPrimitiveEnumerationDatatypeDefinition(nextField, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binderType);
|
||||
} else {
|
||||
def = new RuntimeChildPrimitiveDatatypeDefinition(next, elementName, descriptionAnnotation, childAnnotation, nextDatatype);
|
||||
def = new RuntimeChildPrimitiveDatatypeDefinition(nextField, elementName, descriptionAnnotation, childAnnotation, nextDatatype);
|
||||
}
|
||||
} else {
|
||||
if (IBoundCodeableConcept.class.isAssignableFrom(nextElementType)) {
|
||||
IValueSetEnumBinder<Enum<?>> binder = ModelScanner.getBoundCodeBinder(next);
|
||||
Class<? extends Enum<?>> enumType = ModelScanner.determineEnumTypeForBoundField(next);
|
||||
def = new RuntimeChildCompositeBoundDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder, enumType);
|
||||
IValueSetEnumBinder<Enum<?>> binder = ModelScanner.getBoundCodeBinder(nextField);
|
||||
Class<? extends Enum<?>> enumType = ModelScanner.determineEnumTypeForBoundField(nextField);
|
||||
def = new RuntimeChildCompositeBoundDatatypeDefinition(nextField, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder, enumType);
|
||||
} else if (BaseNarrativeDt.class.isAssignableFrom(nextElementType) || INarrative.class.isAssignableFrom(nextElementType)) {
|
||||
def = new RuntimeChildNarrativeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype);
|
||||
def = new RuntimeChildNarrativeDefinition(nextField, elementName, childAnnotation, descriptionAnnotation, nextDatatype);
|
||||
} else {
|
||||
def = new RuntimeChildCompositeDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype);
|
||||
def = new RuntimeChildCompositeDatatypeDefinition(nextField, elementName, childAnnotation, descriptionAnnotation, nextDatatype);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is not a valid child type: " + nextElementType);
|
||||
throw new ConfigurationException("Field '" + elementName + "' in type '" + declaringClass.getCanonicalName() + "' is not a valid child type: " + nextElementType);
|
||||
}
|
||||
|
||||
Binding bindingAnnotation = ModelScanner.pullAnnotation(next, Binding.class);
|
||||
Binding bindingAnnotation = ModelScanner.pullAnnotation(nextField, Binding.class);
|
||||
if (bindingAnnotation != null) {
|
||||
if (isNotBlank(bindingAnnotation.valueSet())) {
|
||||
def.setBindingValueSet(bindingAnnotation.valueSet());
|
||||
|
@ -448,7 +469,7 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
}
|
||||
mySealed = true;
|
||||
|
||||
scanCompositeElementForChildren(getImplementingClass(), this);
|
||||
scanCompositeElementForChildren();
|
||||
|
||||
super.sealAndInitialize(theContext, theClassToElementDefinitions);
|
||||
|
||||
|
@ -537,5 +558,54 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
return index;
|
||||
}
|
||||
|
||||
private static class ScannedField {
|
||||
private Child myChildAnnotation;
|
||||
|
||||
private List<Class<? extends IBase>> myChoiceTypes = new ArrayList<Class<? extends IBase>>();
|
||||
private Class<?> myElementType;
|
||||
private Field myField;
|
||||
private boolean myFirstFieldInNewClass;
|
||||
public ScannedField(Field theField, Class<?> theClass, boolean theFirstFieldInNewClass) {
|
||||
myField = theField;
|
||||
myFirstFieldInNewClass = theFirstFieldInNewClass;
|
||||
|
||||
Child childAnnotation = ModelScanner.pullAnnotation(theField, Child.class);
|
||||
if (childAnnotation == null) {
|
||||
ourLog.trace("Ignoring non @Child field {} on target type {}", theField.getName(), theClass);
|
||||
return;
|
||||
}
|
||||
if (Modifier.isFinal(theField.getModifiers())) {
|
||||
ourLog.trace("Ignoring constant {} on target type {}", theField.getName(), theClass);
|
||||
return;
|
||||
}
|
||||
|
||||
myChildAnnotation = childAnnotation;
|
||||
myElementType = ModelScanner.determineElementType(theField);
|
||||
|
||||
for (Class<? extends IBase> nextChoiceType : childAnnotation.type()) {
|
||||
myChoiceTypes.add(nextChoiceType);
|
||||
}
|
||||
}
|
||||
|
||||
public Child getChildAnnotation() {
|
||||
return myChildAnnotation;
|
||||
}
|
||||
|
||||
public List<Class<? extends IBase>> getChoiceTypes() {
|
||||
return myChoiceTypes;
|
||||
}
|
||||
|
||||
public Class<?> getElementType() {
|
||||
return myElementType;
|
||||
}
|
||||
|
||||
public Field getField() {
|
||||
return myField;
|
||||
}
|
||||
|
||||
public boolean isFirstFieldInNewClass() {
|
||||
return myFirstFieldInNewClass;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
@ -313,7 +314,7 @@ public class FhirContext {
|
|||
|
||||
RuntimeResourceDefinition retVal = (RuntimeResourceDefinition) myClassToElementDefinition.get(theResourceType);
|
||||
if (retVal == null) {
|
||||
retVal = scanResourceType((Class<? extends IResource>) theResourceType);
|
||||
retVal = scanResourceType(theResourceType);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
@ -329,7 +330,8 @@ public class FhirContext {
|
|||
Map<String, Class<? extends IBaseResource>> nameToType = myVersionToNameToResourceType.get(theVersion);
|
||||
if (nameToType == null) {
|
||||
nameToType = new HashMap<String, Class<? extends IBaseResource>>();
|
||||
ModelScanner.scanVersionPropertyFile(null, nameToType, theVersion);
|
||||
Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> existing = Collections.emptyMap();
|
||||
ModelScanner.scanVersionPropertyFile(null, nameToType, theVersion, existing);
|
||||
|
||||
Map<FhirVersionEnum, Map<String, Class<? extends IBaseResource>>> newVersionToNameToResourceType = new HashMap<FhirVersionEnum, Map<String, Class<? extends IBaseResource>>>();
|
||||
newVersionToNameToResourceType.putAll(myVersionToNameToResourceType);
|
||||
|
@ -585,7 +587,7 @@ public class FhirContext {
|
|||
return defs.get(theResourceType);
|
||||
}
|
||||
|
||||
private RuntimeResourceDefinition scanResourceType(Class<? extends IResource> theResourceType) {
|
||||
private RuntimeResourceDefinition scanResourceType(Class<? extends IBaseResource> theResourceType) {
|
||||
ArrayList<Class<? extends IElement>> resourceTypes = new ArrayList<Class<? extends IElement>>();
|
||||
resourceTypes.add(theResourceType);
|
||||
Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> defs = scanResourceTypes(resourceTypes);
|
||||
|
@ -611,11 +613,19 @@ public class FhirContext {
|
|||
|
||||
Map<String, BaseRuntimeElementDefinition<?>> nameToElementDefinition = new HashMap<String, BaseRuntimeElementDefinition<?>>();
|
||||
nameToElementDefinition.putAll(myNameToElementDefinition);
|
||||
nameToElementDefinition.putAll(scanner.getNameToElementDefinitions());
|
||||
for (Entry<String, BaseRuntimeElementDefinition<?>> next : scanner.getNameToElementDefinitions().entrySet()) {
|
||||
if (!nameToElementDefinition.containsKey(next.getKey())) {
|
||||
nameToElementDefinition.put(next.getKey(), next.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, RuntimeResourceDefinition> nameToResourceDefinition = new HashMap<String, RuntimeResourceDefinition>();
|
||||
nameToResourceDefinition.putAll(myNameToResourceDefinition);
|
||||
nameToResourceDefinition.putAll(scanner.getNameToResourceDefinition());
|
||||
for (Entry<String, RuntimeResourceDefinition> next : scanner.getNameToResourceDefinition().entrySet()) {
|
||||
if (!nameToResourceDefinition.containsKey(next.getKey())) {
|
||||
nameToResourceDefinition.put(next.getKey(), next.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> classToElementDefinition = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
|
||||
classToElementDefinition.putAll(myClassToElementDefinition);
|
||||
|
|
|
@ -150,7 +150,7 @@ class ModelScanner {
|
|||
return myRuntimeChildUndeclaredExtensionDefinition;
|
||||
}
|
||||
|
||||
private void init(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Set<Class<? extends IBase>> theDatatypes) {
|
||||
private void init(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Set<Class<? extends IBase>> theTypesToScan) {
|
||||
if (theExistingDefinitions != null) {
|
||||
myClassToElementDefinitions.putAll(theExistingDefinitions);
|
||||
}
|
||||
|
@ -159,17 +159,11 @@ class ModelScanner {
|
|||
long start = System.currentTimeMillis();
|
||||
Map<String, Class<? extends IBaseResource>> resourceTypes = myNameToResourceType;
|
||||
|
||||
myVersionTypes = scanVersionPropertyFile(theDatatypes, resourceTypes, myVersion);
|
||||
|
||||
// toScan.add(DateDt.class);
|
||||
// toScan.add(CodeDt.class);
|
||||
// toScan.add(DecimalDt.class);
|
||||
// toScan.add(AttachmentDt.class);
|
||||
// toScan.add(ResourceReferenceDt.class);
|
||||
// toScan.add(QuantityDt.class);
|
||||
Set<Class<? extends IBase>> typesToScan = theTypesToScan;
|
||||
myVersionTypes = scanVersionPropertyFile(typesToScan, resourceTypes, myVersion, myClassToElementDefinitions);
|
||||
|
||||
do {
|
||||
for (Class<? extends IBase> nextClass : theDatatypes) {
|
||||
for (Class<? extends IBase> nextClass : typesToScan) {
|
||||
scan(nextClass);
|
||||
}
|
||||
for (Iterator<Class<? extends IBase>> iter = myScanAlso.iterator(); iter.hasNext();) {
|
||||
|
@ -177,10 +171,10 @@ class ModelScanner {
|
|||
iter.remove();
|
||||
}
|
||||
}
|
||||
theDatatypes.clear();
|
||||
theDatatypes.addAll(myScanAlso);
|
||||
typesToScan.clear();
|
||||
typesToScan.addAll(myScanAlso);
|
||||
myScanAlso.clear();
|
||||
} while (!theDatatypes.isEmpty());
|
||||
} while (!typesToScan.isEmpty());
|
||||
|
||||
for (Entry<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> nextEntry : myClassToElementDefinitions.entrySet()) {
|
||||
if (theExistingDefinitions != null && theExistingDefinitions.containsKey(nextEntry.getKey())) {
|
||||
|
@ -237,6 +231,7 @@ class ModelScanner {
|
|||
@SuppressWarnings("unchecked")
|
||||
Class<? extends IBaseResource> resClass = (Class<? extends IBaseResource>) theClass;
|
||||
scanResource(resClass, resourceDefinition);
|
||||
return;
|
||||
}
|
||||
|
||||
DatatypeDef datatypeDefinition = pullAnnotation(theClass, DatatypeDef.class);
|
||||
|
@ -249,11 +244,9 @@ class ModelScanner {
|
|||
@SuppressWarnings({ "unchecked" })
|
||||
Class<? extends IPrimitiveType<?>> resClass = (Class<? extends IPrimitiveType<?>>) theClass;
|
||||
scanPrimitiveDatatype(resClass, datatypeDefinition);
|
||||
} else {
|
||||
return;
|
||||
// throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": " +
|
||||
// theClass.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Block blockDefinition = pullAnnotation(theClass, Block.class);
|
||||
|
@ -297,6 +290,13 @@ class ModelScanner {
|
|||
}
|
||||
myClassToElementDefinitions.put(theClass, elementDef);
|
||||
myNameToElementDefinitions.put(elementDef.getName().toLowerCase(), elementDef);
|
||||
|
||||
/*
|
||||
* See #423:
|
||||
* If the type contains a field that has a custom type, we want to make
|
||||
* sure that this type gets scanned as well
|
||||
*/
|
||||
elementDef.populateScanAlso(myScanAlso);
|
||||
}
|
||||
|
||||
|
||||
|
@ -364,7 +364,8 @@ class ModelScanner {
|
|||
}
|
||||
}
|
||||
|
||||
Class<? extends IBaseResource> builtInType = myNameToResourceType.get(resourceName.toLowerCase());
|
||||
String resourceNameLowerCase = resourceName.toLowerCase();
|
||||
Class<? extends IBaseResource> builtInType = myNameToResourceType.get(resourceNameLowerCase);
|
||||
boolean standardType = builtInType != null && builtInType.equals(theClass) == true;
|
||||
if (primaryNameProvider) {
|
||||
if (builtInType != null && builtInType.equals(theClass) == false) {
|
||||
|
@ -384,7 +385,7 @@ class ModelScanner {
|
|||
myClassToElementDefinitions.put(theClass, resourceDef);
|
||||
if (primaryNameProvider) {
|
||||
if (resourceDef.getStructureVersion() == myVersion) {
|
||||
myNameToResourceDefinitions.put(resourceName.toLowerCase(), resourceDef);
|
||||
myNameToResourceDefinitions.put(resourceNameLowerCase, resourceDef);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,6 +393,13 @@ class ModelScanner {
|
|||
|
||||
scanResourceForSearchParams(theClass, resourceDef);
|
||||
|
||||
/*
|
||||
* See #423:
|
||||
* If the type contains a field that has a custom type, we want to make
|
||||
* sure that this type gets scanned as well
|
||||
*/
|
||||
resourceDef.populateScanAlso(myScanAlso);
|
||||
|
||||
return resourceName;
|
||||
}
|
||||
|
||||
|
@ -482,10 +490,10 @@ class ModelScanner {
|
|||
return type;
|
||||
}
|
||||
|
||||
static Set<Class<? extends IBase>> scanVersionPropertyFile(Set<Class<? extends IBase>> theDatatypes, Map<String, Class<? extends IBaseResource>> theResourceTypes, FhirVersionEnum version) {
|
||||
static Set<Class<? extends IBase>> scanVersionPropertyFile(Set<Class<? extends IBase>> theDatatypes, Map<String, Class<? extends IBaseResource>> theResourceTypes, FhirVersionEnum theVersion, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingElementDefinitions) {
|
||||
Set<Class<? extends IBase>> retVal = new HashSet<Class<? extends IBase>>();
|
||||
|
||||
InputStream str = version.getVersionImplementation().getFhirVersionPropertiesFile();
|
||||
InputStream str = theVersion.getVersionImplementation().getFhirVersionPropertiesFile();
|
||||
Properties prop = new Properties();
|
||||
try {
|
||||
prop.load(str);
|
||||
|
@ -500,6 +508,9 @@ class ModelScanner {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends IBase> dtType = (Class<? extends IBase>) Class.forName(nextValue);
|
||||
if (theExistingElementDefinitions.containsKey(dtType)) {
|
||||
continue;
|
||||
}
|
||||
retVal.add(dtType);
|
||||
|
||||
if (IElement.class.isAssignableFrom(dtType)) {
|
||||
|
@ -525,6 +536,9 @@ class ModelScanner {
|
|||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends IBaseResource> nextClass = (Class<? extends IBaseResource>) Class.forName(nextValue);
|
||||
if (theExistingElementDefinitions.containsKey(nextClass)) {
|
||||
continue;
|
||||
}
|
||||
if (!IBaseResource.class.isAssignableFrom(nextClass)) {
|
||||
throw new ConfigurationException("Class is not assignable from " + IBaseResource.class.getSimpleName() + ": " + nextValue);
|
||||
}
|
||||
|
|
|
@ -53,13 +53,16 @@ public class RuntimeResourceDefinition extends BaseRuntimeElementCompositeDefini
|
|||
myResourceProfile = theResourceAnnotation.profile();
|
||||
myId = theResourceAnnotation.id();
|
||||
|
||||
IBaseResource instance;
|
||||
try {
|
||||
IBaseResource instance = theClass.newInstance();
|
||||
myStructureVersion = instance.getStructureFhirVersionEnum();
|
||||
assert myStructureVersion != null;
|
||||
instance = theClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new ConfigurationException(myContext.getLocalizer().getMessage(getClass(), "nonInstantiableType", theClass.getName(), e.toString()), e);
|
||||
}
|
||||
myStructureVersion = instance.getStructureFhirVersionEnum();
|
||||
if (myStructureVersion != theContext.getVersion().getVersion()) {
|
||||
throw new ConfigurationException(myContext.getLocalizer().getMessage(getClass(), "typeWrongVersion", theContext.getVersion().getVersion(), theClass.getName(), myStructureVersion));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -623,13 +623,15 @@ public abstract class BaseParser implements IParser {
|
|||
@Override
|
||||
public <T extends IBaseResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException {
|
||||
|
||||
/*
|
||||
* We do this so that the context can verify that the structure is for
|
||||
* the correct FHIR version
|
||||
*/
|
||||
if (theResourceType != null) {
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResourceType);
|
||||
if (def.getStructureVersion() != myContext.getVersion().getVersion()) {
|
||||
throw new IllegalArgumentException("This parser is for FHIR version " + myContext.getVersion().getVersion() + " - Can not parse a structure for version " + def.getStructureVersion());
|
||||
}
|
||||
myContext.getResourceDefinition(theResourceType);
|
||||
}
|
||||
|
||||
// Actually do the parse
|
||||
T retVal = doParseResource(theResourceType, theReader);
|
||||
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(retVal);
|
||||
|
|
|
@ -6,6 +6,7 @@ ca.uhn.fhir.context.FhirContext.noStructures=Could not find any HAPI-FHIR struct
|
|||
ca.uhn.fhir.context.FhirContext.noStructuresForSpecifiedVersion=Could not find the HAPI-FHIR structure JAR on the classpath for version {0}. Note that as of HAPI-FHIR v0.8, a separate FHIR strcture JAR must be added to your classpath (or project pom.xml if you are using Maven)
|
||||
|
||||
ca.uhn.fhir.context.RuntimeResourceDefinition.nonInstantiableType=Resource type "{0}" can not be instantiated. Check that this class has a no-argument constructor, and that it is static if it is a nested type. Error is: {1}
|
||||
ca.uhn.fhir.context.RuntimeResourceDefinition.typeWrongVersion=This context is for FHIR version "{0}" but the class "{1}" is for version "{2}"
|
||||
|
||||
ca.uhn.fhir.rest.client.BaseClient.ioExceptionDuringOperation=Encountered IOException when performing {0} to URL {1} - {2}
|
||||
ca.uhn.fhir.rest.client.BaseClient.failedToParseResponse=Failed to parse response from server when performing {0} to URL {1} - {2}
|
||||
|
|
|
@ -760,7 +760,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
@Test
|
||||
public void testDocumentManifestResources() throws Exception {
|
||||
myFhirCtx.getResourceDefinition(Practitioner.class);
|
||||
myFhirCtx.getResourceDefinition(ca.uhn.fhir.model.dstu.resource.DocumentManifest.class);
|
||||
myFhirCtx.getResourceDefinition(DocumentManifest.class);
|
||||
|
||||
IGenericClient client = ourClient;
|
||||
|
||||
|
@ -2254,7 +2254,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
input.addParameter().setName("resource").setResource(patient);
|
||||
|
||||
String inputStr = myFhirCtx.newXmlParser().encodeResourceToString(input);
|
||||
ourLog.info(inputStr);
|
||||
// ourLog.info(inputStr);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate");
|
||||
post.setEntity(new StringEntity(inputStr, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package ca.uhn.fhir.validator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.hl7.fhir.instance.hapi.validation.FhirInstanceValidator;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
|
@ -24,6 +25,18 @@ public class ValidatorAcrossVersionsTest {
|
|||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongContextVersion() {
|
||||
FhirContext ctxDstu2 = FhirContext.forDstu2();
|
||||
try {
|
||||
ctxDstu2.getResourceDefinition(org.hl7.fhir.dstu3.model.Patient.class);
|
||||
fail();
|
||||
} catch (ConfigurationException e) {
|
||||
assertEquals("This context is for FHIR version \"DSTU2\" but the class \"org.hl7.fhir.dstu3.model.Patient\" is for version \"DSTU3\"", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testValidateProfileOnDstu2Resource() {
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
<!-- Set to 'trace' to enable SQL Value logging -->
|
||||
<logger name="org.hibernate.type" additivity="false" level="trace">
|
||||
<logger name="org.hibernate.type" additivity="false" level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
|
||||
|
|
|
@ -956,7 +956,7 @@ public class RestfulServerMethodTest {
|
|||
|
||||
IdDt id = new IdDt("Profile", "observation");
|
||||
Profile profile = profileProvider.getProfileById(createHttpServletRequest(), id);
|
||||
assertNull(profile);
|
||||
assertNotNull(profile);
|
||||
|
||||
id = new IdDt("Profile", "patient");
|
||||
profile = profileProvider.getProfileById(createHttpServletRequest(), id);
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package ca.uhn.fhir.parser.i423;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ProcedureRequest;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
@ResourceDef(name = "ProcedureRequest", id = "custom-procedure-request", profile = "http://test/")
|
||||
public class CustomProcedureRequest extends ProcedureRequest {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* scheduled
|
||||
*/
|
||||
@Child(name = FIELD_SCHEDULED, min = 0, max = 1, order = Child.REPLACE_PARENT, type = { CustomTimingDt.class })
|
||||
@Description(shortDefinition = "When procedure should occur", formalDefinition = "The timing schedule for the proposed or ordered procedure. The Schedule data type allows many different expressions. E.g. \"Every 8 hours\"; \"Three times a day\"; \"1/2 an hour before breakfast for 10 days from 23-Dec 2011:\"; \"15 Oct 2013, 17 Oct 2013 and 1 Nov 2013\".")
|
||||
protected CustomTimingDt ourScheduled;
|
||||
|
||||
public static final String FIELD_SCHEDULED = "scheduled";
|
||||
|
||||
public CustomTimingDt _getScheduled() {
|
||||
if (ourScheduled == null)
|
||||
ourScheduled = new CustomTimingDt();
|
||||
return ourScheduled;
|
||||
}
|
||||
|
||||
public CustomProcedureRequest _setScheduled(CustomTimingDt theValue) {
|
||||
ourScheduled = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(ourScheduled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
|
||||
return ElementUtil.allPopulatedChildElements(theType, ourScheduled);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package ca.uhn.fhir.parser.i423;
|
||||
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
|
||||
public class CustomProcedureRequestTest {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CustomProcedureRequestTest.class);
|
||||
|
||||
@Test
|
||||
public void testCreate() {
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
CustomProcedureRequest procedureRequest = new CustomProcedureRequest();
|
||||
CustomTimingDt timingDt = new CustomTimingDt();
|
||||
CustomTimingDt._Repeat repeat = new CustomTimingDt._Repeat();
|
||||
repeat._setFrequency(new IntegerDt(2));
|
||||
timingDt._setRepeat(repeat);
|
||||
procedureRequest._setScheduled(timingDt);
|
||||
|
||||
String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(procedureRequest);
|
||||
ourLog.info(encoded);
|
||||
|
||||
//@formatter:off
|
||||
assertThat(encoded, stringContainsInOrder(
|
||||
"<ProcedureRequest xmlns=\"http://hl7.org/fhir\">",
|
||||
"<meta>",
|
||||
"<profile value=\"http://test/\"/>",
|
||||
"</meta>",
|
||||
"<scheduledTiming>",
|
||||
"<repeat>",
|
||||
"<frequency value=\"2\"/>",
|
||||
"</repeat>",
|
||||
"</scheduledTiming>",
|
||||
"</ProcedureRequest>"));
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,565 @@
|
|||
package ca.uhn.fhir.parser.i423;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.IDatatype;
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.RangeDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.TimingDt;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.EventTimingEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.UnitsOfTimeEnum;
|
||||
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.model.primitive.DecimalDt;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
@DatatypeDef(name = "Timing")
|
||||
public class CustomTimingDt extends TimingDt {
|
||||
|
||||
/**
|
||||
* repeat
|
||||
*/
|
||||
@Child(name = FIELD_REPEAT, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {_Repeat.class})
|
||||
@Description(shortDefinition = "When the event is to occur", formalDefinition = "A set of rules that describe when the event should occur.")
|
||||
protected _Repeat ourRepeat;
|
||||
public static final String FIELD_REPEAT = "repeat";
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(ourRepeat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
|
||||
return ElementUtil.allPopulatedChildElements(theType, ourRepeat);
|
||||
}
|
||||
|
||||
public _Repeat _getRepeat() {
|
||||
if (ourRepeat == null)
|
||||
ourRepeat = new _Repeat();
|
||||
return ourRepeat;
|
||||
}
|
||||
|
||||
public CustomTimingDt _setRepeat(_Repeat theValue) {
|
||||
ourRepeat = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Block
|
||||
public static class _Repeat extends Repeat {
|
||||
/**
|
||||
* bounds
|
||||
*/
|
||||
@Child(name = FIELD_BOUNDS, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {RangeDt.class, PeriodDt.class})
|
||||
@Description(shortDefinition = "Length/Range of lengths, or (Start and/or end) limits", formalDefinition = "Either a duration for the length of the timing schedule, a range of possible length, or outer bounds for start and/or end limits of the timing schedule.")
|
||||
protected IDatatype ourBounds;
|
||||
public static final String FIELD_BOUNDS = "bounds";
|
||||
/**
|
||||
* count
|
||||
*/
|
||||
@Child(name = FIELD_COUNT, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {IntegerDt.class})
|
||||
@Description(shortDefinition = "Number of times to repeat", formalDefinition = "A total count of the desired number of repetitions.")
|
||||
protected IntegerDt ourCount;
|
||||
public static final String FIELD_COUNT = "count";
|
||||
/**
|
||||
* duration
|
||||
*/
|
||||
@Child(name = FIELD_DURATION, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {DecimalDt.class})
|
||||
@Description(shortDefinition = "How long when it happens", formalDefinition = "How long this thing happens for when it happens.")
|
||||
protected DecimalDt ourDuration;
|
||||
public static final String FIELD_DURATION = "duration";
|
||||
/**
|
||||
* durationMax
|
||||
*/
|
||||
@Child(name = FIELD_DURATIONMAX, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {DecimalDt.class})
|
||||
@Description(shortDefinition = "How long when it happens (Max)", formalDefinition = "The upper limit of how long this thing happens for when it happens.")
|
||||
protected DecimalDt ourDurationMax;
|
||||
public static final String FIELD_DURATIONMAX = "durationMax";
|
||||
/**
|
||||
* durationUnits
|
||||
*/
|
||||
@Child(name = FIELD_DURATIONUNITS, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {CodeDt.class})
|
||||
@Description(shortDefinition = "s | min | h | d | wk | mo | a - unit of time (UCUM)", formalDefinition = "The units of time for the duration, in UCUM units.")
|
||||
protected BoundCodeDt<UnitsOfTimeEnum> ourDurationUnits;
|
||||
public static final String FIELD_DURATIONUNITS = "durationUnits";
|
||||
/**
|
||||
* frequency
|
||||
*/
|
||||
@Child(name = FIELD_FREQUENCY, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {IntegerDt.class})
|
||||
@Description(shortDefinition = "Event occurs frequency times per period", formalDefinition = "The number of times to repeat the action within the specified period / period range (i.e. both period and periodMax provided).")
|
||||
protected IntegerDt ourFrequency;
|
||||
public static final String FIELD_FREQUENCY = "frequency";
|
||||
/**
|
||||
* frequencyMax
|
||||
*/
|
||||
@Child(name = FIELD_FREQUENCYMAX, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {IntegerDt.class})
|
||||
@Description(shortDefinition = "Event occurs up to frequencyMax times per period", formalDefinition = "If present, indicates that the frequency is a range - so repeat between [frequency] and [frequencyMax] times within the period or period range.")
|
||||
protected IntegerDt ourFrequencyMax;
|
||||
public static final String FIELD_FREQUENCYMAX = "frequencyMax";
|
||||
/**
|
||||
* period
|
||||
*/
|
||||
@Child(name = FIELD_PERIOD, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {DecimalDt.class})
|
||||
@Description(shortDefinition = "Event occurs frequency times per period", formalDefinition = "Indicates the duration of time over which repetitions are to occur; e.g. to express \"3 times per day\", 3 would be the frequency and \"1 day\" would be the period.")
|
||||
protected DecimalDt ourPeriod;
|
||||
public static final String FIELD_PERIOD = "period";
|
||||
/**
|
||||
* periodMax
|
||||
*/
|
||||
@Child(name = FIELD_PERIODMAX, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {DecimalDt.class})
|
||||
@Description(shortDefinition = "Upper limit of period (3-4 hours)", formalDefinition = "If present, indicates that the period is a range from [period] to [periodMax], allowing expressing concepts such as \"do this once every 3-5 days.")
|
||||
protected DecimalDt ourPeriodMax;
|
||||
public static final String FIELD_PERIODMAX = "periodMax";
|
||||
/**
|
||||
* periodUnits
|
||||
*/
|
||||
@Child(name = FIELD_PERIODUNITS, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {CodeDt.class})
|
||||
@Description(shortDefinition = "s | min | h | d | wk | mo | a - unit of time (UCUM)", formalDefinition = "The units of time for the period in UCUM units.")
|
||||
protected BoundCodeDt<UnitsOfTimeEnum> ourPeriodUnits;
|
||||
public static final String FIELD_PERIODUNITS = "periodUnits";
|
||||
/**
|
||||
* when
|
||||
*/
|
||||
@Child(name = FIELD_WHEN, min = 0, max = 1, order = Child.REPLACE_PARENT, summary = true, type = {CodeDt.class})
|
||||
@Description(shortDefinition = "Regular life events the event is tied to", formalDefinition = "A real world event that the occurrence of the event should be tied to.")
|
||||
protected BoundCodeDt<EventTimingEnum> ourWhen;
|
||||
public static final String FIELD_WHEN = "when";
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(ourBounds, ourCount, ourDuration, ourDurationMax, ourDurationUnits, ourFrequency, ourFrequencyMax, ourPeriod, ourPeriodMax, ourPeriodUnits, ourWhen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
|
||||
return ElementUtil.allPopulatedChildElements(theType, ourBounds, ourCount, ourDuration, ourDurationMax, ourDurationUnits, ourFrequency, ourFrequencyMax, ourPeriod, ourPeriodMax, ourPeriodUnits, ourWhen);
|
||||
}
|
||||
|
||||
public IDatatype _getBounds() {
|
||||
return ourBounds;
|
||||
}
|
||||
|
||||
public _Repeat _setBounds(IDatatype theValue) {
|
||||
ourBounds = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IntegerDt _getCount() {
|
||||
if (ourCount == null)
|
||||
ourCount = new IntegerDt();
|
||||
return ourCount;
|
||||
}
|
||||
|
||||
public _Repeat _setCount(IntegerDt theValue) {
|
||||
ourCount = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DecimalDt _getDuration() {
|
||||
if (ourDuration == null)
|
||||
ourDuration = new DecimalDt();
|
||||
return ourDuration;
|
||||
}
|
||||
|
||||
public _Repeat _setDuration(DecimalDt theValue) {
|
||||
ourDuration = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DecimalDt _getDurationMax() {
|
||||
if (ourDurationMax == null)
|
||||
ourDurationMax = new DecimalDt();
|
||||
return ourDurationMax;
|
||||
}
|
||||
|
||||
public _Repeat _setDurationMax(DecimalDt theValue) {
|
||||
ourDurationMax = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BoundCodeDt<UnitsOfTimeEnum> _getDurationUnits() {
|
||||
if (ourDurationUnits == null)
|
||||
ourDurationUnits = new BoundCodeDt<UnitsOfTimeEnum>(UnitsOfTimeEnum.VALUESET_BINDER);
|
||||
return ourDurationUnits;
|
||||
}
|
||||
|
||||
public _Repeat _setDurationUnits(BoundCodeDt<UnitsOfTimeEnum> theValue) {
|
||||
ourDurationUnits = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IntegerDt _getFrequency() {
|
||||
if (ourFrequency == null)
|
||||
ourFrequency = new IntegerDt();
|
||||
return ourFrequency;
|
||||
}
|
||||
|
||||
public _Repeat _setFrequency(IntegerDt theValue) {
|
||||
ourFrequency = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IntegerDt _getFrequencyMax() {
|
||||
if (ourFrequencyMax == null)
|
||||
ourFrequencyMax = new IntegerDt();
|
||||
return ourFrequencyMax;
|
||||
}
|
||||
|
||||
public _Repeat _setFrequencyMax(IntegerDt theValue) {
|
||||
ourFrequencyMax = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DecimalDt _getPeriod() {
|
||||
if (ourPeriod == null)
|
||||
ourPeriod = new DecimalDt();
|
||||
return ourPeriod;
|
||||
}
|
||||
|
||||
public _Repeat _setPeriod(DecimalDt theValue) {
|
||||
ourPeriod = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DecimalDt _getPeriodMax() {
|
||||
if (ourPeriodMax == null)
|
||||
ourPeriodMax = new DecimalDt();
|
||||
return ourPeriodMax;
|
||||
}
|
||||
|
||||
public _Repeat _setPeriodMax(DecimalDt theValue) {
|
||||
ourPeriodMax = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BoundCodeDt<UnitsOfTimeEnum> _getPeriodUnits() {
|
||||
if (ourPeriodUnits == null)
|
||||
ourPeriodUnits = new BoundCodeDt<UnitsOfTimeEnum>(UnitsOfTimeEnum.VALUESET_BINDER);
|
||||
return ourPeriodUnits;
|
||||
}
|
||||
|
||||
public _Repeat _setPeriodUnits(BoundCodeDt<UnitsOfTimeEnum> theValue) {
|
||||
ourPeriodUnits = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BoundCodeDt<EventTimingEnum> _getWhen() {
|
||||
if (ourWhen == null)
|
||||
ourWhen = new BoundCodeDt<EventTimingEnum>(EventTimingEnum.VALUESET_BINDER);
|
||||
return ourWhen;
|
||||
}
|
||||
|
||||
public _Repeat _setWhen(BoundCodeDt<EventTimingEnum> theValue) {
|
||||
ourWhen = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public IDatatype getBounds() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setBounds(IDatatype p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setCount(IntegerDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setCount(int p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDuration(DecimalDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDuration(double p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDuration(BigDecimal p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDuration(long p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDurationMax(DecimalDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDurationMax(double p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDurationMax(BigDecimal p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDurationMax(long p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDurationUnits(UnitsOfTimeEnum p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setDurationUnits(BoundCodeDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setFrequency(IntegerDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setFrequency(int p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setFrequencyMax(IntegerDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setFrequencyMax(int p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriod(DecimalDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriod(double p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriod(BigDecimal p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriod(long p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriodMax(DecimalDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriodMax(double p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriodMax(BigDecimal p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriodMax(long p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriodUnits(UnitsOfTimeEnum p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setPeriodUnits(BoundCodeDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setWhen(EventTimingEnum p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Repeat setWhen(BoundCodeDt p0) {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public BoundCodeDt getDurationUnitsElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public BoundCodeDt getPeriodUnitsElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public BoundCodeDt getWhenElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public DecimalDt getDurationElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public DecimalDt getDurationMaxElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public DecimalDt getPeriodElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public DecimalDt getPeriodMaxElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public IntegerDt getCountElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public IntegerDt getFrequencyElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public IntegerDt getFrequencyMaxElement() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Integer getCount() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Integer getFrequency() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Integer getFrequencyMax() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String getDurationUnits() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String getPeriodUnits() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String getWhen() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public BigDecimal getDuration() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public BigDecimal getDurationMax() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public BigDecimal getPeriod() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public BigDecimal getPeriodMax() {
|
||||
throw new UnsupportedOperationException("Deprecated method");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,9 +9,6 @@ import org.hl7.fhir.dstu3.model.StructureDefinition;
|
|||
import org.junit.AfterClass;
|
||||
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.rest.client.MyPatientWithExtensions;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
||||
|
@ -24,7 +21,7 @@ public class FhirContextDstu3Test {
|
|||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See #344
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,7 @@ public class ResourceWithExtensionsDstu3A extends BaseResource {
|
|||
* so check the unit tests immediately after any changes
|
||||
*/
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name = "foo1", type = StringType.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
|
||||
@Extension(url = "http://foo/#f1", definedLocally=true, isModifier=false)
|
||||
|
@ -197,11 +198,6 @@ public class ResourceWithExtensionsDstu3A extends BaseResource {
|
|||
|
||||
|
||||
|
||||
@Override
|
||||
public FhirVersionEnum getStructureFhirVersionEnum() {
|
||||
return FhirVersionEnum.DSTU1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return null;
|
||||
|
|
|
@ -2,12 +2,7 @@ package ca.uhn.fhir.rest.client;
|
|||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
@ -144,6 +139,16 @@ public class GenericClientDstu3Test {
|
|||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
MyPatientWithExtensions read = client.read().resource(MyPatientWithExtensions.class).withId(new IdType("1")).execute();
|
||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div>", read.getText().getDivAsString());
|
||||
|
||||
// Ensure that we haven't overridden the default type for the name
|
||||
assertFalse(MyPatientWithExtensions.class.isAssignableFrom(Patient.class));
|
||||
assertFalse(Patient.class.isAssignableFrom(MyPatientWithExtensions.class));
|
||||
Patient pt = new Patient();
|
||||
pt.getText().setDivAsString("A PATIENT");
|
||||
IParser parser = ourCtx.newXmlParser();
|
||||
String encoded = parser.encodeResourceToString(pt);
|
||||
pt = (Patient) parser.parseResource(encoded);
|
||||
|
||||
}
|
||||
|
||||
private byte[] extractBodyAsByteArray(ArgumentCaptor<HttpUriRequest> capt) throws IOException {
|
||||
|
|
|
@ -15,26 +15,6 @@
|
|||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder (5).launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder (6).launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
|
|
|
@ -156,6 +156,11 @@
|
|||
"-b FOO" that lets you add an authorization header in the form
|
||||
<![CDATA[<code>Authorization: Bearer FOO</code>]]>
|
||||
</action>
|
||||
<action type="fix" issue="423">
|
||||
Parser failed to successfully encode a custom resource
|
||||
if it contained custom fields that also used custom
|
||||
types. Thanks to GitHub user @sjanic for reporting!
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.6" date="2016-07-07">
|
||||
<action type="fix">
|
||||
|
|
Loading…
Reference in New Issue