/* * Copyright 2015 MiLaboratory.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.milaboratory.primitivio; import gnu.trove.map.hash.TByteObjectHashMap; import java.util.HashMap; public final class CustomSerializerImpl implements Serializer { final HashMap<Class<?>, TypeInfo> infoByClass; final TByteObjectHashMap<TypeInfo> infoById; public CustomSerializerImpl(HashMap<Class<?>, TypeInfo> infoByClass) { this.infoByClass = infoByClass; this.infoById = new TByteObjectHashMap<>(); for (TypeInfo info : infoByClass.values()) infoById.put(info.id, info); } @Override public void write(PrimitivO output, Object object) { Class<?> type = object.getClass(); // Trying to find appropriate serializer for TypeInfo info = infoByClass.get(type); if (info == null) { Class<?> parent = Util.findSerializableParent(type, true, false); info = infoByClass.get(parent); if (info == null) throw new RuntimeException("Can't find serializer for " + type); else //Caching this type->info mapping infoByClass.put(type, info); } // Writing type id output.writeByte(info.id); // Writing content using corresponding sub-serializer Serializer serializer = info.serializer; serializer.write(output, object); if (!serializer.handlesReference()) output.writeReference(object); } @Override public Object read(PrimitivI input) { byte id = input.readByte(); Serializer serializer = infoById.get(id).serializer; Object obj = serializer.read(input); if (!serializer.handlesReference()) input.readReference(obj); return obj; } public static class TypeInfo { final byte id; final Serializer serializer; public TypeInfo(byte id, Serializer serializer) { this.id = id; this.serializer = serializer; } } @Override public boolean isReference() { return true; } @Override public boolean handlesReference() { return true; } }