1 package com.fasterxml.jackson.databind.ext;
2
3 import java.util.logging.Logger;
4 import java.util.logging.Level;
5
6 import com.fasterxml.jackson.databind.*;
7 import com.fasterxml.jackson.databind.deser.Deserializers;
8 import com.fasterxml.jackson.databind.ser.Serializers;
9 import com.fasterxml.jackson.databind.util.ClassUtil;
10
11
23 public class OptionalHandlerFactory implements java.io.Serializable
24 {
25 private static final long serialVersionUID = 1;
26
27
31 private final static String PACKAGE_PREFIX_JAVAX_XML = "javax.xml.";
32
33 private final static String SERIALIZERS_FOR_JAVAX_XML = "com.fasterxml.jackson.databind.ext.CoreXMLSerializers";
34 private final static String DESERIALIZERS_FOR_JAVAX_XML = "com.fasterxml.jackson.databind.ext.CoreXMLDeserializers";
35
36
37
38
39 private final static String SERIALIZER_FOR_DOM_NODE = "com.fasterxml.jackson.databind.ext.DOMSerializer";
40 private final static String DESERIALIZER_FOR_DOM_DOCUMENT = "com.fasterxml.jackson.databind.ext.DOMDeserializer$DocumentDeserializer";
41 private final static String DESERIALIZER_FOR_DOM_NODE = "com.fasterxml.jackson.databind.ext.DOMDeserializer$NodeDeserializer";
42
43
44
45
46 private final static Class<?> CLASS_DOM_NODE;
47 private final static Class<?> CLASS_DOM_DOCUMENT;
48
49 static {
50 Class<?> doc = null, node = null;
51 try {
52 node = org.w3c.dom.Node.class;
53 doc = org.w3c.dom.Document.class;
54 } catch (Throwable e) {
55
56 Logger.getLogger(OptionalHandlerFactory.class.getName())
57 .log(Level.INFO, "Could not load DOM `Node` and/or `Document` classes: no DOM support");
58 }
59 CLASS_DOM_NODE = node;
60 CLASS_DOM_DOCUMENT = doc;
61 }
62
63
64
65
66
67 private static final Java7Handlers _jdk7Helper;
68 static {
69 Java7Handlers x = null;
70 try {
71 x = Java7Handlers.instance();
72 } catch (Throwable t) { }
73 _jdk7Helper = x;
74 }
75
76 public final static OptionalHandlerFactory instance = new OptionalHandlerFactory();
77
78 protected OptionalHandlerFactory() { }
79
80
85
86 public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type,
87 BeanDescription beanDesc)
88 {
89 final Class<?> rawType = type.getRawClass();
90
91 if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) {
92 return (JsonSerializer<?>) instantiate(SERIALIZER_FOR_DOM_NODE);
93 }
94
95 if (_jdk7Helper != null) {
96 JsonSerializer<?> ser = _jdk7Helper.getSerializerForJavaNioFilePath(rawType);
97 if (ser != null) {
98 return ser;
99 }
100 }
101
102 String className = rawType.getName();
103 String factoryName;
104 if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML) || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
105 factoryName = SERIALIZERS_FOR_JAVAX_XML;
106 } else {
107 return null;
108 }
109
110 Object ob = instantiate(factoryName);
111 if (ob == null) {
112 return null;
113 }
114 return ((Serializers) ob).findSerializer(config, type, beanDesc);
115 }
116
117 public JsonDeserializer<?> findDeserializer(JavaType type, DeserializationConfig config,
118 BeanDescription beanDesc)
119 throws JsonMappingException
120 {
121 final Class<?> rawType = type.getRawClass();
122
123 if (_jdk7Helper != null) {
124 JsonDeserializer<?> deser = _jdk7Helper.getDeserializerForJavaNioFilePath(rawType);
125 if (deser != null) {
126 return deser;
127 }
128 }
129 if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) {
130 return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_NODE);
131 }
132 if ((CLASS_DOM_DOCUMENT != null) && CLASS_DOM_DOCUMENT.isAssignableFrom(rawType)) {
133 return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_DOCUMENT);
134 }
135 String className = rawType.getName();
136 String factoryName;
137 if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
138 || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
139 factoryName = DESERIALIZERS_FOR_JAVAX_XML;
140 } else {
141 return null;
142 }
143 Object ob = instantiate(factoryName);
144 if (ob == null) {
145 return null;
146 }
147 return ((Deserializers) ob).findBeanDeserializer(type, config, beanDesc);
148 }
149
150 public boolean hasDeserializerFor(Class<?> valueType) {
151 if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(valueType)) {
152 return true;
153 }
154 if ((CLASS_DOM_DOCUMENT != null) && CLASS_DOM_DOCUMENT.isAssignableFrom(valueType)) {
155 return true;
156 }
157 String className = valueType.getName();
158 if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
159 || hasSuperClassStartingWith(valueType, PACKAGE_PREFIX_JAVAX_XML)) {
160 return true;
161 }
162 return false;
163 }
164
165
170
171 private Object instantiate(String className)
172 {
173 try {
174 return ClassUtil.createInstance(Class.forName(className), false);
175 } catch (LinkageError e) { }
176
177 catch (Exception e) { }
178 return null;
179 }
180
181
189 private boolean hasSuperClassStartingWith(Class<?> rawType, String prefix)
190 {
191 for (Class<?> supertype = rawType.getSuperclass(); supertype != null; supertype = supertype.getSuperclass()) {
192 if (supertype == Object.class) {
193 return false;
194 }
195 if (supertype.getName().startsWith(prefix)) {
196 return true;
197 }
198 }
199 return false;
200 }
201 }
202