Unmarshalling of provided XMLGregorianCalendar implementation class
pm-finamis opened this issue · comments
Hi,
we are using json-io to temporarily store java objects as text values for later processing.
In particular, we store webservice request java objects, some of them contain datetime fields of type org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl, which is an XMLGregorianCalendar implementation provided by the application server.
json-io fails to unmarshall these fields, returning LinkedHashMap instead of XMLGregorianCalendarImpl.
It seems Metautils are not able to see the XMLGregorianCalendarImpl class.
As a solution, I added MetaUtils.getNameToClass() method (it returns the private Map<String, Class> nameToClass), then I used it to register the dynamically detected class of the XMLGregorianCalendar implementation class (which is XMLGregorianCalendarImpl). I also provided an instantiator.
static {
MetaUtils.getNameToClass().put(
"org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl",
(new XMLGregorianCalendarClassFactory()).newInstance(null, null).getClass()
);
JsonReader.assignInstantiator(
"org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl",
new XMLGregorianCalendarClassFactory());
}
public static class XMLGregorianCalendarClassFactory implements JsonReader.ClassFactoryEx {
@Override
public Object newInstance(Class aClass, Map map) {
try {
return DatatypeFactory.newInstance().newXMLGregorianCalendar();
} catch (DatatypeConfigurationException e) {
throw new RuntimeException(e);
}
}
}
Is this the right way to do this in json-io? Would you consider adding MetaUtils.getNameToClass() (or sth similar) to MetaUtils?
Thank you,
Regards,
Peter
In the user guide, look at customization approach #4. That shows how to write a custom reader for json-io. You will likely also want to implement a custom writer. This is the "opening" to allow json-io to serialize any class.
Separately, if you are having trouble instantiating a class, then write an "instantiator" (factory) to create the instance, and use the "assignInstantor" to associate the factory class that can instantiate a class to the actual .class. This is only needed when json-io is failing to instantiate a particular class found in the json input. In those cases, use the "assignInstantor" capability.
Hi John, thanks for your reply.
Actually I see no reason to write a custom reader/writer, the default ones work perfectly.
It is class lookup that seems to need some customization.
(And as I mentioned, I provided an instantiator, but it is used AFTER MetaUtils fail to find the class XMLGregorianCalendarImpl. I guess if MetaUtils were able to find the class, they would be probably also able to instatiate it and instantiator would not be needed anyway.)
This was a long time ago. Have you resolved this, moved on, other?