Savarese Software Research Corporation
WebServiceModule.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2009 Savarese Software Research Corporation
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     https://www.savarese.com/software/ApacheLicense-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00022 #ifndef __SSRC_WSPR_WS_WEB_SERVICE_MODULE_H
00023 #define __SSRC_WSPR_WS_WEB_SERVICE_MODULE_H
00024 
00025 #include <ssrc/wispers/service/service.h>
00026 #include <ssrc/wispers/ws/types.h>
00027 #include <ssrc/wispers/utility/Properties.h>
00028 
00029 __BEGIN_NS_SSRC_WSPR_WS
00030 
00031 using NS_SSRC_WISP_PROTOCOL::CallException;
00032 using NS_SSRC_WSPR_SERVICE::timeout_handler;
00033 using NS_SSRC_WSPR_SERVICE::timeout_ptr;
00034 using NS_SSRC_WSPR_SERVICE::message_handler_type;
00035 using NS_SSRC_WSPR_SERVICE::message_handler_entry;
00036 using NS_SSRC_WSPR_SERVICE::message_handler_map;
00037 using NS_SSRC_WSPR_SERVICE::EventLoop;
00038 using NS_SSRC_WSPR_UTILITY::Properties;
00039 
00040 // Forward declaration
00041 class WebServiceRunner;
00042 
00049 struct WebServiceModuleContext {
00050   typedef WebServiceProtocol protocol_traits;
00051   WISP_IMPORT(protocol_traits, packing_traits);
00052   typedef NS_SSRC_WISP_PROTOCOL::ContinuationCaller<packing_traits> caller_type;
00053 
00054   caller_type & caller;
00055   const string ws_type;
00056   const Properties & properties;
00057 
00058   timeout_ptr schedule_timeout(const timeout_handler & handler,
00059                                const TimeValue & timeout,
00060                                const bool once = EventLoop::Persist);
00061 
00062   void cancel_timeout(const timeout_ptr & timeout);
00063 
00064 private:
00065   friend class WebServiceRunner;
00066 
00067   WebServiceModuleContext(WebServiceRunner & runner,
00068                           caller_type & caller,
00069                           const string & ws_type,
00070                           const Properties & properties) :
00071     caller(caller), ws_type(ws_type), properties(properties),
00072     _runner(runner)
00073   { }
00074 
00075   WebServiceRunner & _runner;
00076 };
00077 
00078 typedef boost::shared_ptr<WebServiceModuleContext> ws_module_context_ptr;
00079 
00080 struct WebServiceModule {
00081   virtual ~WebServiceModule() { }
00082 
00083   virtual string ws_type() const = 0;
00084 
00085   virtual call_handler_map::iterator call_begin() = 0;
00086 
00087   virtual call_handler_map::iterator call_end() = 0;
00088 
00089   virtual call_handler_map::iterator call_find(const string & call) = 0;
00090 
00091   virtual message_handler_map::iterator request_begin() = 0;
00092   virtual message_handler_map::iterator request_end() = 0;
00093   virtual message_handler_map::iterator response_begin() = 0;
00094   virtual message_handler_map::iterator response_end() = 0;
00095 };
00096 
00097 #define WS_MODULE_CALL(call, function_ptr) \
00098   DefaultWebServiceModule::call_insert(call, boost::bind(function_ptr, this, _1, _2))
00099 
00100 #define WS_MODULE_CALL_WITH_PARAM(call, module_type, param_type, function_ptr) \
00101   DefaultWebServiceModule::call_insert(call, boost::bind(NS_SSRC_WSPR_WS::ws_call<module_type, param_type>, this, function_ptr, _1, _2))
00102 
00103 class DefaultWebServiceModule : public WebServiceModule {
00104   call_handler_map _call_handlers;
00105   message_handler_map _request_handlers;
00106   message_handler_map _response_handlers;
00107 
00108 protected:
00109   typedef WebServiceProtocol protocol_traits;
00110 
00111   WISP_IMPORT(protocol_traits, packing_traits);
00112   WISP_IMPORT(protocol_traits, parameter_map);
00113   WISP_IMPORT(protocol_traits, MessageResponse);
00114   WISP_IMPORT(protocol_traits, MessageDeliverEvent);
00115   WISP_IMPORT(protocol_traits, CallResponse);
00116   WISP_IMPORT(protocol_traits, CallDeliverEvent);
00117 
00118 public:
00119 
00120   typedef NS_SSRC_WISP_PROTOCOL::ContinuationCaller<packing_traits> caller_type;
00121 
00122   DefaultWebServiceModule(const ws_module_context_ptr & context) :
00123     _call_handlers(), _request_handlers(), _response_handlers(),
00124     _caller(context->caller), _context(context)
00125   { }
00126 
00127   virtual ~DefaultWebServiceModule() { }
00128 
00129   virtual string ws_type() const {
00130     return _context->ws_type;
00131   }
00132 
00133   virtual call_handler_map::iterator call_begin() {
00134     return _call_handlers.begin();
00135   }
00136 
00137   virtual call_handler_map::iterator call_end() {
00138     return _call_handlers.end();
00139   }
00140 
00141   virtual call_handler_map::iterator call_find(const string & call) {
00142     return _call_handlers.find(call);
00143   }
00144 
00145   virtual message_handler_map::iterator request_begin() {
00146     return _request_handlers.begin();
00147   }
00148 
00149   virtual message_handler_map::iterator request_end() {
00150     return _request_handlers.end();
00151   }
00152 
00153   virtual message_handler_map::iterator response_begin() {
00154     return _response_handlers.begin();
00155   }
00156 
00157   virtual message_handler_map::iterator response_end() {
00158     return _response_handlers.end();
00159   }
00160 
00161 protected:
00162 
00163   bool
00164   call_insert(const string & call, const call_handler_type & call_handler) {
00165     return
00166       _call_handlers.insert(call_handler_map::value_type(call, call_handler)).second;
00167   }
00168 
00169   // So you can reuse message types that are expensive to create on each call.
00170   template<typename MessageType, typename Impl>
00171   void request(Impl & impl, MessageType & msg, MessageInfo & msginfo)
00172     SSRC_DECL_THROW(boost::archive::archive_exception, std::ios_base::failure,
00173                     CallException)
00174   {
00175     _caller.unpack(msg, msginfo);
00176     // Cast forces msginfo to be const arg in process_request
00177     impl.process_request(msg, static_cast<const MessageInfo &>(msginfo));
00178   }
00179 
00180   template<typename MessageType, typename Impl>
00181   void request(Impl & impl, MessageInfo & msginfo)
00182     SSRC_DECL_THROW(boost::archive::archive_exception, std::ios_base::failure)
00183   {
00184     MessageType msg;
00185     request(impl, msg, msginfo);
00186   }
00187 
00188   template<typename MessageType, typename Impl>
00189   void respond(Impl & impl, MessageType & msg, MessageInfo & msginfo)
00190     SSRC_DECL_THROW(boost::archive::archive_exception, std::ios_base::failure,
00191                     CallException)
00192   {
00193     _caller.unpack(msg, msginfo);
00194     // Cast forces msginfo to be const arg in process_response
00195     impl.process_response(msg, static_cast<const MessageInfo &>(msginfo));
00196   }
00197 
00198   template<typename MessageType, typename Impl>
00199   void respond(Impl & impl, MessageInfo & msginfo)
00200     SSRC_DECL_THROW(boost::archive::archive_exception, std::ios_base::failure)
00201   {
00202     MessageType msg;
00203     respond(impl, msg, msginfo);
00204   }
00205 
00206   bool set_request_handler(const message_handler_entry & handler) {
00207     return _request_handlers.insert(handler).second;
00208   }
00209 
00210   template<typename MessageType, typename Impl>
00211   bool set_request_handler(Impl & impl) {
00212     return set_request_handler(message_handler_entry(MessageType::protocol,
00213                                                      MessageType::id,
00214                                                      boost::bind(&DefaultWebServiceModule::template request<MessageType, Impl>, this, std::ref(impl), _1)));
00215   }
00216 
00217   template<typename MessageType, typename Impl>
00218   bool set_request_handler(Impl & impl, MessageType & buffer)  {
00219     return set_request_handler(message_handler_entry(MessageType::protocol,
00220                                                      MessageType::id,
00221                                                      boost::bind(&DefaultWebServiceModule::template request<MessageType, Impl>, this, std::ref(impl), std::ref(buffer), _1)));
00222   }
00223 
00224   bool set_response_handler(const message_handler_entry & handler) {
00225     return _response_handlers.insert(handler).second;
00226   }
00227 
00228   template<typename MessageType, typename Impl>
00229   bool set_response_handler(Impl & impl) {
00230     return set_response_handler(message_handler_entry(MessageType::protocol,
00231                                                       MessageType::id,
00232                                                       boost::bind(&DefaultWebServiceModule::template respond<MessageType, Impl>, this, std::ref(impl), _1)));  }
00233 
00234   template<typename MessageType, typename Impl>
00235   bool set_response_handler(Impl & impl, MessageType & buffer) {
00236     return set_response_handler(message_handler_entry(MessageType::protocol,
00237                                                       MessageType::id,
00238                                                       boost::bind(&DefaultWebServiceModule::template respond<MessageType, Impl>, this, std::ref(impl), std::ref(buffer), _1)));
00239   }
00240 
00241   caller_type & _caller;
00242   ws_module_context_ptr _context;
00243 };
00244 
00245 __END_NS_SSRC_WSPR_WS
00246 
00247 #endif

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.