1 package com.vladmihalcea.hibernate.type.util;
2
3 import com.fasterxml.jackson.databind.JavaType;
4 import com.fasterxml.jackson.databind.JsonNode;
5 import com.fasterxml.jackson.databind.type.TypeFactory;
6 import org.hibernate.internal.util.SerializationHelper;
7 import org.hibernate.type.SerializationException;
8
9 import java.io.Serializable;
10 import java.util.Collection;
11 import java.util.Map;
12
13
16 public class ObjectMapperJsonSerializer implements JsonSerializer {
17
18 private final ObjectMapperWrapper objectMapperWrapper;
19
20 public ObjectMapperJsonSerializer(ObjectMapperWrapper objectMapperWrapper) {
21 this.objectMapperWrapper = objectMapperWrapper;
22 }
23
24 @Override
25 public <T> T clone(T object) {
26 if (object instanceof String) {
27 return object;
28 } else if (object instanceof Collection) {
29 Object firstElement = findFirstNonNullElement((Collection) object);
30 if (firstElement != null && !(firstElement instanceof Serializable)) {
31 JavaType type = TypeFactory.defaultInstance().constructParametricType(object.getClass(), firstElement.getClass());
32 return objectMapperWrapper.fromBytes(objectMapperWrapper.toBytes(object), type);
33 }
34 } else if (object instanceof Map) {
35 Map.Entry firstEntry = this.findFirstNonNullEntry((Map) object);
36 if (firstEntry != null) {
37 Object key = firstEntry.getKey();
38 Object value = firstEntry.getValue();
39 if (!(key instanceof Serializable) || !(value instanceof Serializable)) {
40 JavaType type = TypeFactory.defaultInstance().constructParametricType(object.getClass(), key.getClass(), value.getClass());
41 return (T) objectMapperWrapper.fromBytes(objectMapperWrapper.toBytes(object), type);
42 }
43 }
44 } else if (object instanceof JsonNode) {
45 return (T) ((JsonNode) object).deepCopy();
46 }
47
48 if (object instanceof Serializable) {
49 try {
50 return (T) SerializationHelper.clone((Serializable) object);
51 } catch (SerializationException e) {
52
53
54 }
55 }
56
57 return jsonClone(object);
58 }
59
60 private Object findFirstNonNullElement(Collection collection) {
61 for (java.lang.Object element : collection) {
62 if (element != null) {
63 return element;
64 }
65 }
66 return null;
67 }
68
69 private Map.Entry findFirstNonNullEntry(Map<?, ?> map) {
70 for (Map.Entry entry : map.entrySet()) {
71 if (entry.getKey() != null && entry.getValue() != null) {
72 return entry;
73 }
74 }
75 return null;
76 }
77
78 private <T> T jsonClone(T object) {
79 return objectMapperWrapper.fromBytes(objectMapperWrapper.toBytes(object), (Class<T>) object.getClass());
80 }
81 }