Vault
4.1
|
00001 /* 00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved. 00003 This file is part of the Code Vault version 4.1 00004 http://www.bombaydigital.com/ 00005 License: MIT. See LICENSE.md in the Vault top level directory. 00006 */ 00007 00008 #ifndef vmessagehandler_h 00009 #define vmessagehandler_h 00010 00011 #include "vtypes.h" 00012 #include "vstring.h" 00013 #include "vmutex.h" 00014 #include "vmutexlocker.h" 00015 #include "vmessage.h" 00016 #include "vclientsession.h" 00017 00024 class VServer; 00025 class VSocketThread; 00026 00027 class VMessageHandlerFactory; 00028 typedef std::map<VMessageID, VMessageHandlerFactory*> VMessageHandlerFactoryMap; 00029 00052 class VMessageHandler { 00053 public: 00054 00066 static VMessageHandler* get(VMessagePtr m, VServer* server, VClientSessionPtr session, VSocketThread* thread); 00073 static void registerHandlerFactory(VMessageID messageID, VMessageHandlerFactory* factory); 00074 00090 VMessageHandler(const VString& name, VMessagePtr m, VServer* server, VClientSessionPtr session, VSocketThread* thread, const VMessageFactory* messageFactory, VMutex* mutex); 00095 virtual ~VMessageHandler(); 00096 00100 virtual void processMessage() = 0; 00107 VMessagePtr getMessage(VMessageID messageID); 00126 void logMessageContentRecord(const VString& details, VNamedLoggerPtr logger = VNamedLoggerPtr()) const; 00145 void logMessageContentFields(const VString& details, VNamedLoggerPtr logger = VNamedLoggerPtr()) const; 00149 void logMessageDetailsFields(const VString& details, VNamedLoggerPtr logger = VNamedLoggerPtr()) const; 00154 virtual void logProcessMessageStart() const; 00159 virtual void logProcessMessageEnd() const; 00160 00161 protected: 00162 00168 void _logDetailedDispatch(const VString& dispatchInfo) const; 00175 void _logMessageContentRecord(const VString& contentInfo) const; 00176 VNamedLoggerPtr _getMessageContentRecordLogger() const; 00177 00183 void _logMessageContentFields(const VString& contentInfo) const; 00184 VNamedLoggerPtr _getMessageContentFieldsLogger() const; 00185 00192 void _logMessageContentHexDump(const VString& info, const Vu8* buffer, Vs64 length) const; 00193 00194 VString mName; 00195 VString mLoggerName; 00196 VMessagePtr mMessage; 00197 VServer* mServer; 00198 VClientSessionPtr mSession; 00199 VSocketThread* mThread; 00200 const VMessageFactory* mMessageFactory; 00201 VInstant mStartTime; 00202 VMutexLocker mLocker; 00203 VInstant mUnblockTime; 00204 VString mSessionName; 00205 00206 private: 00207 00208 VMessageHandler(const VMessageHandler&); // not copyable 00209 VMessageHandler& operator=(const VMessageHandler&); // not assignable 00210 00211 static VMessageHandlerFactoryMap* mapInstance(); 00212 00213 static VMessageHandlerFactoryMap* gFactoryMap; 00214 }; 00215 00223 class VMessageHandlerFactory { 00224 public: 00225 00226 VMessageHandlerFactory() {} 00227 virtual ~VMessageHandlerFactory() {} 00228 00237 virtual VMessageHandler* createHandler(VMessagePtr m, VServer* server, VClientSessionPtr session, VSocketThread* thread) = 0; 00238 }; 00239 00240 // This macro goes in the handler's .h file to define the handler's factory. 00241 #define DEFINE_MESSAGE_HANDLER_FACTORY(messageid, factoryclassname, handlerclassname, descriptivename) \ 00242 class factoryclassname : public VMessageHandlerFactory { \ 00243 public: \ 00244 \ 00245 factoryclassname() : VMessageHandlerFactory(), mName(VSTRING_ARGS("%s (%s)",#handlerclassname,descriptivename)) { VMessageHandler::registerHandlerFactory(messageid, this); } \ 00246 virtual ~factoryclassname() {} \ 00247 \ 00248 virtual VMessageHandler* createHandler(VMessagePtr m, VServer* server, VClientSessionPtr session, VSocketThread* thread) \ 00249 { return new handlerclassname(mName, m, server, session, thread); } \ 00250 \ 00251 private: \ 00252 \ 00253 static factoryclassname gFactory; \ 00254 VString mName; \ 00255 \ 00256 } 00257 00258 // This macro goes in the handler's .cpp file to declare the handler's factory. 00259 #define DECLARE_MESSAGE_HANDLER_FACTORY(factoryclassname) \ 00260 factoryclassname factoryclassname::gFactory 00261 00262 // This macro goes in a global init function to prevent linker dead-stripping 00263 // of the static initialization in the previous macro. 00264 #define FORCE_LINK_MESSAGE_HANDLER_FACTORY(factoryclassname) \ 00265 if (false) { factoryclassname dummy; } 00266 00274 class VMessageHandlerTask { 00275 public: 00276 00277 VMessageHandlerTask(VClientSessionPtr session) : mSession(session) {} 00278 virtual ~VMessageHandlerTask() {} 00279 00280 protected: 00281 00282 VClientSessionPtr mSession; 00283 00284 }; 00285 00286 #endif /* vmessagehandler_h */