New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom data types for IElement field #364

Closed
volodymyr-vynnytskyi opened this Issue May 13, 2016 · 2 comments

Comments

Projects
None yet
2 participants
@volodymyr-vynnytskyi

volodymyr-vynnytskyi commented May 13, 2016

Hi,

We're using 1.6 version and able to see DataFormatExceptionwhile using IElement field with some custom type elements (with hapi data types it works correctly)

ca.uhn.fhir.parser.DataFormatException: baseValue has type com.systematic.cura.services.api.outcome.CustomResource$CustomDate but this is not a valid type for this element - Expected one of: [class ca.uhn.fhir.model.dstu2.composite.TimingDt, class ca.uhn.fhir.model.primitive.OidDt, class ca.uhn.fhir.model.dstu2.composite.AgeDt, ...

There is example with a test:

@ResourceDef(name = "CustomResource", profile = "http://hl7.org/fhir/profiles/custom-resource", id = "custom-resource")
public class CustomResource extends BaseResource implements IBaseOperationOutcome {

    @Child(name = "baseValue", min = 1, max = Child.MAX_UNLIMITED)
    private IElement baseValues;

    public IElement getBaseValues() {
        return baseValues;
    }

    public void setBaseValues(IElement baseValues) { 
        this.baseValues = baseValues;
    }

    @Override
    public String getResourceName() {
        return "CustomResource";
    }

    @Override
    public FhirVersionEnum getStructureFhirVersionEnum() { 
        return FhirVersionEnum.DSTU2;
    }

    @Override
    public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
        return ElementUtil.allPopulatedChildElements(theType, baseValues);
    }

    @Override
    public boolean isEmpty() { 
        return ElementUtil.isEmpty(baseValues);
    }

    @Block
    public static class CustomDate extends BaseIdentifiableElement implements IResourceBlock {

        @Child(name = "date", order = 0, min = 1, max = 1, type = {DateTimeDt.class})
        private DateTimeDt date;

        public DateTimeDt getDate() { 
              if (date == null)
               date = new DateTimeDt();
            return date;
        }

        public CustomDate setDate(DateTimeDt theValue) {
            date = theValue;
            return this;
        }

        @Override
        public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
            return ElementUtil.allPopulatedChildElements(theType, date);
        }

        @Override
        public boolean isEmpty() {
            return ElementUtil.isEmpty(date);
        }
    } 

    @Test
    public void testCustomType() {
        FhirContext context = FhirContext.forDstu2();
        IParser parser = context.newXmlParser();

        CustomResource resource = new CustomResource();
        resource.setBaseValues(new CustomDate().setDate(new DateTimeDt("2016-05-13")));

        String xml = parser.encodeResourceToString(resource); 
        CustomResource parsedResource = parser.parseResource(CustomResource.class, xml);
    }

    @Test
    public void testPrimitiveType() {
        FhirContext context = FhirContext.forDstu2();
        IParser parser = context.newXmlParser();

        CustomResource resource = new CustomResource();
        resource.setBaseValues(new StringDt("2016-05-13"));

        String xml = parser.encodeResourceToString(resource); 
        CustomResource parsedResource = parser.parseResource(CustomResource.class, xml);
    }
}

@volodymyr-vynnytskyi volodymyr-vynnytskyi changed the title from Custom types in List<IElement> issue to Custom data types for IElement field May 17, 2016

@jamesagnew

This comment has been minimized.

Owner

jamesagnew commented May 22, 2016

Hi Xoude - I'm going to commit a fix to this shortly. One thing to note, I had to make some changes to your custom type in order for this to work. The basic problem is that CustomDate needs to be a datatype and not a block in order for this to work.

This is because of the way FHIR itself works: If you have a choice element (a field that can hold multiple value types), the possible choices must all be datatypes since those datatype names determine what the field is called when the resource is serialized.

Will push a commit in a bit that shows how this is done.

Ps- I hope you don't mind, I'm going to turn your example into a bit of documentation on how to create custom resources since it's good documentation. :)

jamesagnew added a commit that referenced this issue May 22, 2016

@volodymyr-vynnytskyi

This comment has been minimized.

volodymyr-vynnytskyi commented May 23, 2016

@jamesagnew - No, I don't mind. Thanks for answer and fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment