Fix #720 - Failure to parse custom type
This commit is contained in:
parent
5f5475fb17
commit
16e19a9fed
|
@ -606,7 +606,7 @@ class ParserState<T> {
|
|||
return;
|
||||
}
|
||||
case RESOURCE: {
|
||||
if (myInstance instanceof IAnyResource || myInstance instanceof IBaseBackboneElement) {
|
||||
if (myInstance instanceof IAnyResource || myInstance instanceof IBaseBackboneElement || myInstance instanceof IBaseElement) {
|
||||
ParserState<T>.PreResourceStateHl7Org state = new PreResourceStateHl7Org(myInstance, child.getMutator(), null);
|
||||
push(state);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
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.rest.server.exceptions.InternalErrorException;
|
||||
import org.hl7.fhir.dstu3.model.Person;
|
||||
import org.hl7.fhir.dstu3.model.Type;
|
||||
import org.hl7.fhir.instance.model.api.ICompositeType;
|
||||
|
||||
/**
|
||||
* See #720
|
||||
*/
|
||||
@DatatypeDef(name = "ConsentTemplate")
|
||||
public class Bug720Datatype extends Type implements ICompositeType {
|
||||
|
||||
@Child(name = "contact", order = 8, min = 0, max = 1)
|
||||
@Description(shortDefinition = "responsible contact for this consent template")
|
||||
private Person contact = new Person();
|
||||
|
||||
public Person getContact() {
|
||||
return contact;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Type typedCopy() {
|
||||
throw new InternalErrorException("");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
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.rest.server.exceptions.InternalErrorException;
|
||||
import org.hl7.fhir.dstu3.model.DomainResource;
|
||||
import org.hl7.fhir.dstu3.model.ResourceType;
|
||||
import org.hl7.fhir.dstu3.model.Type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* See #720
|
||||
*/
|
||||
@ResourceDef(name = "Bug720ResourceType", profile = "http://example.com/StructureDefinition/dontuse#Bug720ResourceType")
|
||||
public class Bug720ResourceType extends DomainResource {
|
||||
|
||||
|
||||
@Child(name = "templates", order = 4, min = 1, max = Child.MAX_UNLIMITED, type = {Bug720Datatype.class})
|
||||
@Description(shortDefinition = "import information for 1-n consent templates")
|
||||
private List<Type> templates = new ArrayList<Type>();
|
||||
|
||||
@Override
|
||||
public DomainResource copy() {
|
||||
throw new InternalErrorException("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceType getResourceType() {
|
||||
throw new InternalErrorException("");
|
||||
}
|
||||
|
||||
public List<Type> getTemplates() {
|
||||
return templates;
|
||||
}
|
||||
}
|
|
@ -77,6 +77,22 @@ public class JsonParserDstu3Test {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See #720
|
||||
*/
|
||||
@Test
|
||||
public void testParseCustomResourceType() {
|
||||
String input = "{\"resourceType\":\"Bug720ResourceType\",\"meta\":{\"profile\":[\"http://example.com/StructureDefinition/dontuse#Bug720ResourceType\"]},\"supportedVersion\":\"2.5.x\",\"templatesConsentTemplate\":[{\"domainName\":\"name\",\"Name\":\"template_01\",\"version\":\"1.0\",\"title\":\"title\",\"comment\":\"comment\",\"contact\":{\"resourceType\":\"Person\",\"name\":[{\"family\":\"Mustermann\",\"given\":[\"Max\"]}],\"telecom\":[{\"system\":\"email\",\"value\":\"max.mustermann@mail.de\"},{\"system\":\"phone\",\"value\":\"+49 1234 23232\"}],\"address\":[{\"text\":\"street 1-2\",\"city\":\"city\",\"postalCode\":\"12345\",\"country\":\"Germany\"}]}}]}";
|
||||
Bug720ResourceType parsed = ourCtx.newJsonParser().parseResource(Bug720ResourceType.class, input);
|
||||
|
||||
assertEquals(1, parsed.getTemplates().size());
|
||||
assertEquals(Bug720Datatype.class, parsed.getTemplates().get(0).getClass());
|
||||
assertEquals("Mustermann", ((Bug720Datatype)parsed.getTemplates().get(0)).getContact().getNameFirstRep().getFamily());
|
||||
|
||||
ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed));
|
||||
}
|
||||
|
||||
/**
|
||||
* See #563
|
||||
*/
|
||||
|
|
|
@ -1221,7 +1221,8 @@ public class FHIRPathEngine {
|
|||
return result;
|
||||
case Concatenate:
|
||||
result = new TypeDetails(CollectionStatus.SINGLETON, "");
|
||||
return result;
|
||||
// return result;
|
||||
// fall through
|
||||
case Plus:
|
||||
result = new TypeDetails(CollectionStatus.SINGLETON);
|
||||
if (left.hasType(worker, "integer") && right.hasType(worker, "integer"))
|
||||
|
|
|
@ -877,6 +877,18 @@ public class FhirInstanceValidatorDstu3Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGoal() {
|
||||
Goal goal = new Goal();
|
||||
goal.setSubject(new Reference("Patient/123"));
|
||||
goal.setDescription(new CodeableConcept().addCoding(new Coding("http://foo","some other goal","")));
|
||||
goal.setStatus(Goal.GoalStatus.INPROGRESS);
|
||||
|
||||
ValidationResult results = myVal.validateWithResult(goal);
|
||||
List<SingleValidationMessage> outcome = logResultsAndReturnNonInformationalOnes(results);
|
||||
assertEquals(0, outcome.size());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
myDefaultValidationSupport.flush();
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package org.hl7.fhir.r4.utils;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.hl7.fhir.dstu3.utils.FhirPathEngineTest;
|
||||
import org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.hl7.fhir.r4.utils.FHIRPathEngine;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class FhirPathEngineR4Test {
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forR4();
|
||||
private static FHIRPathEngine ourEngine;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirPathEngineTest.class);
|
||||
|
||||
@Test
|
||||
public void testAs() throws Exception {
|
||||
Observation obs = new Observation();
|
||||
obs.setValue(new StringType("FOO"));
|
||||
|
||||
List<Base> value = ourEngine.evaluate(obs, "Observation.value.as(String)");
|
||||
assertEquals(1, value.size());
|
||||
assertEquals("FOO", ((StringType)value.get(0)).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExistsWithNoValue() throws FHIRException {
|
||||
Patient patient = new Patient();
|
||||
patient.setDeceased(new BooleanType());
|
||||
List<Base> eval = ourEngine.evaluate(patient, "Patient.deceased.exists()");
|
||||
ourLog.info(eval.toString());
|
||||
assertFalse(((BooleanType)eval.get(0)).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExistsWithValue() throws FHIRException {
|
||||
Patient patient = new Patient();
|
||||
patient.setDeceased(new BooleanType(false));
|
||||
List<Base> eval = ourEngine.evaluate(patient, "Patient.deceased.exists()");
|
||||
ourLog.info(eval.toString());
|
||||
assertTrue(((BooleanType)eval.get(0)).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcatenation() throws FHIRException {
|
||||
String exp = "Patient.name.family & '.'";
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("TEST");
|
||||
String result = ourEngine.evaluateToString(p, exp);
|
||||
assertEquals("TEST.", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcatenationFunction() throws FHIRException {
|
||||
String exp = "element.first().path.startsWith(%resource.type) and element.tail().all(path.startsWith(%resource.type&'.'))";
|
||||
|
||||
StructureDefinition sd = new StructureDefinition();
|
||||
StructureDefinition.StructureDefinitionDifferentialComponent diff = sd.getDifferential();
|
||||
|
||||
diff.addElement().setPath("Patient.name");
|
||||
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("TEST");
|
||||
List<Base> result = ourEngine.evaluate(null, p, diff, exp);
|
||||
ourLog.info(result.toString());
|
||||
// assertEquals("TEST.", result);
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() throws Exception {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourEngine = new FHIRPathEngine(new HapiWorkerContext(ourCtx, new DefaultProfileValidationSupport()));
|
||||
}
|
||||
|
||||
}
|
|
@ -125,6 +125,11 @@
|
|||
a real resource type, and caused conflicts with the .NET client. Thanks to
|
||||
Vlad Ignatov for reporting!
|
||||
</action>
|
||||
<action type="fix" issue="720">
|
||||
Parsing a DSTU3/R4 custom structure which contained a field of
|
||||
a custom type caused a crash during parsing. Thanks to
|
||||
GitHub user @mosaic-hgw for reporting!
|
||||
</action>
|
||||
</release>
|
||||
<release version="3.0.0" date="2017-09-27">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue