org.babyfish.jimmer.sql.cache.ValueSerializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jimmer-sql Show documentation
Show all versions of jimmer-sql Show documentation
A revolutionary ORM framework for both java and kotlin
package org.babyfish.jimmer.sql.cache;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.databind.type.SimpleType;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.babyfish.jimmer.jackson.ImmutableModule;
import org.babyfish.jimmer.meta.ImmutableProp;
import org.babyfish.jimmer.meta.ImmutableType;
import org.babyfish.jimmer.meta.TargetLevel;
import org.babyfish.jimmer.runtime.DraftContext;
import org.babyfish.jimmer.runtime.Internal;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
public class ValueSerializer {
private static final byte[] NULL_BYTES = "".getBytes(StandardCharsets.UTF_8);
private final ObjectMapper mapper;
private final JavaType valueType;
public ValueSerializer(@NotNull ImmutableType type) {
this(type, null, null);
}
public ValueSerializer(@NotNull ImmutableProp prop) {
this(null, prop, null);
}
public ValueSerializer(@NotNull ImmutableType type, ObjectMapper mapper) {
this(type, null, mapper);
}
public ValueSerializer(@NotNull ImmutableProp prop, ObjectMapper mapper) {
this(null, prop, mapper);
}
private ValueSerializer(ImmutableType type, ImmutableProp prop, ObjectMapper mapper) {
if ((type == null) == (prop == null)) {
throw new IllegalArgumentException("Internal bug: nullity of type and prop must be different");
}
ObjectMapper clonedMapper = mapper != null?
new ObjectMapper(mapper) {} :
new ObjectMapper().registerModule(new JavaTimeModule());
clonedMapper.registerModule(new ImmutableModule());
this.mapper = clonedMapper;
if (prop == null) {
this.valueType = SimpleType.constructUnsafe(type.getJavaClass());
} else if (prop.isAssociation(TargetLevel.ENTITY)) {
ImmutableProp targetIdProp = prop.getTargetType().getIdProp();
JavaType targetIdType = SimpleType.constructUnsafe(
targetIdProp.getElementClass()
);
if (prop.isReferenceList(TargetLevel.OBJECT)) {
this.valueType = CollectionType.construct(
List.class,
null,
null,
null,
targetIdType
);
} else {
this.valueType = targetIdType;
}
} else {
this.valueType = SimpleType.constructUnsafe(prop.getElementClass());
}
}
@NotNull
public byte[] serialize(T value) {
if (value == null) {
return NULL_BYTES.clone();
}
try {
return mapper.writeValueAsBytes(value);
} catch (JsonProcessingException ex) {
throw new SerializationException(ex);
}
}
@NotNull
public Map serialize(@NotNull Map map) {
Map serializedMap = new LinkedHashMap<>((map.size() * 4 + 2) / 3);
for (Map.Entry e : map.entrySet()) {
serializedMap.put(e.getKey(), serialize(e.getValue()));
}
return serializedMap;
}
@NotNull
public Map serialize(@NotNull Map map, @NotNull Function keyMapper) {
Map serializedMap = new LinkedHashMap<>((map.size() * 4 + 2) / 3);
for (Map.Entry e : map.entrySet()) {
serializedMap.put(keyMapper.apply(e.getKey()), serialize(e.getValue()));
}
return serializedMap;
}
public T deserialize(byte[] value) {
if (value == null || value.length == 0 || Arrays.equals(value, NULL_BYTES)) {
return null;
}
try {
return mapper.readValue(value, valueType);
} catch (IOException ex) {
throw new SerializationException(ex);
}
}
@NotNull
public Map deserialize(@NotNull Map map) {
Map deserializedMap = new LinkedHashMap<>((map.size() * 4 + 2) / 3);
for (Map.Entry e : map.entrySet()) {
deserializedMap.put(e.getKey(), deserialize(e.getValue()));
}
return deserializedMap;
}
@NotNull
public Map deserialize(@NotNull Map map, @NotNull Function keyMapper) {
Map deserializedMap = new LinkedHashMap<>((map.size() * 4 + 2) / 3);
for (Map.Entry e : map.entrySet()) {
deserializedMap.put(keyMapper.apply(e.getKey()), deserialize(e.getValue()));
}
return deserializedMap;
}
@NotNull
public Map deserialize(@NotNull Collection keys, @NotNull Collection values) {
Map deserializedMap = new LinkedHashMap<>((keys.size() * 4 + 2) / 3);
Iterator keyItr = keys.iterator();
Iterator byteArrItr = values.iterator();
while (keyItr.hasNext() && byteArrItr.hasNext()) {
K key = keyItr.next();
byte[] byteArr = byteArrItr.next();
if (byteArr != null) {
deserializedMap.put(key, deserialize(byteArr));
}
}
return deserializedMap;
}
}