/** * Copyright (c) 2016, All Contributors (see CONTRIBUTORS file) * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.eventsourcing.layout.binary; import com.eventsourcing.layout.ObjectDeserializer; import com.eventsourcing.layout.ObjectSerializer; import com.eventsourcing.layout.Serialization; import com.eventsourcing.layout.types.ObjectTypeHandler; import lombok.SneakyThrows; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import static com.eventsourcing.layout.TypeHandler.*; public class BinarySerialization extends Serialization { private static final BinarySerialization BINARY_SERIALIZATION = new BinarySerialization(); public static final int SIZE_TAG_LENGTH = 4; private BinarySerialization() { addDeserializer(BIG_DECIMAL_TYPE_HANDLER, new BigDecimalBinaryDeserializer()); addSerializer(BIG_DECIMAL_TYPE_HANDLER, new BigDecimalBinarySerializer()); addDeserializer(BIG_INTEGER_TYPE_HANDLER, new BigIntegerBinaryDeserializer()); addSerializer(BIG_INTEGER_TYPE_HANDLER, new BigIntegerBinarySerializer()); addDeserializer(BOOLEAN_TYPE_HANDLER, new BooleanBinaryDeserializer()); addSerializer(BOOLEAN_TYPE_HANDLER, new BooleanBinarySerializer()); addDeserializer(BYTE_ARRAY_TYPE_HANDLER, new ByteArrayBinaryDeserializer()); addSerializer(BYTE_ARRAY_TYPE_HANDLER, new ByteArrayBinarySerializer()); addDeserializer(BYTE_TYPE_HANDLER, new ByteBinaryDeserializer()); addSerializer(BYTE_TYPE_HANDLER, new ByteBinarySerializer()); addDeserializer(DATE_TYPE_HANDLER, new DateBinaryDeserializer()); addSerializer(DATE_TYPE_HANDLER, new DateBinarySerializer()); addDeserializer(DOUBLE_TYPE_HANDLER, new DoubleBinaryDeserializer()); addSerializer(DOUBLE_TYPE_HANDLER, new DoubleBinarySerializer()); addDeserializer(ENUM_TYPE_HANDLER, new EnumBinaryDeserializer()); addSerializer(ENUM_TYPE_HANDLER, new EnumBinarySerializer()); addDeserializer(FLOAT_TYPE_HANDLER, new FloatBinaryDeserializer()); addSerializer(FLOAT_TYPE_HANDLER, new FloatBinarySerializer()); addDeserializer(INTEGER_TYPE_HANDLER, new IntegerBinaryDeserializer()); addSerializer(INTEGER_TYPE_HANDLER, new IntegerBinarySerializer()); addDeserializer(LIST_TYPE_HANDLER, new ListBinaryDeserializer()); addSerializer(LIST_TYPE_HANDLER, new ListBinarySerializer()); addDeserializer(MAP_TYPE_HANDLER, new MapBinaryDeserializer()); addSerializer(MAP_TYPE_HANDLER, new MapBinarySerializer()); addDeserializer(LONG_TYPE_HANDLER, new LongBinaryDeserializer()); addSerializer(LONG_TYPE_HANDLER, new LongBinarySerializer()); addDeserializer(OBJECT_TYPE_HANDLER, new ObjectBinaryDeserializer<>()); addSerializer(OBJECT_TYPE_HANDLER, new ObjectBinarySerializer<>()); addDeserializer(OPTIONAL_TYPE_HANDLER, new OptionalBinaryDeserializer()); addSerializer(OPTIONAL_TYPE_HANDLER, new OptionalBinarySerializer()); addDeserializer(SHORT_TYPE_HANDLER, new ShortBinaryDeserializer()); addSerializer(SHORT_TYPE_HANDLER, new ShortBinarySerializer()); addDeserializer(STRING_TYPE_HANDLER, new StringBinaryDeserializer()); addSerializer(STRING_TYPE_HANDLER, new StringBinarySerializer()); addDeserializer(UUID_TYPE_HANDLER, new UUIDBinaryDeserializer()); addSerializer(UUID_TYPE_HANDLER, new UUIDBinarySerializer()); } public static BinarySerialization getInstance() { return BINARY_SERIALIZATION; } private Map<String, ObjectSerializer> objectSerializers = new HashMap<>(); private Map<String, ObjectDeserializer> objectDeserializers = new HashMap<>(); @SneakyThrows @Override public <T> ObjectSerializer<T> getSerializer(Class<?> klass) { @SuppressWarnings("unchecked") ObjectSerializer<T> objectSerializer = objectSerializers .computeIfAbsent(klass.getName(), (k) -> new RootObjectBinarySerializer<T>(new ObjectTypeHandler (klass))); return objectSerializer; } @Override public <T> ObjectDeserializer<T> getDeserializer(Class<?> klass, boolean allowReadonly) { @SuppressWarnings("unchecked") ObjectDeserializer<T> objectDeserializer = objectDeserializers .computeIfAbsent(klass.getName() + (allowReadonly ? "(r/o)": ""), (k) -> new RootObjectBinaryDeserializer<>(new ObjectTypeHandler(klass))); return objectDeserializer; } private static class RootObjectBinarySerializer<T> extends ObjectBinarySerializer<T> { private final ObjectTypeHandler typeHandler; public RootObjectBinarySerializer(ObjectTypeHandler typeHandler) {this.typeHandler = typeHandler;} @Override public int size(T value) { return super.size(typeHandler, value); } @Override public void serialize(T value, ByteBuffer buffer) { super.serialize(typeHandler, value, buffer); } @Override public ByteBuffer serialize(T value) { return super.serialize(typeHandler, value); } } private static class RootObjectBinaryDeserializer<T> extends ObjectBinaryDeserializer<T> { private final ObjectTypeHandler typeHandler; public RootObjectBinaryDeserializer(ObjectTypeHandler typeHandler) {this.typeHandler = typeHandler;} @Override public T deserialize(ByteBuffer buffer) { return super.deserialize(typeHandler, buffer); } } }