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
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.