Skip to content
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

Unmarshalling of provided XMLGregorianCalendar implementation class #159

Open
pm-finamis opened this issue Feb 5, 2022 · 2 comments
Open

Comments

@pm-finamis
Copy link

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

@jdereg
Copy link
Owner

jdereg commented Feb 13, 2022

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.

@pm-finamis
Copy link
Author

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.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants