blob: 3d22d6eb40a3de704978b347f47bd0b0c950e70b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
#pragma once
#include "IPdxSerializer.hpp"
#include "Serializable.hpp"
#include <geode/CacheableBuiltins.hpp>
namespace Apache
{
namespace Geode
{
namespace Client
{
using namespace System::Collections::Concurrent;
using namespace System::Reflection;
namespace native = apache::geode::client;
ref class Cache;
public ref class TypeRegistry
{
public:
TypeRegistry(Cache^ cache) : m_cache(cache)
{
ClassNameVsCreateNewObjectLockObj = gcnew Object();
singleIntTypeA = gcnew array<Type^>{ Int32::typeid };
singleIntType = gcnew array<Type^>(1) { Int32::typeid };
ClassNameVsCreateNewObjectDelegate =
gcnew Dictionary<String^, CreateNewObjectDelegate^>();
ClassNameVsCreateNewObjectArrayDelegate =
gcnew Dictionary<String^, CreateNewObjectArrayDelegate^>();
createNewObjectDelegateType = Type::GetType("Apache.Geode.Client.TypeRegistry+CreateNewObjectDelegate");
createNewObjectArrayDelegateType = Type::GetType("Apache.Geode.Client.TypeRegistry+CreateNewObjectArrayDelegate");
}
property IPdxSerializer^ PdxSerializer
{
IPdxSerializer^ get() {
return pdxSerializer;
}
void set(IPdxSerializer^ pdxSerializer) {
this->pdxSerializer = pdxSerializer;
}
}
/// <summary>
/// Register an PdxTypeMapper to map the local types to pdx types
/// </summary>
property IPdxTypeMapper^ PdxTypeMapper
{
IPdxTypeMapper^ get()
{
return pdxTypeMapper;
}
void set(IPdxTypeMapper^ pdxTypeMapper)
{
this->pdxTypeMapper = pdxTypeMapper;
}
}
String^ GetPdxTypeName(String^ localTypeName);
String^ GetLocalTypeName(String^ pdxTypeName);
Type^ GetType(String^ className);
/// <summary>
/// Register an instance factory method for a given type.
/// This should be used when registering types that implement
/// IPdxSerializable.
/// </summary>
/// <param name="creationMethod">
/// the creation function to register
/// </param>
/// <exception cref="IllegalArgumentException">
/// if the method is null
/// </exception>
void RegisterPdxType(PdxTypeFactoryMethod^ creationMethod);
IPdxSerializable^ GetPdxType(String^ className);
/// <summary>
/// Register an instance factory method for a given type.
/// This should be used when registering types that implement
/// ISerializable.
/// </summary>
/// <param name="creationMethod">
/// the creation function to register
/// </param>
/// <exception cref="IllegalArgumentException">
/// if the method is null
/// </exception>
/// <exception cref="IllegalStateException">
/// if the typeId has already been registered, or there is an error
/// in registering the type; check <c>Utils::LastError</c> for more
/// information in the latter case.
/// </exception>
void RegisterType(TypeFactoryMethod^ creationMethod);
internal:
void RegisterDataSerializablePrimitiveOverrideNativeDeserialization(
int8_t dsCode, TypeFactoryMethod^ creationMethod, Type^ managedType);
void RegisterDataSerializableFixedIdTypeOverrideNativeDeserialization(
Int32 fixedId, TypeFactoryMethod^ creationMethod);
/// <summary>
/// Unregister the type with the given typeId
/// </summary>
/// <param name="typeId">typeId of the type to unregister.</param>
void UnregisterTypeGeneric(Byte typeId);
/// <summary>
/// This is to get manged delegates.
/// </summary>
TypeFactoryMethod^ GetManagedDelegateGeneric(System::Int64 typeId)
{
TypeFactoryMethod^ ret = nullptr;
ManagedDelegatesGeneric->TryGetValue(typeId, ret);
return ret;
}
generic<class TValue>
static TValue GetManagedValueGeneric(std::shared_ptr<native::Serializable> val);
static void RegisterDataSerializablePrimitiveWrapper(
DataSerializablePrimitiveWrapperDelegate^ wrapperMethod,
int8_t dsCode, System::Type^ type);
/// <summary>
/// Internal static method to remove managed artifacts created by
/// RegisterType and RegisterWrapper methods when
/// <see cref="DistributedSystem.Disconnect" /> is called.
/// </summary>
static void UnregisterNativesGeneric(Cache^ cache);
void Clear()
{
pdxTypeNameToLocal->Clear();
localTypeNameToPdx->Clear();
classNameVsType->Clear();
ClassNameVsCreateNewObjectDelegate->Clear();
ClassNameVsCreateNewObjectArrayDelegate->Clear();
}
static inline int8_t GetDsCodeForManagedType(Type^ managedType)
{
int8_t retVal = 0;
if (!ManagedTypeToDsCode->TryGetValue(managedType, retVal))
{
if (managedType->IsGenericType)
{
ManagedTypeToDsCode->TryGetValue(managedType->GetGenericTypeDefinition(), retVal);
}
}
return retVal;
}
inline TypeFactoryMethod^ GetDataSerializableFixedTypeFactoryMethodForFixedId(Int32 fixedId)
{
return FixedIdToDataSerializableFixedIdTypeFactoryMethod[fixedId];
}
inline TypeFactoryMethod^ GetDataSerializablePrimitiveTypeFactoryMethodForDsCode(int8_t dsCode)
{
return DsCodeToDataSerializablePrimitiveTypeFactoryMethod[dsCode];
}
static inline DataSerializablePrimitiveWrapperDelegate^ GetDataSerializablePrimitiveWrapperDelegateForDsCode(int8_t dsCode)
{
return DsCodeToDataSerializablePrimitiveWrapperDelegate[dsCode];
}
delegate Object^ CreateNewObjectDelegate();
CreateNewObjectDelegate^ CreateNewObjectDelegateF(Type^ type);
delegate Object^ CreateNewObjectArrayDelegate(int len);
CreateNewObjectArrayDelegate^ CreateNewObjectArrayDelegateF(Type^ type);
Object^ CreateObject(String^ className);
Object^ GetArrayObject(String^ className, int length);
Object^ CreateObjectEx(String^ className);
Object^ GetArrayObjectEx(String^ className, int length);
private:
Cache^ m_cache;
IPdxSerializer^ pdxSerializer;
IPdxTypeMapper^ pdxTypeMapper;
ConcurrentDictionary<String^, String^>^ pdxTypeNameToLocal =
gcnew ConcurrentDictionary<String^, String^>();
ConcurrentDictionary<String^, String^>^ localTypeNameToPdx =
gcnew ConcurrentDictionary<String^, String^>();
ConcurrentDictionary<String^, Type^>^ classNameVsType =
gcnew ConcurrentDictionary<String^, Type^>();
Dictionary<String^, PdxTypeFactoryMethod^>^ PdxDelegateMap =
gcnew Dictionary<String^, PdxTypeFactoryMethod^>();
Dictionary<System::Int64, TypeFactoryMethod^>^ ManagedDelegatesGeneric =
gcnew Dictionary<System::Int64, TypeFactoryMethod^>();
List<TypeFactoryNativeMethodGeneric^>^ NativeDelegatesGeneric =
gcnew List<TypeFactoryNativeMethodGeneric^>();
Dictionary<UInt32, TypeFactoryMethod^>^ DelegateMapGeneric =
gcnew Dictionary<UInt32, TypeFactoryMethod^>();
Dictionary<Byte, TypeFactoryMethod^>^ DsCodeToDataSerializablePrimitiveTypeFactoryMethod =
gcnew Dictionary<Byte, TypeFactoryMethod^>();
Dictionary<Byte, TypeFactoryNativeMethodGeneric^>^ DsCodeToDataSerializablePrimitiveNativeDelegate =
gcnew Dictionary<Byte, TypeFactoryNativeMethodGeneric^>();
Dictionary<Int32, TypeFactoryMethod^>^ FixedIdToDataSerializableFixedIdTypeFactoryMethod =
gcnew Dictionary<Int32, TypeFactoryMethod^>();
Dictionary<Int32, TypeFactoryNativeMethodGeneric^>^ FixedIdToDataSerializableFixedIdNativeDelegate =
gcnew Dictionary<Int32, TypeFactoryNativeMethodGeneric^>();
// Fixed .NET to DSCode mapping
static Dictionary<System::Type^, int8_t>^ ManagedTypeToDsCode =
gcnew Dictionary<System::Type^, int8_t>();
static array<DataSerializablePrimitiveWrapperDelegate^>^ DsCodeToDataSerializablePrimitiveWrapperDelegate =
gcnew array<DataSerializablePrimitiveWrapperDelegate^>(128);
Type^ GetTypeFromRefrencedAssemblies(String^ className, Dictionary<Assembly^, bool>^ referedAssembly, Assembly^ currentAssembly);
Object^ ClassNameVsCreateNewObjectLockObj;
array<Type^>^ singleIntTypeA;
array<Type^>^ singleIntType;
Dictionary<String^, CreateNewObjectDelegate^>^ ClassNameVsCreateNewObjectDelegate;
Dictionary<String^, CreateNewObjectArrayDelegate^>^ ClassNameVsCreateNewObjectArrayDelegate;
Type^ createNewObjectDelegateType;
Type^ createNewObjectArrayDelegateType;
static TypeRegistry()
{
InitializeManagedTypeToDsCode();
RegisterDataSerializablePrimitivesWrapNativeDeserialization();
}
/// <summary>
/// Initializes a static map of .NET types to DataSerializable codes. Internally
/// we call it TypeId.
/// </summary>
static void InitializeManagedTypeToDsCode()
{
Dictionary<Object^, Object^>^ dic = gcnew Dictionary<Object^, Object^>();
ManagedTypeToDsCode[dic->GetType()] = static_cast<int8_t>(native::DSCode::CacheableHashMap);
ManagedTypeToDsCode[dic->GetType()->GetGenericTypeDefinition()] = static_cast<int8_t>(native::DSCode::CacheableHashMap);
System::Collections::ArrayList^ arr = gcnew System::Collections::ArrayList();
ManagedTypeToDsCode[arr->GetType()] = static_cast<int8_t>(native::DSCode::CacheableVector);
System::Collections::Generic::LinkedList<Object^>^ linketList = gcnew System::Collections::Generic::LinkedList<Object^>();
ManagedTypeToDsCode[linketList->GetType()] = static_cast<int8_t>(native::DSCode::CacheableLinkedList);
ManagedTypeToDsCode[linketList->GetType()->GetGenericTypeDefinition()] = static_cast<int8_t>(native::DSCode::CacheableLinkedList);
System::Collections::Generic::IList<Object^>^ iList = gcnew System::Collections::Generic::List<Object^>();
ManagedTypeToDsCode[iList->GetType()] = static_cast<int8_t>(native::DSCode::CacheableArrayList);
ManagedTypeToDsCode[iList->GetType()->GetGenericTypeDefinition()] = static_cast<int8_t>(native::DSCode::CacheableArrayList);
//TODO: Linked list, non generic stack, some other map types and see if more
System::Collections::Generic::Stack<Object^>^ stack = gcnew System::Collections::Generic::Stack<Object^>();
ManagedTypeToDsCode[stack->GetType()] = static_cast<int8_t>(native::DSCode::CacheableStack);
ManagedTypeToDsCode[stack->GetType()->GetGenericTypeDefinition()] = static_cast<int8_t>(native::DSCode::CacheableStack);
ManagedTypeToDsCode[Byte::typeid] = static_cast<int8_t>(native::DSCode::CacheableByte);
ManagedTypeToDsCode[Boolean::typeid] = static_cast<int8_t>(native::DSCode::CacheableBoolean);
ManagedTypeToDsCode[Char::typeid] = static_cast<int8_t>(native::DSCode::CacheableCharacter);
ManagedTypeToDsCode[Double::typeid] = static_cast<int8_t>(native::DSCode::CacheableDouble);
ManagedTypeToDsCode[String::typeid] = static_cast<int8_t>(native::DSCode::CacheableASCIIString);
ManagedTypeToDsCode[float::typeid] = static_cast<int8_t>(native::DSCode::CacheableFloat);
ManagedTypeToDsCode[Int16::typeid] = static_cast<int8_t>(native::DSCode::CacheableInt16);
ManagedTypeToDsCode[Int32::typeid] = static_cast<int8_t>(native::DSCode::CacheableInt32);
ManagedTypeToDsCode[Int64::typeid] = static_cast<int8_t>(native::DSCode::CacheableInt64);
ManagedTypeToDsCode[Type::GetType("System.Byte[]")] = static_cast<int8_t>(native::DSCode::CacheableBytes);
ManagedTypeToDsCode[Type::GetType("System.Double[]")] = static_cast<int8_t>(native::DSCode::CacheableDoubleArray);
ManagedTypeToDsCode[Type::GetType("System.Single[]")] = static_cast<int8_t>(native::DSCode::CacheableFloatArray);
ManagedTypeToDsCode[Type::GetType("System.Int16[]")] = static_cast<int8_t>(native::DSCode::CacheableInt16Array);
ManagedTypeToDsCode[Type::GetType("System.Int32[]")] = static_cast<int8_t>(native::DSCode::CacheableInt32Array);
ManagedTypeToDsCode[Type::GetType("System.Int64[]")] = static_cast<int8_t>(native::DSCode::CacheableInt64Array);
ManagedTypeToDsCode[Type::GetType("System.String[]")] = static_cast<int8_t>(native::DSCode::CacheableStringArray);
ManagedTypeToDsCode[Type::GetType("System.DateTime")] = static_cast<int8_t>(native::DSCode::CacheableDate);
ManagedTypeToDsCode[Type::GetType("System.Collections.Hashtable")] = static_cast<int8_t>(native::DSCode::CacheableHashTable);
}
static void RegisterDataSerializablePrimitivesWrapNativeDeserialization();
};
} // namespace Client
} // namespace Geode
} // namespace Apache