All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fasterxml.jackson.databind.ext.OptionalHandlerFactory Maven / Gradle / Ivy

There is a newer version: 2.17.0
Show newest version
package com.fasterxml.jackson.databind.ext;

import java.util.logging.Logger;
import java.util.logging.Level;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.Deserializers;
import com.fasterxml.jackson.databind.ser.Serializers;
import com.fasterxml.jackson.databind.util.ClassUtil;

/**
 * Helper class used for isolating details of handling optional+external types
 * (javax.xml classes) from standard factories that offer them.
 *

* Note that 2.7 changed handling to slightly less dynamic, to avoid having to * traverse class hierarchy, which turned to be a performance issue in * certain cases. Since DOM classes are assumed to exist on all Java 1.6 * environments (yes, even on Android/GAE), this part could be simplified by * slightly less dynamic lookups. *

* Also with 2.7 we are supporting JDK 1.7/Java 7 type(s). */ public class OptionalHandlerFactory implements java.io.Serializable { private static final long serialVersionUID = 1; /* To make 2 main "optional" handler groups (javax.xml.stream) * more dynamic, we better only figure out handlers completely dynamically, if and * when they are needed. To do this we need to assume package prefixes. */ private final static String PACKAGE_PREFIX_JAVAX_XML = "javax.xml."; private final static String SERIALIZERS_FOR_JAVAX_XML = "com.fasterxml.jackson.databind.ext.CoreXMLSerializers"; private final static String DESERIALIZERS_FOR_JAVAX_XML = "com.fasterxml.jackson.databind.ext.CoreXMLDeserializers"; // Plus we also have a single serializer for DOM Node: // private final static String CLASS_NAME_DOM_NODE = "org.w3c.dom.Node"; // private final static String CLASS_NAME_DOM_DOCUMENT = "org.w3c.dom.Document"; private final static String SERIALIZER_FOR_DOM_NODE = "com.fasterxml.jackson.databind.ext.DOMSerializer"; private final static String DESERIALIZER_FOR_DOM_DOCUMENT = "com.fasterxml.jackson.databind.ext.DOMDeserializer$DocumentDeserializer"; private final static String DESERIALIZER_FOR_DOM_NODE = "com.fasterxml.jackson.databind.ext.DOMDeserializer$NodeDeserializer"; // // Since 2.7, we will assume DOM classes are always found, both due to JDK 1.6 minimum // // and because Android (and presumably GAE) have these classes private final static Class CLASS_DOM_NODE; private final static Class CLASS_DOM_DOCUMENT; static { Class doc = null, node = null; try { node = org.w3c.dom.Node.class; doc = org.w3c.dom.Document.class; } catch (Exception e) { // not optimal but will do Logger.getLogger(OptionalHandlerFactory.class.getName()) .log(Level.INFO, "Could not load DOM `Node` and/or `Document` classes: no DOM support"); } CLASS_DOM_NODE = node; CLASS_DOM_DOCUMENT = doc; } // // But Java7 type(s) may or may not be; dynamic lookup should be fine, still // // (note: also assume it comes from JDK so that ClassLoader issues with OSGi // // can, I hope, be avoided?) private static final Java7Support _jdk7Helper; static { Java7Support x = null; try { x = Java7Support.instance(); } catch (Throwable t) { } _jdk7Helper = x; } public final static OptionalHandlerFactory instance = new OptionalHandlerFactory(); protected OptionalHandlerFactory() { } /* /********************************************************** /* Public API /********************************************************** */ public JsonSerializer findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) { final Class rawType = type.getRawClass(); if (_jdk7Helper != null) { JsonSerializer ser = _jdk7Helper.getSerializerForJavaNioFilePath(rawType); if (ser != null) { return ser; } } if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) { return (JsonSerializer) instantiate(SERIALIZER_FOR_DOM_NODE); } String className = rawType.getName(); String factoryName; if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML) || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) { factoryName = SERIALIZERS_FOR_JAVAX_XML; } else { return null; } Object ob = instantiate(factoryName); if (ob == null) { // could warn, if we had logging system (j.u.l?) return null; } return ((Serializers) ob).findSerializer(config, type, beanDesc); } public JsonDeserializer findDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { final Class rawType = type.getRawClass(); if (_jdk7Helper != null) { JsonDeserializer deser = _jdk7Helper.getDeserializerForJavaNioFilePath(rawType); if (deser != null) { return deser; } } if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) { return (JsonDeserializer) instantiate(DESERIALIZER_FOR_DOM_NODE); } if ((CLASS_DOM_DOCUMENT != null) && CLASS_DOM_DOCUMENT.isAssignableFrom(rawType)) { return (JsonDeserializer) instantiate(DESERIALIZER_FOR_DOM_DOCUMENT); } String className = rawType.getName(); String factoryName; if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML) || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) { factoryName = DESERIALIZERS_FOR_JAVAX_XML; } else { return null; } Object ob = instantiate(factoryName); if (ob == null) { // could warn, if we had logging system (j.u.l?) return null; } return ((Deserializers) ob).findBeanDeserializer(type, config, beanDesc); } /* /********************************************************** /* Internal helper methods /********************************************************** */ private Object instantiate(String className) { try { return ClassUtil.createInstance(Class.forName(className), false); } catch (LinkageError e) { } // too many different kinds to enumerate here: catch (Exception e) { } return null; } /** * Since 2.7 we only need to check for class extension, as all implemented * types are classes, not interfaces. This has performance implications for * some cases, as we do not need to go over interfaces implemented, just * superclasses * * @since 2.7 */ private boolean hasSuperClassStartingWith(Class rawType, String prefix) { for (Class supertype = rawType.getSuperclass(); supertype != null; supertype = supertype.getSuperclass()) { if (supertype == Object.class) { return false; } if (supertype.getName().startsWith(prefix)) { return true; } } return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy