/* * * * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.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. * * * * For more information: http://www.orientechnologies.com * */ package com.orientechnologies.orient.core.serialization.serializer.binary; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import com.orientechnologies.common.log.OLogManager; import com.orientechnologies.common.serialization.types.*; import com.orientechnologies.orient.core.db.ODatabaseDocumentInternal; import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; import com.orientechnologies.orient.core.metadata.schema.OType; import com.orientechnologies.orient.core.serialization.serializer.binary.impl.OLinkSerializer; import com.orientechnologies.orient.core.serialization.serializer.binary.impl.index.OCompositeKeySerializer; import com.orientechnologies.orient.core.serialization.serializer.binary.impl.index.OSimpleKeySerializer; import com.orientechnologies.orient.core.serialization.serializer.stream.OStreamSerializerRID; import com.orientechnologies.orient.core.serialization.serializer.stream.OStreamSerializerSBTreeIndexRIDContainer; /** * This class is responsible for obtaining OBinarySerializer realization, by it's id of type of object that should be serialized. * * * @author Evgeniy Degtiarenko (gmandnepr-at-gmail.com) */ public class OBinarySerializerFactory { /** * Size of the type identifier block size */ public static final int TYPE_IDENTIFIER_SIZE = 1; private final ConcurrentMap<Byte, OBinarySerializer<?>> serializerIdMap = new ConcurrentHashMap<Byte, OBinarySerializer<?>>(); private final ConcurrentMap<Byte, Class<? extends OBinarySerializer>> serializerClassesIdMap = new ConcurrentHashMap<Byte, Class<? extends OBinarySerializer>>(); private final ConcurrentMap<OType, OBinarySerializer<?>> serializerTypeMap = new ConcurrentHashMap<OType, OBinarySerializer<?>>(); private OBinarySerializerFactory() { } public static OBinarySerializerFactory create(int binaryFormatVersion) { final OBinarySerializerFactory factory = new OBinarySerializerFactory(); // STATELESS SERIALIER factory.registerSerializer(new ONullSerializer(), null); factory.registerSerializer(OBooleanSerializer.INSTANCE, OType.BOOLEAN); factory.registerSerializer(OIntegerSerializer.INSTANCE, OType.INTEGER); factory.registerSerializer(OShortSerializer.INSTANCE, OType.SHORT); factory.registerSerializer(OLongSerializer.INSTANCE, OType.LONG); factory.registerSerializer(OFloatSerializer.INSTANCE, OType.FLOAT); factory.registerSerializer(ODoubleSerializer.INSTANCE, OType.DOUBLE); factory.registerSerializer(ODateTimeSerializer.INSTANCE, OType.DATETIME); factory.registerSerializer(OCharSerializer.INSTANCE, null); factory.registerSerializer(OStringSerializer.INSTANCE, OType.STRING); factory.registerSerializer(OByteSerializer.INSTANCE, OType.BYTE); factory.registerSerializer(ODateSerializer.INSTANCE, OType.DATE); factory.registerSerializer(OLinkSerializer.INSTANCE, OType.LINK); factory.registerSerializer(OCompositeKeySerializer.INSTANCE, null); factory.registerSerializer(OStreamSerializerRID.INSTANCE, null); factory.registerSerializer(OBinaryTypeSerializer.INSTANCE, OType.BINARY); factory.registerSerializer(ODecimalSerializer.INSTANCE, OType.DECIMAL); factory.registerSerializer(OStreamSerializerSBTreeIndexRIDContainer.INSTANCE, null); // STATEFUL SERIALIER factory.registerSerializer(OSimpleKeySerializer.ID, OSimpleKeySerializer.class); return factory; } public static OBinarySerializerFactory getInstance() { final ODatabaseDocumentInternal database = ODatabaseRecordThreadLocal.INSTANCE.getIfDefined(); if (database != null) return database.getSerializerFactory(); else return OBinarySerializerFactory.create(Integer.MAX_VALUE); } public void registerSerializer(final OBinarySerializer<?> iInstance, final OType iType) { if (serializerIdMap.containsKey(iInstance.getId())) throw new IllegalArgumentException("Binary serializer with id " + iInstance.getId() + " has been already registered."); serializerIdMap.put(iInstance.getId(), iInstance); if (iType != null) serializerTypeMap.put(iType, iInstance); } @SuppressWarnings({ "unchecked", "rawtypes" }) public void registerSerializer(final byte iId, final Class<? extends OBinarySerializer> iClass) { if (serializerClassesIdMap.containsKey(iId)) throw new IllegalStateException("Serializer with id " + iId + " has been already registered."); serializerClassesIdMap.put(iId, (Class<? extends OBinarySerializer>) iClass); } /** * Obtain OBinarySerializer instance by it's id. * * @param identifier * is serializes identifier. * @return OBinarySerializer instance. */ public OBinarySerializer<?> getObjectSerializer(final byte identifier) { OBinarySerializer<?> impl = serializerIdMap.get(identifier); if (impl == null) { final Class<? extends OBinarySerializer> cls = serializerClassesIdMap.get(identifier); if (cls != null) try { impl = cls.newInstance(); } catch (Exception e) { OLogManager.instance().error(this, "Cannot create an instance of class %s invoking the empty constructor", cls); } } return impl; } /** * Obtain OBinarySerializer realization for the OType * * @param type * is the OType to obtain serializer algorithm for * @return OBinarySerializer instance */ @SuppressWarnings("unchecked") public <T> OBinarySerializer<T> getObjectSerializer(final OType type) { return (OBinarySerializer<T>) serializerTypeMap.get(type); } }