/******************************************************************************* * Copyright © 2012-2015 eBay Software Foundation * This program is dual licensed under the MIT and Apache 2.0 licenses. * Please see LICENSE for more information. *******************************************************************************/ package com.ebay.jetstream.xmlser; import java.rmi.MarshalException; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.springframework.util.ClassUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; public abstract class XMLSerializer implements IXmlSerializer { private final Map<Class<?>, IXmlSerializer> m_nodeSerializers = new HashMap<Class<?>, IXmlSerializer>(); protected Element getRootElement(Object object) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder; try { builder = factory.newDocumentBuilder(); } catch (ParserConfigurationException e) { throw new IllegalStateException (e); } Document document = builder.newDocument(); return (Element) document.appendChild(document.createElement("bean")); } protected IXmlSerializer getSerializer(Object object, Class<?> defaultClass) { Class<?> clazz = object == null || ClassUtils.isPrimitiveOrWrapper(object.getClass()) ? null : object.getClass(); IXmlSerializer result = m_nodeSerializers.get(clazz); if (result == null) { for (Map.Entry<Class<?>, IXmlSerializer> entry : m_nodeSerializers.entrySet()) { Class<?> c = entry.getKey(); if (c != null && c != Object.class && c.isAssignableFrom(clazz)) { result = entry.getValue(); break; } } // Handle XSerializable implicitly and explicitly (note implicit was already checked) if (result == null && XMLSerializationManager.isXSerializable(object.getClass())) { result = m_nodeSerializers.get(XSerializable.class); } // Finally, use the default if nothing better found if (result == null) { result = m_nodeSerializers.get(defaultClass); } } return result; } /** * Serializes an object to its XML representation, in a DOM. * * @param object * the object to serialize. * @return the root Element of a DOM containing the serialized object. */ public Element getXMLRepresentation(Object object) { Element root = getRootElement(object); try { getSerializer(object, XSerializable.class).serialize(root, object); } catch (MarshalException e) { throw new RuntimeException(e); } return root; } /** * Serializes an object to its XML representation, as a String. * * @param object * the object to serialize. * * @return the serialized XML representation of an object as a String. */ public String getXMLStringRepresentation(Object object) { return XHelper.getStringFromElement(getXMLRepresentation(object)); } /** * Registers a serializer for a class. There are several "special" classes: null represents the primitive object * serializer. Object.class represents the basic object serializer. XSerializable represents the bean serializer. * * @param clazz * the class to register for. * @param serializer * the instance of IXmlSerializer to use for this class. * @return the old serializer. */ protected IXmlSerializer registerSerializer(Class<?> clazz, IXmlSerializer serializer) { IXmlSerializer old = m_nodeSerializers.get(clazz); m_nodeSerializers.put(clazz, serializer); return old; } public void serialize(Element containingElement, Object object) throws MarshalException { getSerializer(object, Object.class).serialize(containingElement, object); } }