This is a little messy and I'm going to report part of the answer as a bug internally. But regardless, here's one way to make it work - in short, have all of the things that could be listed as a recipient extend a common parent class, and in that class override %JSONNew to detect which type it is.
Class DC.Demo.Container Extends (%RegisteredObject, %JSON.Adaptor)
{
Property recipient As DC.Demo.Recipient;
ClassMethod Demo()
{
for json = {"recipient":{"dob":"2021-06-10"}}, {"recipient":{"reference":"foo"}} {
set inst = ..%New()
do inst.%JSONImport(json)
write !,json.%ToJSON(),!,$classname(inst.recipient),!
}
}
}
Class DC.Demo.Recipient Extends (%RegisteredObject, %JSON.Adaptor)
{
/// Get an instance of an JSON enabled class.<br><br>
///
/// You may override this method to do custom processing (such as initializing
/// the object instance) before returning an instance of this class.
/// However, this method should not be called directly from user code.<br>
/// Arguments:<br>
/// dynamicObject is the dynamic object with thee values to be assigned to the new object.<br>
/// containerOref is the containing object instance when called from JSONImport.
ClassMethod %JSONNew(dynamicObject As %DynamicObject, containerOref As %RegisteredObject = "") As %RegisteredObject
{
// This is weird: shouldn't need to reference .recipient here
if dynamicObject.recipient.%IsDefined("dob") {
quit ##class(DC.Demo.Patient).%New()
} elseif dynamicObject.recipient.%IsDefined("reference") {
quit ##class(DC.Demo.Reference).%New()
} else {
quit ..%New()
}
}
}
Class DC.Demo.Reference Extends DC.Demo.Recipient
{
Property reference As %String;
}
Class DC.Demo.Patient Extends DC.Demo.Recipient
{
Property dob As %Date;
}Output is:
d ##class(DC.Demo.Container).Demo()
{"recipient":{"dob":"2021-06-10"}}
DC.Demo.Patient
{"recipient":{"reference":"foo"}}
DC.Demo.ReferenceOnly problem is, %JSONNew (as advertised in class reference documentation) should get the %DynamicObject representing the object itself, not the parent %DynamicObject. This would only really work if each type is used in exactly one context like this, which seems unlikely.
- Log in to post comments