http://git-wip-us.apache.org/repos/asf/geode/blob/e4fd74fb/src/clicache/src/impl/ManagedCacheListener.hpp ---------------------------------------------------------------------- diff --git a/src/clicache/src/impl/ManagedCacheListener.hpp b/src/clicache/src/impl/ManagedCacheListener.hpp index 7e9c34b..470bc3c 100644 --- a/src/clicache/src/impl/ManagedCacheListener.hpp +++ b/src/clicache/src/impl/ManagedCacheListener.hpp @@ -33,204 +33,208 @@ namespace GemStone { } } -namespace gemfire { - - /// <summary> - /// Wraps the managed <see cref="GemStone.GemFire.Cache.ICacheListener" /> - /// object and implements the native <c>gemfire::CacheListener</c> interface. - /// </summary> - class ManagedCacheListenerGeneric - : public gemfire::CacheListener - { - public: - - /// <summary> - /// Constructor to initialize with the provided managed object. - /// </summary> - /// <param name="userptr"> - /// The managed object. - /// </param> - inline ManagedCacheListenerGeneric( - /*GemStone::GemFire::Cache::ICacheListener^ managedptr,*/ Object^ userptr ) - : /*m_managedptr( managedptr ),*/ m_userptr( userptr ) { } - - /// <summary> - /// Static function to create a <c>ManagedCacheListener</c> using given - /// managed assembly path and given factory function. - /// </summary> - /// <param name="assemblyPath"> - /// The path of the managed assembly that contains the <c>ICacheListener</c> - /// factory function. - /// </param> - /// <param name="factoryFunctionName"> - /// The name of the factory function of the managed class for creating - /// an object that implements <c>ICacheListener</c>. - /// This should be a static function of the format - /// {Namespace}.{Class Name}.{Method Name}. - /// </param> - /// <exception cref="IllegalArgumentException"> - /// If the managed library cannot be loaded or the factory function fails. - /// </exception> - static gemfire::CacheListener* create( const char* assemblyPath, - const char* factoryFunctionName ); - - /// <summary> - /// Destructor -- does nothing. - /// </summary> - virtual ~ManagedCacheListenerGeneric( ) { } - - /// <summary> - /// Handles the event of a new key being added to a region. - /// </summary> - /// <remarks> - /// The entry did not previously exist in this region in the local cache - /// (even with a null value). - /// <para> - /// This function does not throw any exception. - /// </para> - /// </remarks> - /// <param name="ev"> - /// Denotes the event object associated with the entry creation. - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Region.Create" /> - /// <seealso cref="GemStone.GemFire.Cache.Region.Put" /> - /// <seealso cref="GemStone.GemFire.Cache.Region.Get" /> - virtual void afterCreate( const gemfire::EntryEvent& ev ); - - /// <summary> - /// Handles the event of an entry's value being modified in a region. - /// </summary> - /// <remarks> - /// This entry previously existed in this region in the local cache, - /// but its previous value may have been null. - /// </remarks> - /// <param name="ev"> - /// EntryEvent denotes the event object associated with updating the entry. - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Region.Put" /> - virtual void afterUpdate( const gemfire::EntryEvent& ev ); - - /// <summary> - /// Handles the event of an entry's value being invalidated. - /// </summary> - /// <param name="ev"> - /// EntryEvent denotes the event object associated with the entry invalidation. - /// </param> - virtual void afterInvalidate( const gemfire::EntryEvent& ev ); - - /// <summary> - /// Handles the event of an entry being destroyed. - /// </summary> - /// <param name="ev"> - /// EntryEvent denotes the event object associated with the entry destruction. - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Region.Destroy" /> - virtual void afterDestroy( const gemfire::EntryEvent& ev ); - - /// <summary> - /// Handles the event of a region being cleared. - /// </summary> - virtual void afterRegionClear( const gemfire::RegionEvent& ev ); - - /// <summary> - /// Handles the event of a region being invalidated. - /// </summary> - /// <remarks> - /// Events are not invoked for each individual value that is invalidated - /// as a result of the region being invalidated. Each subregion, however, - /// gets its own <c>regionInvalidated</c> event invoked on its listener. - /// </remarks> - /// <param name="ev"> - /// RegionEvent denotes the event object associated with the region invalidation. - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Region.InvalidateRegion" /> - virtual void afterRegionInvalidate( const gemfire::RegionEvent& ev ); - - /// <summary> - /// Handles the event of a region being destroyed. - /// </summary> - /// <remarks> - /// Events are not invoked for each individual entry that is destroyed - /// as a result of the region being destroyed. Each subregion, however, - /// gets its own <c>afterRegionDestroyed</c> event invoked on its listener. - /// </remarks> - /// <param name="ev"> - /// RegionEvent denotes the event object associated with the region destruction. - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> - virtual void afterRegionDestroy( const gemfire::RegionEvent& ev ); - - /// <summary> - /// Handles the event of a region being live. - /// </summary> - /// <remarks> - /// Each subregion gets its own <c>afterRegionLive</c> event invoked on its listener. - /// </remarks> - /// <param name="ev"> - /// RegionEvent denotes the event object associated with the region going live. - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Cache.ReadyForEvents" /> - virtual void afterRegionLive( const gemfire::RegionEvent& ev ); - - /// <summary> - /// Called when the region containing this callback is destroyed, when - /// the cache is closed. - /// </summary> - /// <remarks> - /// Implementations should clean up any external resources, - /// such as database connections. Any runtime exceptions this method - /// throws will be logged. - /// <para> - /// It is possible for this method to be called multiple times on a single - /// callback instance, so implementations must be tolerant of this. - /// </para> - /// </remarks> - /// <seealso cref="GemStone.GemFire.Cache.Cache.Close" /> - /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> - virtual void close( const gemfire::RegionPtr& region ); - - ///<summary> - ///Called when all the endpoints associated with region are down. - ///This will be called when all the endpoints are down for the first time. - ///If endpoints come up and again go down it will be called again. - ///This will also be called when all endpoints are down and region is attached to the pool. - ///</summary> - ///<remarks> - ///</remark> - ///<param> - ///region Region^ denotes the assosiated region. - ///</param> - virtual void afterRegionDisconnected( const gemfire::RegionPtr& region ); - - /// <summary> - /// Returns the wrapped managed object reference. - /// </summary> - inline GemStone::GemFire::Cache::Generic::ICacheListener<Object^, Object^>^ ptr( ) const - { - return m_managedptr; - } - - inline void setptr( GemStone::GemFire::Cache::Generic::ICacheListener<Object^, Object^>^ managedptr ) - { - m_managedptr = managedptr; - } - - inline Object^ userptr( ) const - { - return m_userptr; - } - - private: - - /// <summary> - /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). - /// Note: not using auto_gcroot since it will result in 'Dispose' of the ICacheListener - /// to be called which is not what is desired when this object is destroyed. Normally this - /// managed object may be created by the user and will be handled automatically by the GC. - /// </summary> - gcroot<GemStone::GemFire::Cache::Generic::ICacheListener<Object^, Object^>^> m_managedptr; - - gcroot<Object^> m_userptr; - }; - -} +namespace apache { + namespace geode { + namespace client { + + /// <summary> + /// Wraps the managed <see cref="GemStone.GemFire.Cache.ICacheListener" /> + /// object and implements the native <c>apache::geode::client::CacheListener</c> interface. + /// </summary> + class ManagedCacheListenerGeneric + : public apache::geode::client::CacheListener + { + public: + + /// <summary> + /// Constructor to initialize with the provided managed object. + /// </summary> + /// <param name="userptr"> + /// The managed object. + /// </param> + inline ManagedCacheListenerGeneric( + /*GemStone::GemFire::Cache::ICacheListener^ managedptr,*/ Object^ userptr) + : /*m_managedptr( managedptr ),*/ m_userptr(userptr) { } + + /// <summary> + /// Static function to create a <c>ManagedCacheListener</c> using given + /// managed assembly path and given factory function. + /// </summary> + /// <param name="assemblyPath"> + /// The path of the managed assembly that contains the <c>ICacheListener</c> + /// factory function. + /// </param> + /// <param name="factoryFunctionName"> + /// The name of the factory function of the managed class for creating + /// an object that implements <c>ICacheListener</c>. + /// This should be a static function of the format + /// {Namespace}.{Class Name}.{Method Name}. + /// </param> + /// <exception cref="IllegalArgumentException"> + /// If the managed library cannot be loaded or the factory function fails. + /// </exception> + static apache::geode::client::CacheListener* create(const char* assemblyPath, + const char* factoryFunctionName); + + /// <summary> + /// Destructor -- does nothing. + /// </summary> + virtual ~ManagedCacheListenerGeneric() { } + + /// <summary> + /// Handles the event of a new key being added to a region. + /// </summary> + /// <remarks> + /// The entry did not previously exist in this region in the local cache + /// (even with a null value). + /// <para> + /// This function does not throw any exception. + /// </para> + /// </remarks> + /// <param name="ev"> + /// Denotes the event object associated with the entry creation. + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Region.Create" /> + /// <seealso cref="GemStone.GemFire.Cache.Region.Put" /> + /// <seealso cref="GemStone.GemFire.Cache.Region.Get" /> + virtual void afterCreate(const apache::geode::client::EntryEvent& ev); + + /// <summary> + /// Handles the event of an entry's value being modified in a region. + /// </summary> + /// <remarks> + /// This entry previously existed in this region in the local cache, + /// but its previous value may have been null. + /// </remarks> + /// <param name="ev"> + /// EntryEvent denotes the event object associated with updating the entry. + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Region.Put" /> + virtual void afterUpdate(const apache::geode::client::EntryEvent& ev); + + /// <summary> + /// Handles the event of an entry's value being invalidated. + /// </summary> + /// <param name="ev"> + /// EntryEvent denotes the event object associated with the entry invalidation. + /// </param> + virtual void afterInvalidate(const apache::geode::client::EntryEvent& ev); + + /// <summary> + /// Handles the event of an entry being destroyed. + /// </summary> + /// <param name="ev"> + /// EntryEvent denotes the event object associated with the entry destruction. + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Region.Destroy" /> + virtual void afterDestroy(const apache::geode::client::EntryEvent& ev); + + /// <summary> + /// Handles the event of a region being cleared. + /// </summary> + virtual void afterRegionClear(const apache::geode::client::RegionEvent& ev); + + /// <summary> + /// Handles the event of a region being invalidated. + /// </summary> + /// <remarks> + /// Events are not invoked for each individual value that is invalidated + /// as a result of the region being invalidated. Each subregion, however, + /// gets its own <c>regionInvalidated</c> event invoked on its listener. + /// </remarks> + /// <param name="ev"> + /// RegionEvent denotes the event object associated with the region invalidation. + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Region.InvalidateRegion" /> + virtual void afterRegionInvalidate(const apache::geode::client::RegionEvent& ev); + + /// <summary> + /// Handles the event of a region being destroyed. + /// </summary> + /// <remarks> + /// Events are not invoked for each individual entry that is destroyed + /// as a result of the region being destroyed. Each subregion, however, + /// gets its own <c>afterRegionDestroyed</c> event invoked on its listener. + /// </remarks> + /// <param name="ev"> + /// RegionEvent denotes the event object associated with the region destruction. + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> + virtual void afterRegionDestroy(const apache::geode::client::RegionEvent& ev); + + /// <summary> + /// Handles the event of a region being live. + /// </summary> + /// <remarks> + /// Each subregion gets its own <c>afterRegionLive</c> event invoked on its listener. + /// </remarks> + /// <param name="ev"> + /// RegionEvent denotes the event object associated with the region going live. + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Cache.ReadyForEvents" /> + virtual void afterRegionLive(const apache::geode::client::RegionEvent& ev); + + /// <summary> + /// Called when the region containing this callback is destroyed, when + /// the cache is closed. + /// </summary> + /// <remarks> + /// Implementations should clean up any external resources, + /// such as database connections. Any runtime exceptions this method + /// throws will be logged. + /// <para> + /// It is possible for this method to be called multiple times on a single + /// callback instance, so implementations must be tolerant of this. + /// </para> + /// </remarks> + /// <seealso cref="GemStone.GemFire.Cache.Cache.Close" /> + /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> + virtual void close(const apache::geode::client::RegionPtr& region); + + ///<summary> + ///Called when all the endpoints associated with region are down. + ///This will be called when all the endpoints are down for the first time. + ///If endpoints come up and again go down it will be called again. + ///This will also be called when all endpoints are down and region is attached to the pool. + ///</summary> + ///<remarks> + ///</remark> + ///<param> + ///region Region^ denotes the assosiated region. + ///</param> + virtual void afterRegionDisconnected(const apache::geode::client::RegionPtr& region); + + /// <summary> + /// Returns the wrapped managed object reference. + /// </summary> + inline GemStone::GemFire::Cache::Generic::ICacheListener<Object^, Object^>^ ptr() const + { + return m_managedptr; + } + + inline void setptr(GemStone::GemFire::Cache::Generic::ICacheListener<Object^, Object^>^ managedptr) + { + m_managedptr = managedptr; + } + + inline Object^ userptr() const + { + return m_userptr; + } + + private: + + /// <summary> + /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). + /// Note: not using auto_gcroot since it will result in 'Dispose' of the ICacheListener + /// to be called which is not what is desired when this object is destroyed. Normally this + /// managed object may be created by the user and will be handled automatically by the GC. + /// </summary> + gcroot<GemStone::GemFire::Cache::Generic::ICacheListener<Object^, Object^>^> m_managedptr; + + gcroot<Object^> m_userptr; + }; + + } // namespace client + } // namespace geode +} // namespace apache
http://git-wip-us.apache.org/repos/asf/geode/blob/e4fd74fb/src/clicache/src/impl/ManagedCacheLoader.cpp ---------------------------------------------------------------------- diff --git a/src/clicache/src/impl/ManagedCacheLoader.cpp b/src/clicache/src/impl/ManagedCacheLoader.cpp index 3052138..5d1a6cc 100644 --- a/src/clicache/src/impl/ManagedCacheLoader.cpp +++ b/src/clicache/src/impl/ManagedCacheLoader.cpp @@ -29,231 +29,237 @@ using namespace System::Text; using namespace System::Reflection; -namespace gemfire +namespace apache { - - CacheLoader* ManagedCacheLoaderGeneric::create( const char* assemblyPath, - const char* factoryFunctionName ) + namespace geode { - try + namespace client { - String^ mg_assemblyPath = - GemStone::GemFire::Cache::Generic::ManagedString::Get( assemblyPath ); - String^ mg_factoryFunctionName = - GemStone::GemFire::Cache::Generic::ManagedString::Get( factoryFunctionName ); - String^ mg_typeName = nullptr; - - String^ mg_genericKey = nullptr; - String^ mg_genericVal = nullptr; - - int32_t dotIndx = -1; - int32_t genericsOpenIndx = -1; - int32_t genericsCloseIndx = -1; - int32_t commaIndx = -1; - - if (mg_factoryFunctionName == nullptr || - ( dotIndx = mg_factoryFunctionName->LastIndexOf( '.' ) ) < 0 ) - { - std::string ex_str = "ManagedCacheLoaderGeneric: Factory function name '"; - ex_str += factoryFunctionName; - ex_str += "' does not contain type name"; - throw IllegalArgumentException( ex_str.c_str( ) ); - } - - if ((genericsCloseIndx = mg_factoryFunctionName->LastIndexOf( '>' )) < 0 ) - { - std::string ex_str = "ManagedCacheLoaderGeneric: Factory function name '"; - ex_str += factoryFunctionName; - ex_str += "' does not contain any generic type parameters"; - throw gemfire::IllegalArgumentException( ex_str.c_str( ) ); - } - - if ((genericsOpenIndx = mg_factoryFunctionName->LastIndexOf( '<' )) < 0 || - genericsOpenIndx > genericsCloseIndx) - { - std::string ex_str = "ManagedCacheLoaderGeneric: Factory function name '"; - ex_str += factoryFunctionName; - ex_str += "' does not contain expected generic type parameters"; - throw gemfire::IllegalArgumentException( ex_str.c_str( ) ); - } - if ((commaIndx = mg_factoryFunctionName->LastIndexOf( ',' )) < 0 || - (commaIndx < genericsOpenIndx || commaIndx > genericsCloseIndx)) - { - std::string ex_str = "ManagedCacheLoaderGeneric: Factory function name '"; - ex_str += factoryFunctionName; - ex_str += "' does not contain expected generic type parameter comma separator"; - throw gemfire::IllegalArgumentException( ex_str.c_str( ) ); - } - - StringBuilder^ typeBuilder = gcnew StringBuilder(mg_factoryFunctionName->Substring(0, genericsOpenIndx)); - mg_typeName = typeBuilder->ToString(); - mg_genericKey = mg_factoryFunctionName->Substring(genericsOpenIndx + 1, commaIndx - genericsOpenIndx - 1); - mg_genericKey = mg_genericKey->Trim(); - mg_genericVal = mg_factoryFunctionName->Substring(commaIndx + 1, genericsCloseIndx - commaIndx - 1); - mg_genericVal = mg_genericVal->Trim(); - mg_factoryFunctionName = mg_factoryFunctionName->Substring( dotIndx + 1 ); - - GemStone::GemFire::Cache::Generic::Log::Fine("Attempting to instantiate a [{0}<{1}, {2}>] via the [{3}] factory method.", - mg_typeName, mg_genericKey, mg_genericVal, mg_factoryFunctionName); - - typeBuilder->Append("`2"); - mg_typeName = typeBuilder->ToString(); - - Assembly^ assmb = nullptr; - try - { - assmb = Assembly::Load( mg_assemblyPath ); - } - catch (System::Exception^) + CacheLoader* ManagedCacheLoaderGeneric::create(const char* assemblyPath, + const char* factoryFunctionName) { - assmb = nullptr; - } - if (assmb == nullptr) - { - std::string ex_str = "ManagedCacheLoaderGeneric: Could not load assembly: "; - ex_str += assemblyPath; - throw IllegalArgumentException( ex_str.c_str( ) ); - } + try + { + String^ mg_assemblyPath = + GemStone::GemFire::Cache::Generic::ManagedString::Get(assemblyPath); + String^ mg_factoryFunctionName = + GemStone::GemFire::Cache::Generic::ManagedString::Get(factoryFunctionName); + String^ mg_typeName = nullptr; + + String^ mg_genericKey = nullptr; + String^ mg_genericVal = nullptr; + + int32_t dotIndx = -1; + int32_t genericsOpenIndx = -1; + int32_t genericsCloseIndx = -1; + int32_t commaIndx = -1; + + if (mg_factoryFunctionName == nullptr || + (dotIndx = mg_factoryFunctionName->LastIndexOf('.')) < 0) + { + std::string ex_str = "ManagedCacheLoaderGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain type name"; + throw IllegalArgumentException(ex_str.c_str()); + } - GemStone::GemFire::Cache::Generic::Log::Debug("Loading type: [{0}]", mg_typeName); + if ((genericsCloseIndx = mg_factoryFunctionName->LastIndexOf('>')) < 0) + { + std::string ex_str = "ManagedCacheLoaderGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain any generic type parameters"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } - Type^ typeInst = assmb->GetType(mg_typeName, false, true); + if ((genericsOpenIndx = mg_factoryFunctionName->LastIndexOf('<')) < 0 || + genericsOpenIndx > genericsCloseIndx) + { + std::string ex_str = "ManagedCacheLoaderGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain expected generic type parameters"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } - if (typeInst != nullptr) - { - array<Type^>^ types = gcnew array<Type^>(2); - types[0] = Type::GetType(mg_genericKey, false, true); - types[1] = Type::GetType(mg_genericVal, false, true); + if ((commaIndx = mg_factoryFunctionName->LastIndexOf(',')) < 0 || + (commaIndx < genericsOpenIndx || commaIndx > genericsCloseIndx)) + { + std::string ex_str = "ManagedCacheLoaderGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain expected generic type parameter comma separator"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } - if (types[0] == nullptr || types[1] == nullptr) - { - std::string ex_str = "ManagedCacheLoaderGeneric: Could not get both generic type argument instances"; - throw gemfire::IllegalArgumentException( ex_str.c_str( ) ); - } + StringBuilder^ typeBuilder = gcnew StringBuilder(mg_factoryFunctionName->Substring(0, genericsOpenIndx)); + mg_typeName = typeBuilder->ToString(); + mg_genericKey = mg_factoryFunctionName->Substring(genericsOpenIndx + 1, commaIndx - genericsOpenIndx - 1); + mg_genericKey = mg_genericKey->Trim(); + mg_genericVal = mg_factoryFunctionName->Substring(commaIndx + 1, genericsCloseIndx - commaIndx - 1); + mg_genericVal = mg_genericVal->Trim(); + mg_factoryFunctionName = mg_factoryFunctionName->Substring(dotIndx + 1); - typeInst = typeInst->MakeGenericType(types); - GemStone::GemFire::Cache::Generic::Log::Info("Loading function: [{0}]", mg_factoryFunctionName); + GemStone::GemFire::Cache::Generic::Log::Fine("Attempting to instantiate a [{0}<{1}, {2}>] via the [{3}] factory method.", + mg_typeName, mg_genericKey, mg_genericVal, mg_factoryFunctionName); - MethodInfo^ mInfo = typeInst->GetMethod( mg_factoryFunctionName, - BindingFlags::Public | BindingFlags::Static | BindingFlags::IgnoreCase ); + typeBuilder->Append("`2"); + mg_typeName = typeBuilder->ToString(); - if (mInfo != nullptr) - { - Object^ managedptr = nullptr; + Assembly^ assmb = nullptr; try { - managedptr = mInfo->Invoke(typeInst, nullptr); + assmb = Assembly::Load(mg_assemblyPath); } - catch (System::Exception^ ex) + catch (System::Exception^) { - GemStone::GemFire::Cache::Generic::Log::Debug("{0}: {1}", ex->GetType()->Name, ex->Message); - managedptr = nullptr; + assmb = nullptr; } - if (managedptr == nullptr) + if (assmb == nullptr) { - std::string ex_str = "ManagedCacheLoaderGeneric: Could not create " - "object on invoking factory function ["; - ex_str += factoryFunctionName; - ex_str += "] in assembly: "; + std::string ex_str = "ManagedCacheLoaderGeneric: Could not load assembly: "; ex_str += assemblyPath; - throw IllegalArgumentException( ex_str.c_str( ) ); + throw IllegalArgumentException(ex_str.c_str()); } - ManagedCacheLoaderGeneric* mgcl = new ManagedCacheLoaderGeneric(managedptr); + GemStone::GemFire::Cache::Generic::Log::Debug("Loading type: [{0}]", mg_typeName); - Type^ clgType = Type::GetType("GemStone.GemFire.Cache.Generic.CacheLoaderGeneric`2"); - clgType = clgType->MakeGenericType(types); - Object^ clg = Activator::CreateInstance(clgType); + Type^ typeInst = assmb->GetType(mg_typeName, false, true); - mInfo = clgType->GetMethod("SetCacheLoader"); - array<Object^>^ params = gcnew array<Object^>(1); - params[0] = managedptr; - mInfo->Invoke(clg, params); + if (typeInst != nullptr) + { + array<Type^>^ types = gcnew array<Type^>(2); + types[0] = Type::GetType(mg_genericKey, false, true); + types[1] = Type::GetType(mg_genericVal, false, true); + + if (types[0] == nullptr || types[1] == nullptr) + { + std::string ex_str = "ManagedCacheLoaderGeneric: Could not get both generic type argument instances"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } + + typeInst = typeInst->MakeGenericType(types); + GemStone::GemFire::Cache::Generic::Log::Info("Loading function: [{0}]", mg_factoryFunctionName); + + MethodInfo^ mInfo = typeInst->GetMethod(mg_factoryFunctionName, + BindingFlags::Public | BindingFlags::Static | BindingFlags::IgnoreCase); + + if (mInfo != nullptr) + { + Object^ managedptr = nullptr; + try + { + managedptr = mInfo->Invoke(typeInst, nullptr); + } + catch (System::Exception^ ex) + { + GemStone::GemFire::Cache::Generic::Log::Debug("{0}: {1}", ex->GetType()->Name, ex->Message); + managedptr = nullptr; + } + if (managedptr == nullptr) + { + std::string ex_str = "ManagedCacheLoaderGeneric: Could not create " + "object on invoking factory function ["; + ex_str += factoryFunctionName; + ex_str += "] in assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + + ManagedCacheLoaderGeneric* mgcl = new ManagedCacheLoaderGeneric(managedptr); + + Type^ clgType = Type::GetType("GemStone.GemFire.Cache.Generic.CacheLoaderGeneric`2"); + clgType = clgType->MakeGenericType(types); + Object^ clg = Activator::CreateInstance(clgType); + + mInfo = clgType->GetMethod("SetCacheLoader"); + array<Object^>^ params = gcnew array<Object^>(1); + params[0] = managedptr; + mInfo->Invoke(clg, params); + + mgcl->setptr((GemStone::GemFire::Cache::Generic::ICacheLoaderProxy^)clg); + + return mgcl; + } + else + { + std::string ex_str = "ManagedCacheLoaderGeneric: Could not load " + "function with name ["; + ex_str += factoryFunctionName; + ex_str += "] in assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + } + else + { + GemStone::GemFire::Cache::Generic::ManagedString typeName(mg_typeName); + std::string ex_str = "ManagedCacheLoaderGeneric: Could not load type ["; + ex_str += typeName.CharPtr; + ex_str += "] in assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + } + catch (const apache::geode::client::Exception&) + { + throw; + } + catch (System::Exception^ ex) + { + GemStone::GemFire::Cache::Generic::ManagedString mg_exStr(ex->ToString()); + std::string ex_str = "ManagedCacheLoaderGeneric: Got an exception while " + "loading managed library: "; + ex_str += mg_exStr.CharPtr; + throw IllegalArgumentException(ex_str.c_str()); + } + return NULL; + } + + CacheablePtr ManagedCacheLoaderGeneric::load(const RegionPtr& region, + const CacheableKeyPtr& key, const UserDataPtr& aCallbackArgument) + { + try { + /* + Region<Object^, Object^>^ mregion = + Region<Object^, Object^>::Create( region.ptr( ) ); + + ICacheableKey^ mkey = SafeGenericUMKeyConvert( key.ptr( ) ); - mgcl->setptr((GemStone::GemFire::Cache::Generic::ICacheLoaderProxy^)clg); + IGFSerializable^ mcallbackArg = SafeGenericUMSerializableConvert(aCallbackArgument.ptr()); + */ - return mgcl; + /* + return apache::geode::client::CacheablePtr(SafeMSerializableConvert( + m_managedptr->Load(mregion, mkey, mcallbackArg))); + */ + return m_managedptr->load(region, key, aCallbackArgument); } - else - { - std::string ex_str = "ManagedCacheLoaderGeneric: Could not load " - "function with name ["; - ex_str += factoryFunctionName; - ex_str += "] in assembly: "; - ex_str += assemblyPath; - throw IllegalArgumentException( ex_str.c_str( ) ); + catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); } + return NULLPTR; } - else + + void ManagedCacheLoaderGeneric::close(const RegionPtr& region) { - GemStone::GemFire::Cache::Generic::ManagedString typeName( mg_typeName ); - std::string ex_str = "ManagedCacheLoaderGeneric: Could not load type ["; - ex_str += typeName.CharPtr; - ex_str += "] in assembly: "; - ex_str += assemblyPath; - throw IllegalArgumentException( ex_str.c_str( ) ); + try { + /* + GemStone::GemFire::Cache::Region^ mregion = + GemStone::GemFire::Cache::Region::Create( region.ptr( ) ); + */ + + m_managedptr->close(region); + } + catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); + } } - } - catch (const gemfire::Exception&) - { - throw; - } - catch (System::Exception^ ex) - { - GemStone::GemFire::Cache::Generic::ManagedString mg_exStr( ex->ToString( ) ); - std::string ex_str = "ManagedCacheLoaderGeneric: Got an exception while " - "loading managed library: "; - ex_str += mg_exStr.CharPtr; - throw IllegalArgumentException( ex_str.c_str( ) ); - } - return NULL; - } - - CacheablePtr ManagedCacheLoaderGeneric::load(const RegionPtr& region, - const CacheableKeyPtr& key, const UserDataPtr& aCallbackArgument) - { - try { - /* - Region<Object^, Object^>^ mregion = - Region<Object^, Object^>::Create( region.ptr( ) ); - - ICacheableKey^ mkey = SafeGenericUMKeyConvert( key.ptr( ) ); - - IGFSerializable^ mcallbackArg = SafeGenericUMSerializableConvert(aCallbackArgument.ptr()); - */ - - /* - return gemfire::CacheablePtr(SafeMSerializableConvert( - m_managedptr->Load(mregion, mkey, mcallbackArg))); - */ - return m_managedptr->load(region, key, aCallbackArgument); - } - catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { - ex->ThrowNative(); - } - catch (System::Exception^ ex) { - GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); - } - return NULLPTR; - } - - void ManagedCacheLoaderGeneric::close( const RegionPtr& region ) - { - try { - /* - GemStone::GemFire::Cache::Region^ mregion = - GemStone::GemFire::Cache::Region::Create( region.ptr( ) ); - */ - - m_managedptr->close( region ); - } - catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { - ex->ThrowNative(); - } - catch (System::Exception^ ex) { - GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); - } - } - -} + + } // namespace client + } // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode/blob/e4fd74fb/src/clicache/src/impl/ManagedCacheLoader.hpp ---------------------------------------------------------------------- diff --git a/src/clicache/src/impl/ManagedCacheLoader.hpp b/src/clicache/src/impl/ManagedCacheLoader.hpp index 54be639..b15cdb3 100644 --- a/src/clicache/src/impl/ManagedCacheLoader.hpp +++ b/src/clicache/src/impl/ManagedCacheLoader.hpp @@ -24,128 +24,134 @@ #include "../ICacheLoader.hpp" #include "CacheLoader.hpp" -namespace gemfire +namespace apache { - - /// <summary> - /// Wraps the managed <see cref="GemStone.GemFire.Cache.ICacheLoader" /> - /// object and implements the native <c>gemfire::CacheLoader</c> interface. - /// </summary> - class ManagedCacheLoaderGeneric - : public gemfire::CacheLoader + namespace geode { - public: - - /// <summary> - /// Constructor to initialize with the provided managed object. - /// </summary> - /// <param name="userptr"> - /// The managed object. - /// </param> - inline ManagedCacheLoaderGeneric( - /*Generic::ICacheLoader<Object^, Object^>^ managedptr,*/ Object^ userptr ) - : /*m_managedptr( managedptr ),*/ m_userptr(userptr) { } - - /// <summary> - /// Static function to create a <c>ManagedCacheLoader</c> using given - /// managed assembly path and given factory function. - /// </summary> - /// <param name="assemblyPath"> - /// The path of the managed assembly that contains the <c>ICacheLoader</c> - /// factory function. - /// </param> - /// <param name="factoryFunctionName"> - /// The name of the factory function of the managed class for creating - /// an object that implements <c>ICacheLoader</c>. - /// This should be a static function of the format - /// {Namespace}.{Class Name}.{Method Name}. - /// </param> - /// <exception cref="IllegalArgumentException"> - /// If the managed library cannot be loaded or the factory function fails. - /// </exception> - static gemfire::CacheLoader* create( const char* assemblyPath, - const char* factoryFunctionName ); - - virtual ~ManagedCacheLoaderGeneric( ) { } - - /// <summary> - /// Loads a value. Application writers should implement this - /// method to customize the loading of a value. - /// </summary> - /// <remarks> - /// This method is called by the caching service when the requested - /// value is not in the cache. Any exception thrown by this method - /// is propagated back to and thrown by the invocation of - /// <see cref="GemStone.GemFire.Cache.Region.Get" /> that triggered this load. - /// </remarks> - /// <param name="region">a Region Pointer for which this is called.</param> - /// <param name="key">the key for the cacheable</param> - /// <param name="aCallbackArgument">any related user data, or null</param> - /// <returns> - /// the value supplied for this key, or null if no value can be - /// supplied. - /// If every available loader returns - /// a null value, <see cref="GemStone.GemFire.Cache.Region.Get" /> - /// will return null. - /// </returns> - /// <seealso cref="GemStone.GemFire.Cache.Region.Get" /> - virtual CacheablePtr load(const RegionPtr& region, - const CacheableKeyPtr& key, const UserDataPtr& aCallbackArgument); - - /// <summary> - /// Called when the region containing this callback is destroyed, when - /// the cache is closed. - /// </summary> - /// <remarks> - /// Implementations should clean up any external - /// resources, such as database connections. Any runtime exceptions this method - /// throws will be logged. - /// <para> - /// It is possible for this method to be called multiple times on a single - /// callback instance, so implementations must be tolerant of this. - /// </para> - /// </remarks> - /// <param name="region">the region pointer</param> - /// <seealso cref="GemStone.GemFire.Cache.Cache.Close" /> - /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> - virtual void close( const RegionPtr& region ); - - /* - /// <summary> - /// Returns the wrapped managed object reference. - /// </summary> - inline GemStone::GemFire::Cache::ICacheLoader^ ptr( ) const - { - return m_managedptr; - } - */ - - inline void setptr(GemStone::GemFire::Cache::Generic::ICacheLoaderProxy^ managedptr) - { - m_managedptr = managedptr; - } - - inline Object^ userptr( ) const + namespace client { - return m_userptr; - } - - - private: - - /// <summary> - /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). - /// Note: not using auto_gcroot since it will result in 'Dispose' of the ICacheLoader - /// to be called which is not what is desired when this object is destroyed. Normally this - /// managed object may be created by the user and will be handled automatically by the GC. - /// </summary> - gcroot<GemStone::GemFire::Cache::Generic::ICacheLoaderProxy^> m_managedptr; - - gcroot<Object^> m_userptr; - - // Disable the copy and assignment constructors - ManagedCacheLoaderGeneric( const ManagedCacheLoaderGeneric& ); - ManagedCacheLoaderGeneric& operator = ( const ManagedCacheLoaderGeneric& ); - }; -} + /// <summary> + /// Wraps the managed <see cref="GemStone.GemFire.Cache.ICacheLoader" /> + /// object and implements the native <c>apache::geode::client::CacheLoader</c> interface. + /// </summary> + class ManagedCacheLoaderGeneric + : public apache::geode::client::CacheLoader + { + public: + + /// <summary> + /// Constructor to initialize with the provided managed object. + /// </summary> + /// <param name="userptr"> + /// The managed object. + /// </param> + inline ManagedCacheLoaderGeneric( + /*Generic::ICacheLoader<Object^, Object^>^ managedptr,*/ Object^ userptr) + : /*m_managedptr( managedptr ),*/ m_userptr(userptr) { } + + /// <summary> + /// Static function to create a <c>ManagedCacheLoader</c> using given + /// managed assembly path and given factory function. + /// </summary> + /// <param name="assemblyPath"> + /// The path of the managed assembly that contains the <c>ICacheLoader</c> + /// factory function. + /// </param> + /// <param name="factoryFunctionName"> + /// The name of the factory function of the managed class for creating + /// an object that implements <c>ICacheLoader</c>. + /// This should be a static function of the format + /// {Namespace}.{Class Name}.{Method Name}. + /// </param> + /// <exception cref="IllegalArgumentException"> + /// If the managed library cannot be loaded or the factory function fails. + /// </exception> + static apache::geode::client::CacheLoader* create(const char* assemblyPath, + const char* factoryFunctionName); + + virtual ~ManagedCacheLoaderGeneric() { } + + /// <summary> + /// Loads a value. Application writers should implement this + /// method to customize the loading of a value. + /// </summary> + /// <remarks> + /// This method is called by the caching service when the requested + /// value is not in the cache. Any exception thrown by this method + /// is propagated back to and thrown by the invocation of + /// <see cref="GemStone.GemFire.Cache.Region.Get" /> that triggered this load. + /// </remarks> + /// <param name="region">a Region Pointer for which this is called.</param> + /// <param name="key">the key for the cacheable</param> + /// <param name="aCallbackArgument">any related user data, or null</param> + /// <returns> + /// the value supplied for this key, or null if no value can be + /// supplied. + /// If every available loader returns + /// a null value, <see cref="GemStone.GemFire.Cache.Region.Get" /> + /// will return null. + /// </returns> + /// <seealso cref="GemStone.GemFire.Cache.Region.Get" /> + virtual CacheablePtr load(const RegionPtr& region, + const CacheableKeyPtr& key, const UserDataPtr& aCallbackArgument); + + /// <summary> + /// Called when the region containing this callback is destroyed, when + /// the cache is closed. + /// </summary> + /// <remarks> + /// Implementations should clean up any external + /// resources, such as database connections. Any runtime exceptions this method + /// throws will be logged. + /// <para> + /// It is possible for this method to be called multiple times on a single + /// callback instance, so implementations must be tolerant of this. + /// </para> + /// </remarks> + /// <param name="region">the region pointer</param> + /// <seealso cref="GemStone.GemFire.Cache.Cache.Close" /> + /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> + virtual void close(const RegionPtr& region); + + /* + /// <summary> + /// Returns the wrapped managed object reference. + /// </summary> + inline GemStone::GemFire::Cache::ICacheLoader^ ptr( ) const + { + return m_managedptr; + } + */ + + inline void setptr(GemStone::GemFire::Cache::Generic::ICacheLoaderProxy^ managedptr) + { + m_managedptr = managedptr; + } + + inline Object^ userptr() const + { + return m_userptr; + } + + + private: + + /// <summary> + /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). + /// Note: not using auto_gcroot since it will result in 'Dispose' of the ICacheLoader + /// to be called which is not what is desired when this object is destroyed. Normally this + /// managed object may be created by the user and will be handled automatically by the GC. + /// </summary> + gcroot<GemStone::GemFire::Cache::Generic::ICacheLoaderProxy^> m_managedptr; + + gcroot<Object^> m_userptr; + + // Disable the copy and assignment constructors + ManagedCacheLoaderGeneric(const ManagedCacheLoaderGeneric&); + ManagedCacheLoaderGeneric& operator = (const ManagedCacheLoaderGeneric&); + }; + + } // namespace client + } // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode/blob/e4fd74fb/src/clicache/src/impl/ManagedCacheWriter.cpp ---------------------------------------------------------------------- diff --git a/src/clicache/src/impl/ManagedCacheWriter.cpp b/src/clicache/src/impl/ManagedCacheWriter.cpp index 47c36de..6583ead 100644 --- a/src/clicache/src/impl/ManagedCacheWriter.cpp +++ b/src/clicache/src/impl/ManagedCacheWriter.cpp @@ -31,279 +31,286 @@ using namespace System; using namespace System::Text; using namespace System::Reflection; -namespace gemfire +namespace apache { - - CacheWriter* ManagedCacheWriterGeneric::create( const char* assemblyPath, - const char* factoryFunctionName ) + namespace geode { - try + namespace client { - String^ mg_assemblyPath = - GemStone::GemFire::Cache::Generic::ManagedString::Get( assemblyPath ); - String^ mg_factoryFunctionName = - GemStone::GemFire::Cache::Generic::ManagedString::Get( factoryFunctionName ); - String^ mg_typeName = nullptr; - - String^ mg_genericKey = nullptr; - String^ mg_genericVal = nullptr; - - int32_t dotIndx = -1; - int32_t genericsOpenIndx = -1; - int32_t genericsCloseIndx = -1; - int32_t commaIndx = -1; - - if (mg_factoryFunctionName == nullptr || - ( dotIndx = mg_factoryFunctionName->LastIndexOf( '.' ) ) < 0 ) - { - std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; - ex_str += factoryFunctionName; - ex_str += "' does not contain type name"; - throw IllegalArgumentException( ex_str.c_str( ) ); - } - - if ((genericsCloseIndx = mg_factoryFunctionName->LastIndexOf( '>' )) < 0 ) - { - std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; - ex_str += factoryFunctionName; - ex_str += "' does not contain any generic type parameters"; - throw gemfire::IllegalArgumentException( ex_str.c_str( ) ); - } - if ((genericsOpenIndx = mg_factoryFunctionName->LastIndexOf( '<' )) < 0 || - genericsOpenIndx > genericsCloseIndx) + CacheWriter* ManagedCacheWriterGeneric::create(const char* assemblyPath, + const char* factoryFunctionName) { - std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; - ex_str += factoryFunctionName; - ex_str += "' does not contain expected generic type parameters"; - throw gemfire::IllegalArgumentException( ex_str.c_str( ) ); - } - - if ((commaIndx = mg_factoryFunctionName->LastIndexOf( ',' )) < 0 || - (commaIndx < genericsOpenIndx || commaIndx > genericsCloseIndx)) - { - std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; - ex_str += factoryFunctionName; - ex_str += "' does not contain expected generic type parameter comma separator"; - throw gemfire::IllegalArgumentException( ex_str.c_str( ) ); - } - - StringBuilder^ typeBuilder = gcnew StringBuilder(mg_factoryFunctionName->Substring(0, genericsOpenIndx)); - mg_typeName = typeBuilder->ToString(); - mg_genericKey = mg_factoryFunctionName->Substring(genericsOpenIndx + 1, commaIndx - genericsOpenIndx - 1); - mg_genericKey = mg_genericKey->Trim(); - mg_genericVal = mg_factoryFunctionName->Substring(commaIndx + 1, genericsCloseIndx - commaIndx - 1); - mg_genericVal = mg_genericVal->Trim(); - mg_factoryFunctionName = mg_factoryFunctionName->Substring( dotIndx + 1 ); - - GemStone::GemFire::Cache::Generic::Log::Fine( - "Attempting to instantiate a [{0}<{1}, {2}>] via the [{3}] factory method.", - mg_typeName, mg_genericKey, mg_genericVal, mg_factoryFunctionName); + try + { + String^ mg_assemblyPath = + GemStone::GemFire::Cache::Generic::ManagedString::Get(assemblyPath); + String^ mg_factoryFunctionName = + GemStone::GemFire::Cache::Generic::ManagedString::Get(factoryFunctionName); + String^ mg_typeName = nullptr; + + String^ mg_genericKey = nullptr; + String^ mg_genericVal = nullptr; + + int32_t dotIndx = -1; + int32_t genericsOpenIndx = -1; + int32_t genericsCloseIndx = -1; + int32_t commaIndx = -1; + + if (mg_factoryFunctionName == nullptr || + (dotIndx = mg_factoryFunctionName->LastIndexOf('.')) < 0) + { + std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain type name"; + throw IllegalArgumentException(ex_str.c_str()); + } - typeBuilder->Append("`2"); - mg_typeName = typeBuilder->ToString(); + if ((genericsCloseIndx = mg_factoryFunctionName->LastIndexOf('>')) < 0) + { + std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain any generic type parameters"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } - Assembly^ assmb = nullptr; - try - { - assmb = Assembly::Load( mg_assemblyPath ); - } - catch (System::Exception^) - { - assmb = nullptr; - } - if (assmb == nullptr) - { - std::string ex_str = "ManagedCacheWriterGeneric: Could not load assembly: "; - ex_str += assemblyPath; - throw IllegalArgumentException( ex_str.c_str( ) ); - } - - GemStone::GemFire::Cache::Generic::Log::Debug("Loading type: [{0}]", mg_typeName); + if ((genericsOpenIndx = mg_factoryFunctionName->LastIndexOf('<')) < 0 || + genericsOpenIndx > genericsCloseIndx) + { + std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain expected generic type parameters"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } - Type^ typeInst = assmb->GetType(mg_typeName, false, true); + if ((commaIndx = mg_factoryFunctionName->LastIndexOf(',')) < 0 || + (commaIndx < genericsOpenIndx || commaIndx > genericsCloseIndx)) + { + std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain expected generic type parameter comma separator"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } - if (typeInst != nullptr) - { - array<Type^>^ types = gcnew array<Type^>(2); - types[0] = Type::GetType(mg_genericKey, false, true); - types[1] = Type::GetType(mg_genericVal, false, true); + StringBuilder^ typeBuilder = gcnew StringBuilder(mg_factoryFunctionName->Substring(0, genericsOpenIndx)); + mg_typeName = typeBuilder->ToString(); + mg_genericKey = mg_factoryFunctionName->Substring(genericsOpenIndx + 1, commaIndx - genericsOpenIndx - 1); + mg_genericKey = mg_genericKey->Trim(); + mg_genericVal = mg_factoryFunctionName->Substring(commaIndx + 1, genericsCloseIndx - commaIndx - 1); + mg_genericVal = mg_genericVal->Trim(); + mg_factoryFunctionName = mg_factoryFunctionName->Substring(dotIndx + 1); - if (types[0] == nullptr || types[1] == nullptr) - { - std::string ex_str = "ManagedCacheWriterGeneric: Could not get both generic type argument instances"; - throw gemfire::IllegalArgumentException( ex_str.c_str( ) ); - } + GemStone::GemFire::Cache::Generic::Log::Fine( + "Attempting to instantiate a [{0}<{1}, {2}>] via the [{3}] factory method.", + mg_typeName, mg_genericKey, mg_genericVal, mg_factoryFunctionName); - typeInst = typeInst->MakeGenericType(types); - GemStone::GemFire::Cache::Generic::Log::Info("Loading function: [{0}]", mg_factoryFunctionName); + typeBuilder->Append("`2"); + mg_typeName = typeBuilder->ToString(); - MethodInfo^ mInfo = typeInst->GetMethod( mg_factoryFunctionName, - BindingFlags::Public | BindingFlags::Static | BindingFlags::IgnoreCase ); - if (mInfo != nullptr) - { - Object^ managedptr = nullptr; + Assembly^ assmb = nullptr; try { - managedptr = mInfo->Invoke( typeInst, nullptr ); + assmb = Assembly::Load(mg_assemblyPath); } - catch (System::Exception^ ex) + catch (System::Exception^) { - GemStone::GemFire::Cache::Generic::Log::Debug("{0}: {1}", ex->GetType()->Name, ex->Message); - managedptr = nullptr; + assmb = nullptr; } - if (managedptr == nullptr) + if (assmb == nullptr) { - std::string ex_str = "ManagedCacheWriterGeneric: Could not create " - "object on invoking factory function ["; - ex_str += factoryFunctionName; + std::string ex_str = "ManagedCacheWriterGeneric: Could not load assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + + GemStone::GemFire::Cache::Generic::Log::Debug("Loading type: [{0}]", mg_typeName); + + Type^ typeInst = assmb->GetType(mg_typeName, false, true); + + if (typeInst != nullptr) + { + array<Type^>^ types = gcnew array<Type^>(2); + types[0] = Type::GetType(mg_genericKey, false, true); + types[1] = Type::GetType(mg_genericVal, false, true); + + if (types[0] == nullptr || types[1] == nullptr) + { + std::string ex_str = "ManagedCacheWriterGeneric: Could not get both generic type argument instances"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } + + typeInst = typeInst->MakeGenericType(types); + GemStone::GemFire::Cache::Generic::Log::Info("Loading function: [{0}]", mg_factoryFunctionName); + + MethodInfo^ mInfo = typeInst->GetMethod(mg_factoryFunctionName, + BindingFlags::Public | BindingFlags::Static | BindingFlags::IgnoreCase); + if (mInfo != nullptr) + { + Object^ managedptr = nullptr; + try + { + managedptr = mInfo->Invoke(typeInst, nullptr); + } + catch (System::Exception^ ex) + { + GemStone::GemFire::Cache::Generic::Log::Debug("{0}: {1}", ex->GetType()->Name, ex->Message); + managedptr = nullptr; + } + if (managedptr == nullptr) + { + std::string ex_str = "ManagedCacheWriterGeneric: Could not create " + "object on invoking factory function ["; + ex_str += factoryFunctionName; + ex_str += "] in assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + ManagedCacheWriterGeneric* mgcw = new ManagedCacheWriterGeneric(managedptr); + + Type^ cwgType = Type::GetType("GemStone.GemFire.Cache.Generic.CacheWriterGeneric`2"); + cwgType = cwgType->MakeGenericType(types); + Object^ cwg = Activator::CreateInstance(cwgType); + + mInfo = cwgType->GetMethod("SetCacheWriter"); + array<Object^>^ params = gcnew array<Object^>(1); + params[0] = managedptr; + mInfo->Invoke(cwg, params); + + mgcw->setptr((GemStone::GemFire::Cache::Generic::ICacheWriter<Object^, Object^>^)cwg); + + return mgcw; + } + else + { + std::string ex_str = "ManagedCacheWriterGeneric: Could not load " + "function with name ["; + ex_str += factoryFunctionName; + ex_str += "] in assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + } + else + { + GemStone::GemFire::Cache::Generic::ManagedString typeName(mg_typeName); + std::string ex_str = "ManagedCacheWriterGeneric: Could not load type ["; + ex_str += typeName.CharPtr; ex_str += "] in assembly: "; ex_str += assemblyPath; - throw IllegalArgumentException( ex_str.c_str( ) ); + throw IllegalArgumentException(ex_str.c_str()); } - ManagedCacheWriterGeneric* mgcw = new ManagedCacheWriterGeneric(managedptr); + } + catch (const apache::geode::client::Exception&) + { + throw; + } + catch (System::Exception^ ex) + { + GemStone::GemFire::Cache::Generic::ManagedString mg_exStr(ex->ToString()); + std::string ex_str = "ManagedCacheWriterGeneric: Got an exception while " + "loading managed library: "; + ex_str += mg_exStr.CharPtr; + throw IllegalArgumentException(ex_str.c_str()); + } + return NULL; + } - Type^ cwgType = Type::GetType("GemStone.GemFire.Cache.Generic.CacheWriterGeneric`2"); - cwgType = cwgType->MakeGenericType(types); - Object^ cwg = Activator::CreateInstance(cwgType); + bool ManagedCacheWriterGeneric::beforeUpdate(const EntryEvent& ev) + { + try { + GemStone::GemFire::Cache::Generic::EntryEvent<Object^, Object^> mevent(&ev); - mInfo = cwgType->GetMethod("SetCacheWriter"); - array<Object^>^ params = gcnew array<Object^>(1); - params[0] = managedptr; - mInfo->Invoke(cwg, params); + return m_managedptr->BeforeUpdate(%mevent); + } + catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); + } + return false; + } - mgcw->setptr((GemStone::GemFire::Cache::Generic::ICacheWriter<Object^, Object^>^)cwg); + bool ManagedCacheWriterGeneric::beforeCreate(const EntryEvent& ev) + { + try { + GemStone::GemFire::Cache::Generic::EntryEvent<Object^, Object^> mevent(&ev); - return mgcw; + return m_managedptr->BeforeCreate(%mevent); } - else - { - std::string ex_str = "ManagedCacheWriterGeneric: Could not load " - "function with name ["; - ex_str += factoryFunctionName; - ex_str += "] in assembly: "; - ex_str += assemblyPath; - throw IllegalArgumentException( ex_str.c_str( ) ); + catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); } + return false; } - else + + bool ManagedCacheWriterGeneric::beforeDestroy(const EntryEvent& ev) { - GemStone::GemFire::Cache::Generic::ManagedString typeName( mg_typeName ); - std::string ex_str = "ManagedCacheWriterGeneric: Could not load type ["; - ex_str += typeName.CharPtr; - ex_str += "] in assembly: "; - ex_str += assemblyPath; - throw IllegalArgumentException( ex_str.c_str( ) ); + try { + GemStone::GemFire::Cache::Generic::EntryEvent<Object^, Object^> mevent(&ev); + + return m_managedptr->BeforeDestroy(%mevent); + } + catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); + } + return false; } - } - catch (const gemfire::Exception&) - { - throw; - } - catch (System::Exception^ ex) - { - GemStone::GemFire::Cache::Generic::ManagedString mg_exStr( ex->ToString( ) ); - std::string ex_str = "ManagedCacheWriterGeneric: Got an exception while " - "loading managed library: "; - ex_str += mg_exStr.CharPtr; - throw IllegalArgumentException( ex_str.c_str( ) ); - } - return NULL; - } - - bool ManagedCacheWriterGeneric::beforeUpdate( const EntryEvent& ev ) - { - try { - GemStone::GemFire::Cache::Generic::EntryEvent<Object^, Object^> mevent( &ev ); - - return m_managedptr->BeforeUpdate( %mevent ); - } - catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { - ex->ThrowNative(); - } - catch (System::Exception^ ex) { - GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); - } - return false; - } - - bool ManagedCacheWriterGeneric::beforeCreate( const EntryEvent& ev ) - { - try { - GemStone::GemFire::Cache::Generic::EntryEvent<Object^, Object^> mevent( &ev ); - - return m_managedptr->BeforeCreate( %mevent ); - } - catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { - ex->ThrowNative(); - } - catch (System::Exception^ ex) { - GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); - } - return false; - } - - bool ManagedCacheWriterGeneric::beforeDestroy( const EntryEvent& ev ) - { - try { - GemStone::GemFire::Cache::Generic::EntryEvent<Object^, Object^> mevent( &ev ); - - return m_managedptr->BeforeDestroy( %mevent ); - } - catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { - ex->ThrowNative(); - } - catch (System::Exception^ ex) { - GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); - } - return false; - } - bool ManagedCacheWriterGeneric::beforeRegionClear( const RegionEvent& ev ) - { - try { - GemStone::GemFire::Cache::Generic::RegionEvent<Object^, Object^> mevent( &ev ); - - return m_managedptr->BeforeRegionClear( %mevent ); - } - catch ( GemStone::GemFire::Cache::Generic::GemFireException^ ex ) { - ex->ThrowNative( ); - } - catch ( System::Exception^ ex ) { - GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); - } - return false; - } - - bool ManagedCacheWriterGeneric::beforeRegionDestroy( const RegionEvent& ev ) - { - try { - GemStone::GemFire::Cache::Generic::RegionEvent<Object^, Object^> mevent( &ev ); - - return m_managedptr->BeforeRegionDestroy( %mevent ); - } - catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { - ex->ThrowNative(); - } - catch (System::Exception^ ex) { - GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); - } - return false; - } - - void ManagedCacheWriterGeneric::close( const RegionPtr& rp ) - { - try { - GemStone::GemFire::Cache::Generic::IRegion<Object^, Object^>^ mregion = - GemStone::GemFire::Cache::Generic::Region<Object^, Object^>::Create( rp.ptr( ) ); - - m_managedptr->Close(reinterpret_cast<GemStone::GemFire::Cache::Generic::Region<Object^, Object^>^>(mregion)); - } - catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { - ex->ThrowNative(); - } - catch (System::Exception^ ex) { - GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); - } - } - -} + bool ManagedCacheWriterGeneric::beforeRegionClear(const RegionEvent& ev) + { + try { + GemStone::GemFire::Cache::Generic::RegionEvent<Object^, Object^> mevent(&ev); + + return m_managedptr->BeforeRegionClear(%mevent); + } + catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); + } + return false; + } + + bool ManagedCacheWriterGeneric::beforeRegionDestroy(const RegionEvent& ev) + { + try { + GemStone::GemFire::Cache::Generic::RegionEvent<Object^, Object^> mevent(&ev); + + return m_managedptr->BeforeRegionDestroy(%mevent); + } + catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); + } + return false; + } + + void ManagedCacheWriterGeneric::close(const RegionPtr& rp) + { + try { + GemStone::GemFire::Cache::Generic::IRegion<Object^, Object^>^ mregion = + GemStone::GemFire::Cache::Generic::Region<Object^, Object^>::Create(rp.ptr()); + + m_managedptr->Close(reinterpret_cast<GemStone::GemFire::Cache::Generic::Region<Object^, Object^>^>(mregion)); + } + catch (GemStone::GemFire::Cache::Generic::GemFireException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + GemStone::GemFire::Cache::Generic::GemFireException::ThrowNative(ex); + } + } + + } // namespace client + } // namespace geode +} // namespace apache + http://git-wip-us.apache.org/repos/asf/geode/blob/e4fd74fb/src/clicache/src/impl/ManagedCacheWriter.hpp ---------------------------------------------------------------------- diff --git a/src/clicache/src/impl/ManagedCacheWriter.hpp b/src/clicache/src/impl/ManagedCacheWriter.hpp index 12ae5e0..f27c5bf 100644 --- a/src/clicache/src/impl/ManagedCacheWriter.hpp +++ b/src/clicache/src/impl/ManagedCacheWriter.hpp @@ -23,7 +23,7 @@ #include "../ICacheWriter.hpp" using namespace System; -//using namespace gemfire; +//using namespace apache::geode::client; namespace GemStone { namespace GemFire @@ -35,159 +35,165 @@ namespace GemStone } } -namespace gemfire +namespace apache { - - /// <summary> - /// Wraps the managed <see cref="GemStone.GemFire.Cache.ICacheWriter" /> - /// object and implements the native <c>gemfire::CacheWriter</c> interface. - /// </summary> - class ManagedCacheWriterGeneric - : public CacheWriter + namespace geode { - public: - - /// <summary> - /// Constructor to initialize with the provided managed object. - /// </summary> - /// <param name="userptr"> - /// The managed object. - /// </param> - inline ManagedCacheWriterGeneric( Object^ userptr ) : m_userptr( userptr ) { } - - /// <summary> - /// Static function to create a <c>ManagedCacheWriter</c> using given - /// managed assembly path and given factory function. - /// </summary> - /// <param name="assemblyPath"> - /// The path of the managed assembly that contains the <c>ICacheWriter</c> - /// factory function. - /// </param> - /// <param name="factoryFunctionName"> - /// The name of the factory function of the managed class for creating - /// an object that implements <c>ICacheWriter</c>. - /// This should be a static function of the format - /// {Namespace}.{Class Name}.{Method Name}. - /// </param> - /// <exception cref="IllegalArgumentException"> - /// If the managed library cannot be loaded or the factory function fails. - /// </exception> - static CacheWriter* create( const char* assemblyPath, - const char* factoryFunctionName ); - - virtual ~ManagedCacheWriterGeneric( ) { } - - /// <summary> - /// Called before an entry is updated. The entry update is initiated by a - /// <c>put</c> or a <c>get</c> that causes the loader to update an existing entry. - /// </summary> - /// <remarks> - /// The entry previously existed in the cache where the operation was - /// initiated, although the old value may have been null. The entry being - /// updated may or may not exist in the local cache where the CacheWriter is - /// installed. - /// </remarks> - /// <param name="ev"> - /// EntryEvent denotes the event object associated with updating the entry - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Region.Put" /> - /// <seealso cref="GemStone.GemFire.Cache.Region.Get" /> - bool beforeUpdate( const EntryEvent& ev ); - - /// <summary> - /// Called before an entry is created. Entry creation is initiated by a - /// <c>create</c>, a <c>put</c>, or a <c>get</c>. - /// </summary> - /// <remarks> - /// The <c>CacheWriter</c> can determine whether this value comes from a - /// <c>get</c> or not from <c>load</c>. The entry being created may already - /// exist in the local cache where this <c>CacheWriter</c> is installed, - /// but it does not yet exist in the cache where the operation was initiated. - /// </remarks> - /// <param name="ev"> - /// EntryEvent denotes the event object associated with creating the entry - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Region.Create" /> - /// <seealso cref="GemStone.GemFire.Cache.Region.Put" /> - /// <seealso cref="GemStone.GemFire.Cache.Region.Get" /> - bool beforeCreate( const EntryEvent& ev ); - - /// <summary> - /// Called before an entry is destroyed. - /// </summary> - /// <remarks> - /// The entry being destroyed may or may - /// not exist in the local cache where the CacheWriter is installed. This method - /// is <em>not</em> called as a result of expiration or - /// <see cref="GemStone.GemFire.Cache.Region.LocalDestroyRegion" />. - /// </remarks> - /// <param name="ev"> - /// EntryEvent denotes the event object associated with destroying the entry - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Region.Destroy" /> - bool beforeDestroy( const EntryEvent& ev ); - - /// <summary> - /// called before this region is cleared - /// </summary> - bool beforeRegionClear( const RegionEvent& ev ); - - /// <summary> - /// called before this region is destroyed - /// </summary> - /// <param name="ev"> - /// RegionEvent denotes the event object associated with destroying the region - /// </param> - /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> - bool beforeRegionDestroy( const RegionEvent& ev ); - - /// <summary> - /// Called when the region containing this callback is destroyed, when - /// the cache is closed. - /// </summary> - /// <remarks> - /// Implementations should clean up any external - /// resources, such as database connections. Any runtime exceptions this method - /// throws will be logged. - /// <para> - /// It is possible for this method to be called multiple times on a single - /// callback instance, so implementations must be tolerant of this. - /// </para> - /// </remarks> - /// <seealso cref="GemStone.GemFire.Cache.Cache.Close" /> - /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> - void close( const RegionPtr& rp ); - - /// <summary> - /// Returns the wrapped managed object reference. - /// </summary> - inline GemStone::GemFire::Cache::Generic::ICacheWriter<Object^, Object^>^ ptr( ) const + namespace client { - return m_managedptr; - } - inline void setptr( GemStone::GemFire::Cache::Generic::ICacheWriter<Object^, Object^>^ managedptr ) - { - m_managedptr = managedptr; - } - - inline Object^ userptr( ) const - { - return m_userptr; - } - - - private: - - /// <summary> - /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). - /// Note: not using auto_gcroot since it will result in 'Dispose' of the ICacheWriter - /// to be called which is not what is desired when this object is destroyed. Normally this - /// managed object may be created by the user and will be handled automatically by the GC. - /// </summary> - gcroot<GemStone::GemFire::Cache::Generic::ICacheWriter<Object^, Object^>^> m_managedptr; - - gcroot<Object^> m_userptr; - }; - -} + /// <summary> + /// Wraps the managed <see cref="GemStone.GemFire.Cache.ICacheWriter" /> + /// object and implements the native <c>apache::geode::client::CacheWriter</c> interface. + /// </summary> + class ManagedCacheWriterGeneric + : public CacheWriter + { + public: + + /// <summary> + /// Constructor to initialize with the provided managed object. + /// </summary> + /// <param name="userptr"> + /// The managed object. + /// </param> + inline ManagedCacheWriterGeneric(Object^ userptr) : m_userptr(userptr) { } + + /// <summary> + /// Static function to create a <c>ManagedCacheWriter</c> using given + /// managed assembly path and given factory function. + /// </summary> + /// <param name="assemblyPath"> + /// The path of the managed assembly that contains the <c>ICacheWriter</c> + /// factory function. + /// </param> + /// <param name="factoryFunctionName"> + /// The name of the factory function of the managed class for creating + /// an object that implements <c>ICacheWriter</c>. + /// This should be a static function of the format + /// {Namespace}.{Class Name}.{Method Name}. + /// </param> + /// <exception cref="IllegalArgumentException"> + /// If the managed library cannot be loaded or the factory function fails. + /// </exception> + static CacheWriter* create(const char* assemblyPath, + const char* factoryFunctionName); + + virtual ~ManagedCacheWriterGeneric() { } + + /// <summary> + /// Called before an entry is updated. The entry update is initiated by a + /// <c>put</c> or a <c>get</c> that causes the loader to update an existing entry. + /// </summary> + /// <remarks> + /// The entry previously existed in the cache where the operation was + /// initiated, although the old value may have been null. The entry being + /// updated may or may not exist in the local cache where the CacheWriter is + /// installed. + /// </remarks> + /// <param name="ev"> + /// EntryEvent denotes the event object associated with updating the entry + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Region.Put" /> + /// <seealso cref="GemStone.GemFire.Cache.Region.Get" /> + bool beforeUpdate(const EntryEvent& ev); + + /// <summary> + /// Called before an entry is created. Entry creation is initiated by a + /// <c>create</c>, a <c>put</c>, or a <c>get</c>. + /// </summary> + /// <remarks> + /// The <c>CacheWriter</c> can determine whether this value comes from a + /// <c>get</c> or not from <c>load</c>. The entry being created may already + /// exist in the local cache where this <c>CacheWriter</c> is installed, + /// but it does not yet exist in the cache where the operation was initiated. + /// </remarks> + /// <param name="ev"> + /// EntryEvent denotes the event object associated with creating the entry + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Region.Create" /> + /// <seealso cref="GemStone.GemFire.Cache.Region.Put" /> + /// <seealso cref="GemStone.GemFire.Cache.Region.Get" /> + bool beforeCreate(const EntryEvent& ev); + + /// <summary> + /// Called before an entry is destroyed. + /// </summary> + /// <remarks> + /// The entry being destroyed may or may + /// not exist in the local cache where the CacheWriter is installed. This method + /// is <em>not</em> called as a result of expiration or + /// <see cref="GemStone.GemFire.Cache.Region.LocalDestroyRegion" />. + /// </remarks> + /// <param name="ev"> + /// EntryEvent denotes the event object associated with destroying the entry + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Region.Destroy" /> + bool beforeDestroy(const EntryEvent& ev); + + /// <summary> + /// called before this region is cleared + /// </summary> + bool beforeRegionClear(const RegionEvent& ev); + + /// <summary> + /// called before this region is destroyed + /// </summary> + /// <param name="ev"> + /// RegionEvent denotes the event object associated with destroying the region + /// </param> + /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> + bool beforeRegionDestroy(const RegionEvent& ev); + + /// <summary> + /// Called when the region containing this callback is destroyed, when + /// the cache is closed. + /// </summary> + /// <remarks> + /// Implementations should clean up any external + /// resources, such as database connections. Any runtime exceptions this method + /// throws will be logged. + /// <para> + /// It is possible for this method to be called multiple times on a single + /// callback instance, so implementations must be tolerant of this. + /// </para> + /// </remarks> + /// <seealso cref="GemStone.GemFire.Cache.Cache.Close" /> + /// <seealso cref="GemStone.GemFire.Cache.Region.DestroyRegion" /> + void close(const RegionPtr& rp); + + /// <summary> + /// Returns the wrapped managed object reference. + /// </summary> + inline GemStone::GemFire::Cache::Generic::ICacheWriter<Object^, Object^>^ ptr() const + { + return m_managedptr; + } + + inline void setptr(GemStone::GemFire::Cache::Generic::ICacheWriter<Object^, Object^>^ managedptr) + { + m_managedptr = managedptr; + } + + inline Object^ userptr() const + { + return m_userptr; + } + + + private: + + /// <summary> + /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). + /// Note: not using auto_gcroot since it will result in 'Dispose' of the ICacheWriter + /// to be called which is not what is desired when this object is destroyed. Normally this + /// managed object may be created by the user and will be handled automatically by the GC. + /// </summary> + gcroot<GemStone::GemFire::Cache::Generic::ICacheWriter<Object^, Object^>^> m_managedptr; + + gcroot<Object^> m_userptr; + }; + + } // namespace client + } // namespace geode +} // namespace apache