00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <boost/asio.hpp>
00021 #include <pion/platform/CodecFactory.hpp>
00022 #include <pion/platform/ProtocolFactory.hpp>
00023 #include <pion/platform/DatabaseManager.hpp>
00024 #include <pion/platform/ReactionEngine.hpp>
00025
00026
00027 namespace pion {
00028 namespace platform {
00029
00030
00031
00032
00033 const boost::uint32_t ReactionEngine::DEFAULT_NUM_THREADS = 4;
00034 const std::string ReactionEngine::DEFAULT_CONFIG_FILE = "reactors.xml";
00035 const std::string ReactionEngine::CONNECTION_ELEMENT_NAME = "Connection";
00036 const std::string ReactionEngine::TYPE_ELEMENT_NAME = "Type";
00037 const std::string ReactionEngine::FROM_ELEMENT_NAME = "From";
00038 const std::string ReactionEngine::TO_ELEMENT_NAME = "To";
00039 const std::string ReactionEngine::TOTAL_OPS_ELEMENT_NAME = "TotalOps";
00040 const std::string ReactionEngine::EVENTS_QUEUED_ELEMENT_NAME = "EventsQueued";
00041 const std::string ReactionEngine::CONNECTION_TYPE_REACTOR = "reactor";
00042 const std::string ReactionEngine::CONNECTION_TYPE_INPUT = "input";
00043 const std::string ReactionEngine::CONNECTION_TYPE_OUTPUT = "output";
00044 const std::string ReactionEngine::REACTORS_PERMISSION_TYPE = "Reactors";
00045 const std::string ReactionEngine::UNRESTRICTED_ELEMENT_NAME = "Unrestricted";
00046 const std::string ReactionEngine::WORKSPACE_QUALIFIER_ELEMENT_NAME = "Workspace";
00047
00048
00049
00050
00051 ReactionEngine::ReactionEngine(VocabularyManager& vocab_mgr,
00052 CodecFactory& codec_factory,
00053 ProtocolFactory& protocol_factory,
00054 DatabaseManager& database_mgr)
00055 : PluginConfig<Reactor>(vocab_mgr, DEFAULT_CONFIG_FILE, Reactor::REACTOR_ELEMENT_NAME),
00056 m_codec_factory(codec_factory),
00057 m_protocol_factory(protocol_factory),
00058 m_database_mgr(database_mgr),
00059 m_is_running(false),
00060 m_multithread_branches(false)
00061 {
00062 setLogger(PION_GET_LOGGER("pion.platform.ReactionEngine"));
00063 m_scheduler.setLogger(PION_GET_LOGGER("pion.platform.ReactionEngine"));
00064 m_scheduler.setNumThreads(DEFAULT_NUM_THREADS);
00065 m_codec_connection = m_codec_factory.registerForUpdates(boost::bind(&ReactionEngine::updateCodecs, this));
00066 m_db_connection = m_database_mgr.registerForUpdates(boost::bind(&ReactionEngine::updateDatabases, this));
00067 m_protocol_connection = m_protocol_factory.registerForUpdates(boost::bind(&ReactionEngine::updateProtocols, this));
00068 }
00069
00070 void ReactionEngine::openConfigFile(void)
00071 {
00072 boost::mutex::scoped_lock engine_lock(m_mutex);
00073
00074
00075 if (ConfigManager::configIsOpen())
00076 return;
00077
00078
00079 ConfigManager::openPluginConfig(m_plugin_element);
00080
00081
00082
00083
00084
00085 xmlNodePtr connection_node = m_config_node_ptr->children;
00086 while ( (connection_node = ConfigManager::findConfigNodeByName(CONNECTION_ELEMENT_NAME, connection_node)) != NULL)
00087 {
00088
00089 std::string connection_id;
00090 if (! ConfigManager::getNodeId(connection_node, connection_id))
00091 throw EmptyConnectionIdException(ConfigManager::getConfigFile());
00092
00093
00094 std::string connection_type;
00095 if (! ConfigManager::getConfigOption(TYPE_ELEMENT_NAME, connection_type, connection_node->children)
00096 || connection_type != CONNECTION_TYPE_REACTOR)
00097 {
00098 throw BadConnectionTypeException(connection_id);
00099 }
00100
00101
00102 std::string from_id;
00103 if (! ConfigManager::getConfigOption(FROM_ELEMENT_NAME, from_id, connection_node->children))
00104 throw EmptyFromException(connection_id);
00105
00106
00107 std::string to_id;
00108 if (! ConfigManager::getConfigOption(TO_ELEMENT_NAME, to_id, connection_node->children))
00109 throw EmptyToException(connection_id);
00110
00111
00112 addConnectionNoLock(connection_id, from_id, to_id);
00113
00114
00115 connection_node = connection_node->next;
00116 }
00117
00118 PION_LOG_INFO(m_logger, "Loaded Reactor configuration file: " << ConfigManager::getConfigFile());
00119
00120
00121 engine_lock.unlock();
00122 start();
00123 }
00124
00125 void ReactionEngine::clearReactorStats(const std::string& reactor_id)
00126 {
00127
00128 try {
00129 m_plugins.run(reactor_id, boost::bind(&Reactor::clearStats, _1));
00130 } catch (PluginManager<Reactor>::PluginNotFoundException& ) {
00131 throw ReactorNotFoundException(reactor_id);
00132 }
00133 PION_LOG_DEBUG(m_logger, "Cleared reactor statistics: " << reactor_id);
00134 }
00135
00136 void ReactionEngine::start(void)
00137 {
00138 boost::mutex::scoped_lock engine_lock(m_mutex);
00139 if (! m_is_running) {
00140 PION_LOG_INFO(m_logger, "Starting the ReactionEngine");
00141
00142
00143 m_scheduler.addActiveUser();
00144
00145 m_is_running = true;
00146 }
00147 }
00148
00149 void ReactionEngine::stop(void)
00150 {
00151 boost::mutex::scoped_lock engine_lock(m_mutex);
00152 stopNoLock();
00153 }
00154
00155 void ReactionEngine::shutdown(void)
00156 {
00157 stop();
00158 m_scheduler.shutdown();
00159 m_temp_connections.clear();
00160 m_reactor_connections.clear();
00161 m_plugins.run(boost::bind(&Reactor::clearConnections, _1));
00162 this->releasePlugins();
00163 }
00164
00165 void ReactionEngine::clearStats(void)
00166 {
00167 m_plugins.run(boost::bind(&Reactor::clearStats, _1));
00168 PION_LOG_DEBUG(m_logger, "Cleared all reactor statistics");
00169 }
00170
00171 void ReactionEngine::updateCodecs(void)
00172 {
00173 m_plugins.run(boost::bind(&Reactor::updateCodecs, _1));
00174 }
00175
00176 void ReactionEngine::updateDatabases(void)
00177 {
00178 m_plugins.run(boost::bind(&Reactor::updateDatabases, _1));
00179 }
00180
00181 void ReactionEngine::updateProtocols(void)
00182 {
00183 m_plugins.run(boost::bind(&Reactor::updateProtocols, _1));
00184 }
00185
00186 void ReactionEngine::restartReactorsThatShouldBeRunning(void)
00187 {
00188 try {
00189
00190 xmlNodePtr reactor_node = m_config_node_ptr->children;
00191 while ( (reactor_node = findConfigNodeByName(Reactor::REACTOR_ELEMENT_NAME, reactor_node)) != NULL)
00192 {
00193
00194 std::string reactor_id;
00195 if (getNodeId(reactor_node, reactor_id)) {
00196
00197 m_plugins.run(reactor_id,
00198 boost::bind(&Reactor::startOutRunning, _1, reactor_node->children, true));
00199 }
00200
00201
00202 reactor_node = reactor_node->next;
00203 }
00204 } catch (std::exception& e) {
00205
00206 PION_LOG_ERROR(m_logger, e.what());
00207 }
00208 }
00209
00210 void ReactionEngine::setReactorConfig(const std::string& reactor_id,
00211 const xmlNodePtr config_ptr)
00212 {
00213
00214 try {
00215 PluginConfig<Reactor>::setPluginConfig(reactor_id, config_ptr);
00216 } catch (PluginManager<Reactor>::PluginNotFoundException&) {
00217 throw ReactorNotFoundException(reactor_id);
00218 }
00219 }
00220
00221 void ReactionEngine::setReactorLocation(const std::string& reactor_id,
00222 const xmlNodePtr config_ptr)
00223 {
00224
00225 if (! configIsOpen())
00226 throw ConfigNotOpenException(getConfigFile());
00227
00228
00229 xmlNodePtr reactor_node = m_config_node_ptr->children;
00230 while ( (reactor_node = ConfigManager::findConfigNodeByName(Reactor::REACTOR_ELEMENT_NAME, reactor_node)) != NULL) {
00231 std::string node_id;
00232 getNodeId(reactor_node, node_id);
00233 if (node_id == reactor_id)
00234 break;
00235 reactor_node = reactor_node->next;
00236 }
00237 if (reactor_node == NULL)
00238 throw ReactorNotFoundException(reactor_id);
00239
00240
00241 std::string x_coord;
00242 if (ConfigManager::getConfigOption(Reactor::X_COORDINATE_ELEMENT_NAME, x_coord, config_ptr))
00243 if (! ConfigManager::updateConfigOption(Reactor::X_COORDINATE_ELEMENT_NAME, x_coord, reactor_node))
00244 throw UpdateConfigOptionException(reactor_id);
00245 std::string y_coord;
00246 if (ConfigManager::getConfigOption(Reactor::Y_COORDINATE_ELEMENT_NAME, y_coord, config_ptr))
00247 if (! ConfigManager::updateConfigOption(Reactor::Y_COORDINATE_ELEMENT_NAME, y_coord, reactor_node))
00248 throw UpdateConfigOptionException(reactor_id);
00249
00250
00251 const std::string prefix_1 = "Proxy_X_";
00252 const std::string prefix_2 = "Proxy_Y_";
00253 const xmlChar* xmlchar_prefix_1_ptr = reinterpret_cast<const xmlChar*>(prefix_1.c_str());
00254 const xmlChar* xmlchar_prefix_2_ptr = reinterpret_cast<const xmlChar*>(prefix_2.c_str());
00255 for (xmlNodePtr cur_node = config_ptr; cur_node != NULL; cur_node = cur_node->next) {
00256 if (cur_node->type == XML_ELEMENT_NODE) {
00257 if (xmlStrncmp(cur_node->name, xmlchar_prefix_1_ptr, prefix_1.length()) == 0
00258 || xmlStrncmp(cur_node->name, xmlchar_prefix_2_ptr, prefix_2.length()) == 0)
00259 {
00260
00261 xmlChar* new_coord_ptr = xmlNodeGetContent(cur_node);
00262 if (new_coord_ptr != NULL) {
00263 if (! ConfigManager::updateConfigOption(reinterpret_cast<const char*>(cur_node->name),
00264 reinterpret_cast<const char*>(new_coord_ptr),
00265 reactor_node))
00266 throw UpdateConfigOptionException(reactor_id);
00267 xmlFree(new_coord_ptr);
00268 }
00269 }
00270 }
00271 }
00272
00273 saveConfigFile();
00274 }
00275
00276 std::string ReactionEngine::addReactor(const xmlNodePtr config_ptr)
00277 {
00278 return PluginConfig<Reactor>::addPlugin(config_ptr);
00279 }
00280
00281 void ReactionEngine::removeReactor(const std::string& reactor_id)
00282 {
00283 boost::mutex::scoped_lock engine_lock(m_mutex);
00284
00285 Reactor *reactor_ptr = m_plugins.get(reactor_id);
00286 if (reactor_ptr == NULL)
00287 throw ReactorNotFoundException(reactor_id);
00288
00289
00290 if (reactor_ptr->isRunning()) {
00291 stopReactor(reactor_id);
00292 }
00293
00294
00295 ReactorConnectionList::iterator reactor_i = m_reactor_connections.begin();
00296 while (reactor_i != m_reactor_connections.end()) {
00297 ReactorConnectionList::iterator current_i = reactor_i++;
00298 if (current_i->m_from_id == reactor_id || current_i->m_to_id == reactor_id) {
00299
00300 removeConnectionNoLock(current_i->m_from_id, current_i->m_to_id);
00301 removeConnectionConfigNoLock(current_i->m_from_id, current_i->m_to_id);
00302 m_reactor_connections.erase(current_i);
00303 }
00304 }
00305
00306
00307 TempConnectionList::iterator connection_i = m_temp_connections.begin();
00308 while (connection_i != m_temp_connections.end()) {
00309 TempConnectionList::iterator current_i = connection_i++;
00310 if (current_i->m_reactor_id == reactor_id) {
00311 if (current_i->m_output_connection) {
00312
00313 removeConnectionNoLock(current_i->m_reactor_id, current_i->m_connection_id);
00314 }
00315
00316 current_i->m_removed_handler();
00317
00318 m_temp_connections.erase(current_i);
00319 }
00320 }
00321
00322
00323 try {
00324
00325 engine_lock.unlock();
00326 PluginConfig<Reactor>::removePlugin(reactor_id);
00327 } catch (PluginManager<Reactor>::PluginNotFoundException&) {
00328 throw ReactorNotFoundException(reactor_id);
00329 }
00330 }
00331
00332 Reactor *ReactionEngine::addTempConnectionIn(const std::string& reactor_id,
00333 const std::string& connection_id,
00334 const std::string& connection_info,
00335 boost::function0<void> removed_handler)
00336 {
00337
00338 if (! configIsOpen())
00339 throw ConfigNotOpenException(getConfigFile());
00340
00341
00342 boost::mutex::scoped_lock engine_lock(m_mutex);
00343 Reactor *reactor_ptr = m_plugins.get(reactor_id);
00344 if (reactor_ptr == NULL)
00345 throw ReactorNotFoundException(reactor_id);
00346
00347
00348 m_temp_connections.push_back(TempConnection(false, reactor_id, connection_id,
00349 connection_info, removed_handler));
00350
00351 PION_LOG_DEBUG(m_logger, "Added temporary Reactor input connection: "
00352 << reactor_id << " <- " << connection_info);
00353
00354 return reactor_ptr;
00355 }
00356
00357 void ReactionEngine::addTempConnectionOut(const std::string& reactor_id,
00358 const std::string& connection_id,
00359 const std::string& connection_info,
00360 Reactor::EventHandler connection_handler)
00361 {
00362
00363 if (! configIsOpen())
00364 throw ConfigNotOpenException(getConfigFile());
00365
00366
00367 boost::mutex::scoped_lock engine_lock(m_mutex);
00368 Reactor *reactor_ptr = m_plugins.get(reactor_id);
00369 if (reactor_ptr == NULL)
00370 throw ReactorNotFoundException(reactor_id);
00371 reactor_ptr->addConnection(connection_id, connection_handler);
00372
00373
00374 EventPtr null_event_ptr;
00375 boost::function0<void> removed_handler(boost::bind(connection_handler, null_event_ptr));
00376
00377
00378 m_temp_connections.push_back(TempConnection(true, reactor_id, connection_id,
00379 connection_info, removed_handler));
00380
00381 PION_LOG_DEBUG(m_logger, "Added temporary Reactor output connection: "
00382 << reactor_id << " -> " << connection_info);
00383 }
00384
00385 void ReactionEngine::removeTempConnection(const std::string& connection_id)
00386 {
00387
00388 if (! configIsOpen())
00389 throw ConfigNotOpenException(getConfigFile());
00390
00391
00392 bool type_is_output = true;
00393 std::string reactor_id;
00394 std::string connection_info;
00395
00396
00397 boost::mutex::scoped_lock engine_lock(m_mutex);
00398 for (TempConnectionList::iterator i = m_temp_connections.begin();
00399 i != m_temp_connections.end(); ++i)
00400 {
00401 if (i->m_connection_id == connection_id) {
00402 type_is_output = i->m_output_connection;
00403 reactor_id = i->m_reactor_id;
00404 connection_info = i->m_connection_info;
00405 m_temp_connections.erase(i);
00406 break;
00407 }
00408 }
00409
00410 if (! reactor_id.empty()) {
00411 if (type_is_output) {
00412
00413 removeConnectionNoLock(reactor_id, connection_id);
00414
00415 PION_LOG_DEBUG(m_logger, "Removed temporary Reactor output connection: "
00416 << reactor_id << " -> " << connection_info);
00417 } else {
00418 PION_LOG_DEBUG(m_logger, "Removed temporary Reactor input connection: "
00419 << reactor_id << " <- " << connection_info);
00420 }
00421 }
00422 }
00423
00424 void ReactionEngine::startReactor(const std::string& reactor_id)
00425 {
00426
00427 if (! configIsOpen())
00428 throw ConfigNotOpenException(getConfigFile());
00429
00430
00431 xmlNodePtr reactor_node = m_config_node_ptr->children;
00432 while ( (reactor_node = ConfigManager::findConfigNodeByName(Reactor::REACTOR_ELEMENT_NAME, reactor_node)) != NULL) {
00433 std::string node_id;
00434 getNodeId(reactor_node, node_id);
00435 if (node_id == reactor_id)
00436 break;
00437 reactor_node = reactor_node->next;
00438 }
00439 if (reactor_node == NULL)
00440 throw ReactorNotFoundException(reactor_id);
00441
00442
00443 m_plugins.run(reactor_id, boost::bind(&Reactor::start, _1));
00444
00445
00446 if (! ConfigManager::updateConfigOption(Reactor::RUNNING_ELEMENT_NAME, "true", reactor_node))
00447 throw UpdateConfigOptionException(reactor_id);
00448 saveConfigFile();
00449 }
00450
00451 void ReactionEngine::stopReactor(const std::string& reactor_id)
00452 {
00453
00454 if (! configIsOpen())
00455 throw ConfigNotOpenException(getConfigFile());
00456
00457
00458 xmlNodePtr reactor_node = m_config_node_ptr->children;
00459 while ( (reactor_node = ConfigManager::findConfigNodeByName(Reactor::REACTOR_ELEMENT_NAME, reactor_node)) != NULL) {
00460 std::string node_id;
00461 getNodeId(reactor_node, node_id);
00462 if (node_id == reactor_id)
00463 break;
00464 reactor_node = reactor_node->next;
00465 }
00466 if (reactor_node == NULL)
00467 throw ReactorNotFoundException(reactor_id);
00468
00469
00470 m_plugins.run(reactor_id, boost::bind(&Reactor::stop, _1));
00471
00472
00473 if (! ConfigManager::updateConfigOption(Reactor::RUNNING_ELEMENT_NAME, "false", reactor_node))
00474 throw UpdateConfigOptionException(reactor_id);
00475 saveConfigFile();
00476 }
00477
00478 std::string ReactionEngine::addReactorConnection(const std::string& from_id,
00479 const std::string& to_id)
00480 {
00481
00482 if (! configIsOpen())
00483 throw ConfigNotOpenException(getConfigFile());
00484
00485
00486 const std::string connection_id(ConfigManager::createUUID());
00487
00488
00489 boost::mutex::scoped_lock engine_lock(m_mutex);
00490 addConnectionNoLock(connection_id, from_id, to_id);
00491
00492
00493
00494
00495 xmlNodePtr connection_node = xmlNewNode(NULL, reinterpret_cast<const xmlChar*>(CONNECTION_ELEMENT_NAME.c_str()));
00496 if (connection_node == NULL)
00497 throw AddConnectionConfigException(getConnectionAsText(from_id, to_id));
00498 if ((connection_node=xmlAddChild(m_config_node_ptr, connection_node)) == NULL) {
00499 xmlFreeNode(connection_node);
00500 throw AddConnectionConfigException(getConnectionAsText(from_id, to_id));
00501 }
00502
00503
00504 if (xmlNewProp(connection_node,
00505 reinterpret_cast<const xmlChar*>(ID_ATTRIBUTE_NAME.c_str()),
00506 reinterpret_cast<const xmlChar*>(connection_id.c_str())) == NULL)
00507 throw AddConnectionConfigException(getConnectionAsText(from_id, to_id));
00508
00509
00510 if (xmlNewTextChild(connection_node, NULL,
00511 reinterpret_cast<const xmlChar*>(TYPE_ELEMENT_NAME.c_str()),
00512 reinterpret_cast<const xmlChar*>(CONNECTION_TYPE_REACTOR.c_str())) == NULL)
00513 throw AddConnectionConfigException(getConnectionAsText(from_id, to_id));
00514
00515
00516 if (xmlNewTextChild(connection_node, NULL,
00517 reinterpret_cast<const xmlChar*>(FROM_ELEMENT_NAME.c_str()),
00518 reinterpret_cast<const xmlChar*>(from_id.c_str())) == NULL)
00519 throw AddConnectionConfigException(getConnectionAsText(from_id, to_id));
00520
00521
00522 if (xmlNewTextChild(connection_node, NULL,
00523 reinterpret_cast<const xmlChar*>(TO_ELEMENT_NAME.c_str()),
00524 reinterpret_cast<const xmlChar*>(to_id.c_str())) == NULL)
00525 throw AddConnectionConfigException(getConnectionAsText(from_id, to_id));
00526
00527
00528 saveConfigFile();
00529
00530 PION_LOG_DEBUG(m_logger, "Added reactor connection: " << from_id << " -> " << to_id);
00531
00532 return connection_id;
00533 }
00534
00535 std::string ReactionEngine::addReactorConnection(const xmlNodePtr config_ptr)
00536 {
00537
00538 std::string from_id;
00539 if (! ConfigManager::getConfigOption(FROM_ELEMENT_NAME, from_id, config_ptr))
00540 throw BadConnectionConfigException();
00541
00542
00543 std::string to_id;
00544 if (! ConfigManager::getConfigOption(TO_ELEMENT_NAME, to_id, config_ptr))
00545 throw BadConnectionConfigException();
00546
00547
00548 return addReactorConnection(from_id, to_id);
00549 }
00550
00551 void ReactionEngine::removeReactorConnection(const std::string& from_id,
00552 const std::string& to_id)
00553 {
00554
00555 if (! configIsOpen())
00556 throw ConfigNotOpenException(getConfigFile());
00557
00558
00559 boost::mutex::scoped_lock engine_lock(m_mutex);
00560 removeConnectionNoLock(from_id, to_id);
00561 for (ReactorConnectionList::iterator i = m_reactor_connections.begin();
00562 i != m_reactor_connections.end(); ++i)
00563 {
00564 if (i->m_from_id == from_id && i->m_to_id == to_id) {
00565 m_reactor_connections.erase(i);
00566 break;
00567 }
00568 }
00569
00570
00571 removeConnectionConfigNoLock(from_id, to_id);
00572
00573 PION_LOG_DEBUG(m_logger, "Removed reactor connection: " << from_id << " -> " << to_id);
00574 }
00575
00576 void ReactionEngine::removeReactorConnection(const std::string& connection_id)
00577 {
00578
00579 if (! configIsOpen())
00580 throw ConfigNotOpenException(getConfigFile());
00581
00582
00583 boost::mutex::scoped_lock engine_lock(m_mutex);
00584 ReactorConnectionList::iterator i = m_reactor_connections.begin();
00585 while (i != m_reactor_connections.end()) {
00586 if (i->m_connection_id == connection_id)
00587 break;
00588 ++i;
00589 }
00590 if (i == m_reactor_connections.end())
00591 throw ConnectionNotFoundException(connection_id);
00592
00593
00594 removeConnectionNoLock(i->m_from_id, i->m_to_id);
00595
00596
00597 removeConnectionConfigNoLock(i->m_from_id, i->m_to_id);
00598
00599 PION_LOG_DEBUG(m_logger, "Removed reactor connection: "
00600 << i->m_from_id << " -> " << i->m_to_id);
00601
00602
00603 m_reactor_connections.erase(i);
00604 }
00605
00606 void ReactionEngine::addConnectionNoLock(const std::string& connection_id,
00607 const std::string& from_id,
00608 const std::string& to_id)
00609 {
00610
00611 Reactor *from_ptr = m_plugins.get(from_id);
00612 if (from_ptr == NULL)
00613 throw ReactorNotFoundException(from_id);
00614
00615
00616 Reactor *to_ptr = m_plugins.get(to_id);
00617 if (to_ptr == NULL)
00618 throw ReactorNotFoundException(to_id);
00619
00620
00621 from_ptr->addConnection(*to_ptr);
00622
00623
00624 m_reactor_connections.push_back(ReactorConnection(connection_id, from_id, to_id));
00625 }
00626
00627 void ReactionEngine::removeConnectionNoLock(const std::string& reactor_id,
00628 const std::string& connection_id)
00629 {
00630
00631 Reactor *from_ptr = m_plugins.get(reactor_id);
00632 if (from_ptr == NULL)
00633 throw ReactorNotFoundException(reactor_id);
00634
00635
00636 from_ptr->removeConnection(connection_id);
00637 }
00638
00639 void ReactionEngine::removeConnectionConfigNoLock(const std::string& from_id,
00640 const std::string& to_id)
00641 {
00642
00643 xmlNodePtr connection_node = m_config_node_ptr->children;
00644 while ( (connection_node = ConfigManager::findConfigNodeByName(CONNECTION_ELEMENT_NAME, connection_node)) != NULL)
00645 {
00646
00647 std::string node_from_id;
00648 std::string node_to_id;
00649 ConfigManager::getConfigOption(FROM_ELEMENT_NAME, node_from_id, connection_node->children);
00650 ConfigManager::getConfigOption(TO_ELEMENT_NAME, node_to_id, connection_node->children);
00651
00652
00653 if (from_id == node_from_id && to_id == node_to_id) {
00654
00655 break;
00656 }
00657
00658
00659 connection_node = connection_node->next;
00660 }
00661
00662
00663 if (connection_node == NULL)
00664 throw RemoveConnectionConfigException(getConnectionAsText(from_id, to_id));
00665
00666
00667 xmlUnlinkNode(connection_node);
00668 xmlFreeNode(connection_node);
00669
00670
00671 saveConfigFile();
00672 }
00673
00674 std::string ReactionEngine::addWorkspace(const char* content_buf, std::size_t content_length)
00675 {
00676
00677 if (! configIsOpen())
00678 throw ConfigNotOpenException(getConfigFile());
00679
00680
00681 const std::string workspace_id(ConfigManager::createUUID());
00682
00683 boost::mutex::scoped_lock engine_lock(m_mutex);
00684
00685
00686 xmlNodePtr workspace_node = xmlNewNode(NULL, reinterpret_cast<const xmlChar*>(Reactor::WORKSPACE_ELEMENT_NAME.c_str()));
00687 if (workspace_node == NULL)
00688 throw AddWorkspaceConfigException();
00689 if ((workspace_node = xmlAddChild(m_config_node_ptr, workspace_node)) == NULL) {
00690 xmlFreeNode(workspace_node);
00691 throw AddWorkspaceConfigException();
00692 }
00693
00694
00695 if (xmlNewProp(workspace_node,
00696 reinterpret_cast<const xmlChar*>(ID_ATTRIBUTE_NAME.c_str()),
00697 reinterpret_cast<const xmlChar*>(workspace_id.c_str())) == NULL)
00698 throw AddWorkspaceConfigException();
00699
00700 setWorkspaceConfig(workspace_node, content_buf, content_length);
00701
00702
00703 saveConfigFile();
00704
00705 PION_LOG_DEBUG(m_logger, "Added Reactor Workspace: " << workspace_id);
00706
00707 return workspace_id;
00708 }
00709
00710 void ReactionEngine::removeReactorsFromWorkspace(const std::string& workspace_id)
00711 {
00712
00713 if (! configIsOpen())
00714 throw ConfigNotOpenException(getConfigFile());
00715
00716 if (! hasWorkspace(workspace_id))
00717 throw WorkspaceNotFoundException(workspace_id);
00718
00719 boost::mutex::scoped_lock engine_lock(m_mutex);
00720
00721
00722 std::vector<std::string> reactors_in_workspace;
00723
00724
00725 xmlNodePtr reactor_node = m_config_node_ptr->children;
00726 while ( (reactor_node = findConfigNodeByName(Reactor::REACTOR_ELEMENT_NAME, reactor_node)) != NULL) {
00727 std::string workspace_str;
00728 if (ConfigManager::getConfigOption(Reactor::WORKSPACE_ELEMENT_NAME, workspace_str, reactor_node->children)) {
00729 if (workspace_str == workspace_id) {
00730 std::string reactor_id;
00731 if (! getNodeId(reactor_node, reactor_id))
00732 throw EmptyPluginIdException(getConfigFile());
00733 reactors_in_workspace.push_back(reactor_id);
00734 }
00735 }
00736
00737
00738 reactor_node = reactor_node->next;
00739 }
00740
00741
00742 engine_lock.unlock();
00743 std::for_each(reactors_in_workspace.begin(), reactors_in_workspace.end(), boost::bind(&ReactionEngine::removeReactor, this, _1));
00744 }
00745
00746 void ReactionEngine::removeWorkspace(const std::string& workspace_id)
00747 {
00748
00749 if (! configIsOpen())
00750 throw ConfigNotOpenException(getConfigFile());
00751
00752
00753 boost::mutex::scoped_lock engine_lock(m_mutex);
00754 xmlNodePtr workspace_node = findConfigNodeByAttr(Reactor::WORKSPACE_ELEMENT_NAME,
00755 ID_ATTRIBUTE_NAME,
00756 workspace_id,
00757 m_config_node_ptr->children);
00758
00759 if (workspace_node == NULL)
00760 throw WorkspaceNotFoundException(workspace_id);
00761
00762
00763 bool empty = true;
00764 xmlNodePtr reactor_node = m_config_node_ptr->children;
00765 while ( (reactor_node = findConfigNodeByName(Reactor::REACTOR_ELEMENT_NAME, reactor_node)) != NULL) {
00766 std::string workspace_str;
00767 if (ConfigManager::getConfigOption(Reactor::WORKSPACE_ELEMENT_NAME, workspace_str, reactor_node->children)) {
00768 if (workspace_str == workspace_id) {
00769 empty = false;
00770 break;
00771 }
00772 }
00773
00774
00775 reactor_node = reactor_node->next;
00776 }
00777
00778 if (! empty)
00779 throw RemoveNonEmptyWorkspaceException(workspace_id);
00780
00781
00782 xmlUnlinkNode(workspace_node);
00783 xmlFreeNode(workspace_node);
00784
00785
00786 saveConfigFile();
00787
00788 PION_LOG_DEBUG(m_logger, "Removed Reactor Workspace: " << workspace_id);
00789 }
00790
00791 void ReactionEngine::setWorkspaceConfig(const std::string& workspace_id, const char* content_buf, std::size_t content_length)
00792 {
00793
00794 boost::mutex::scoped_lock engine_lock(m_mutex);
00795 xmlNodePtr workspace_node = findConfigNodeByAttr(Reactor::WORKSPACE_ELEMENT_NAME,
00796 ID_ATTRIBUTE_NAME,
00797 workspace_id,
00798 m_config_node_ptr->children);
00799
00800 if (workspace_node == NULL)
00801 throw WorkspaceNotFoundException(workspace_id);
00802
00803
00804 setWorkspaceConfig(workspace_node, content_buf, content_length);
00805
00806
00807 saveConfigFile();
00808 }
00809
00810 void ReactionEngine::setWorkspaceConfig(xmlNodePtr workspace_node, const char* content_buf, std::size_t content_length)
00811 {
00812
00813 xmlNodePtr config_ptr = ConfigManager::createResourceConfig(Reactor::WORKSPACE_ELEMENT_NAME,
00814 content_buf,
00815 content_length);
00816 if (config_ptr == NULL)
00817 throw BadWorkspaceConfigException();
00818
00819
00820 std::string name;
00821 if (ConfigManager::getConfigOption(ConfigManager::NAME_ELEMENT_NAME, name, config_ptr)) {
00822 if (! ConfigManager::updateConfigOption(ConfigManager::NAME_ELEMENT_NAME, name, workspace_node)) {
00823 xmlFreeNodeList(config_ptr);
00824 throw SetWorkspaceConfigException();
00825 }
00826 }
00827
00828
00829 std::string comment;
00830 if (ConfigManager::getConfigOption(ConfigManager::COMMENT_ELEMENT_NAME, comment, config_ptr)) {
00831 if (! ConfigManager::updateConfigOption(ConfigManager::COMMENT_ELEMENT_NAME, comment, workspace_node)) {
00832 xmlFreeNodeList(config_ptr);
00833 throw SetWorkspaceConfigException();
00834 }
00835 }
00836
00837 xmlFreeNodeList(config_ptr);
00838 }
00839
00840 void ReactionEngine::stopNoLock(void)
00841 {
00842 if (m_is_running) {
00843 PION_LOG_INFO(m_logger, "Stopping the ReactionEngine");
00844
00845
00846 for (TempConnectionList::iterator i = m_temp_connections.begin();
00847 i != m_temp_connections.end(); ++i)
00848 {
00849 if (i->m_output_connection) {
00850
00851 removeConnectionNoLock(i->m_reactor_id, i->m_connection_id);
00852 }
00853
00854 i->m_removed_handler();
00855 }
00856 m_temp_connections.clear();
00857
00858
00859 PION_LOG_INFO(m_logger, "Stopping all reactors");
00860 m_plugins.run(boost::bind(&Reactor::stop, _1));
00861
00862
00863 m_scheduler.removeActiveUser();
00864
00865 m_is_running = false;
00866 }
00867 }
00868
00869 void ReactionEngine::writeStatsXML(std::ostream& out, const std::string& only_id, const bool details)
00870 {
00871 writeBeginPionStatsXML(out);
00872
00873 const Reactor::QueryBranches branches;
00874 const Reactor::QueryParams qp;
00875 boost::mutex::scoped_lock engine_lock(m_mutex);
00876
00877 if (only_id.empty()) {
00878
00879 std::string reactor_id;
00880 Reactor *reactor_ptr;
00881 xmlNodePtr reactor_node = m_config_node_ptr->children;
00882 while ( (reactor_node = ConfigManager::findConfigNodeByName(Reactor::REACTOR_ELEMENT_NAME, reactor_node)) != NULL)
00883 {
00884
00885 if (getNodeId(reactor_node, reactor_id)
00886 && (reactor_ptr = m_plugins.get(reactor_id)) != NULL)
00887 {
00888
00889 if (details) {
00890 reactor_ptr->query(out, branches, qp);
00891 } else {
00892 reactor_ptr->writeStatsXML(out);
00893 }
00894 }
00895
00896 reactor_node = reactor_node->next;
00897 }
00898
00899
00900 out << "\t<" << TOTAL_OPS_ELEMENT_NAME << '>' << getTotalOperations()
00901 << "</" << TOTAL_OPS_ELEMENT_NAME << '>' << std::endl;
00902
00903
00904 out << "\t<" << EVENTS_QUEUED_ELEMENT_NAME << '>' << getEventsQueued()
00905 << "</" << EVENTS_QUEUED_ELEMENT_NAME << '>' << std::endl;
00906
00907 } else {
00908
00909 Reactor *reactor_ptr = m_plugins.get(only_id);
00910
00911
00912 if (details) {
00913 reactor_ptr->query(out, branches, qp);
00914 } else {
00915 reactor_ptr->writeStatsXML(out);
00916 }
00917 }
00918
00919 writeEndPionStatsXML(out);
00920 }
00921
00922 void ReactionEngine::writeConnectionsXML(std::ostream& out,
00923 const std::string& only_id) const
00924 {
00925 ConfigManager::writeBeginPionConfigXML(out);
00926
00927 bool found_one = false;
00928 boost::mutex::scoped_lock engine_lock(m_mutex);
00929
00930
00931 for (ReactorConnectionList::const_iterator reactor_i = m_reactor_connections.begin();
00932 reactor_i != m_reactor_connections.end(); ++reactor_i)
00933 {
00934 if (only_id.empty() || reactor_i->m_connection_id == only_id
00935 || reactor_i->m_from_id == only_id || reactor_i->m_to_id == only_id)
00936 {
00937 found_one = true;
00938 out << "\t<" << CONNECTION_ELEMENT_NAME << ' ' << ID_ATTRIBUTE_NAME
00939 << "=\"" << reactor_i->m_connection_id << "\">" << std::endl
00940 << "\t\t<" << TYPE_ELEMENT_NAME << '>' << CONNECTION_TYPE_REACTOR
00941 << "</" << TYPE_ELEMENT_NAME << '>' << std::endl
00942 << "\t\t<" << FROM_ELEMENT_NAME << '>' << reactor_i->m_from_id << "</"
00943 << FROM_ELEMENT_NAME << '>' << std::endl
00944 << "\t\t<" << TO_ELEMENT_NAME << '>' << reactor_i->m_to_id << "</"
00945 << TO_ELEMENT_NAME << '>' << std::endl
00946 << "\t</" << CONNECTION_ELEMENT_NAME << '>' << std::endl;
00947 }
00948 }
00949
00950
00951 for (TempConnectionList::const_iterator temp_i = m_temp_connections.begin();
00952 temp_i != m_temp_connections.end(); ++temp_i)
00953 {
00954 if (only_id.empty() || temp_i->m_connection_id == only_id
00955 || temp_i->m_reactor_id == only_id)
00956 {
00957 found_one = true;
00958 out << "\t<" << CONNECTION_ELEMENT_NAME << ' ' << ID_ATTRIBUTE_NAME
00959 << "=\"" << temp_i->m_connection_id << "\">" << std::endl
00960 << "\t\t<" << TYPE_ELEMENT_NAME << '>';
00961 if (temp_i->m_output_connection) {
00962 out << CONNECTION_TYPE_OUTPUT << "</" << TYPE_ELEMENT_NAME << '>' << std::endl
00963 << "\t\t<" << FROM_ELEMENT_NAME << '>' << temp_i->m_reactor_id
00964 << "</" << FROM_ELEMENT_NAME << '>' << std::endl
00965 << "\t\t<" << TO_ELEMENT_NAME << '>' << temp_i->m_connection_info;
00966 } else {
00967 out << CONNECTION_TYPE_INPUT << "</" << TYPE_ELEMENT_NAME << '>' << std::endl
00968 << "\t\t<" << FROM_ELEMENT_NAME << '>' << temp_i->m_connection_info
00969 << "</" << FROM_ELEMENT_NAME << '>' << std::endl
00970 << "\t\t<" << TO_ELEMENT_NAME << '>' << temp_i->m_reactor_id;
00971 }
00972 out << "</" << TO_ELEMENT_NAME << '>' << std::endl
00973 << "\t</" << CONNECTION_ELEMENT_NAME << '>' << std::endl;
00974 }
00975 }
00976
00977 if (! found_one && ! only_id.empty())
00978 throw ConnectionNotFoundException(only_id);
00979
00980 ConfigManager::writeEndPionConfigXML(out);
00981 }
00982
00983 bool ReactionEngine::writeWorkspaceXML(std::ostream& out,
00984 const std::string& workspace_id) const
00985 {
00986
00987 boost::mutex::scoped_lock engine_lock(m_mutex);
00988 xmlNodePtr workspace_node = findConfigNodeByAttr(Reactor::WORKSPACE_ELEMENT_NAME,
00989 ID_ATTRIBUTE_NAME,
00990 workspace_id,
00991 m_config_node_ptr->children);
00992 if (workspace_node == NULL)
00993 return false;
00994
00995
00996 ConfigManager::writeBeginPionConfigXML(out);
00997 ConfigManager::writeConfigXML(out, workspace_node, false);
00998 ConfigManager::writeEndPionConfigXML(out);
00999
01000 return true;
01001 }
01002
01003 void ReactionEngine::writeWorkspacesXML(std::ostream& out) const
01004 {
01005 boost::mutex::scoped_lock engine_lock(m_mutex);
01006 ConfigManager::writeBeginPionConfigXML(out);
01007
01008
01009 xmlNodePtr workspace_node = m_config_node_ptr->children;
01010 while ( (workspace_node = ConfigManager::findConfigNodeByName(Reactor::WORKSPACE_ELEMENT_NAME, workspace_node)) != NULL) {
01011 ConfigManager::writeConfigXML(out, workspace_node, false);
01012 workspace_node = workspace_node->next;
01013 }
01014
01015 ConfigManager::writeEndPionConfigXML(out);
01016 }
01017
01018 bool ReactionEngine::hasWorkspace(const std::string& workspace_id) const
01019 {
01020 xmlNodePtr workspace_node = findConfigNodeByAttr(Reactor::WORKSPACE_ELEMENT_NAME,
01021 ID_ATTRIBUTE_NAME,
01022 workspace_id,
01023 m_config_node_ptr->children);
01024 return workspace_node != NULL;
01025 }
01026
01027 bool ReactionEngine::writeWorkspaceLimitedConfigXML(std::ostream& out, const std::string& workspace_id) const {
01028
01029 boost::mutex::scoped_lock engine_lock(m_mutex);
01030 xmlNodePtr workspace_node = findConfigNodeByAttr(Reactor::WORKSPACE_ELEMENT_NAME,
01031 ID_ATTRIBUTE_NAME,
01032 workspace_id,
01033 m_config_node_ptr->children);
01034 if (workspace_node == NULL)
01035 return false;
01036
01037 ConfigManager::writeBeginPionConfigXML(out);
01038
01039
01040 xmlNodePtr reactor_node = m_config_node_ptr->children;
01041 while ( (reactor_node = findConfigNodeByName(Reactor::REACTOR_ELEMENT_NAME, reactor_node)) != NULL) {
01042 std::string workspace_str;
01043 if (ConfigManager::getConfigOption(Reactor::WORKSPACE_ELEMENT_NAME, workspace_str, reactor_node->children)) {
01044 if (workspace_str == workspace_id)
01045 ConfigManager::writeConfigXML(out, reactor_node);
01046 }
01047
01048
01049 reactor_node = reactor_node->next;
01050 }
01051
01052
01053
01054 xmlNodePtr connection_node = m_config_node_ptr->children;
01055 while ( (connection_node = findConfigNodeByName(CONNECTION_ELEMENT_NAME, connection_node)) != NULL) {
01056 std::string source_reactor_id;
01057 if (ConfigManager::getConfigOption(FROM_ELEMENT_NAME, source_reactor_id, connection_node->children)) {
01058 const Reactor* source_reactor_ptr = m_plugins.get(source_reactor_id);
01059 if (source_reactor_ptr == NULL)
01060 throw ReactorNotFoundException(source_reactor_id);
01061
01062 if (source_reactor_ptr->getWorkspace() == workspace_id) {
01063 ConfigManager::writeConfigXML(out, connection_node);
01064 } else {
01065 std::string sink_reactor_id;
01066 if (ConfigManager::getConfigOption(TO_ELEMENT_NAME, sink_reactor_id, connection_node->children)) {
01067 const Reactor* sink_reactor_ptr = m_plugins.get(sink_reactor_id);
01068 if (sink_reactor_ptr == NULL)
01069 throw ReactorNotFoundException(sink_reactor_id);
01070
01071 if (sink_reactor_ptr->getWorkspace() == workspace_id)
01072 ConfigManager::writeConfigXML(out, connection_node);
01073 }
01074 }
01075 }
01076
01077
01078 connection_node = connection_node->next;
01079 }
01080
01081 ConfigManager::writeEndPionConfigXML(out);
01082
01083 return true;
01084 }
01085
01086 bool ReactionEngine::creationAllowed(xmlNodePtr permission_config_ptr, xmlNodePtr config_ptr) const
01087 {
01088 if (permission_config_ptr == NULL)
01089 return false;
01090
01091 if (ConfigManager::findConfigNodeByContent(UNRESTRICTED_ELEMENT_NAME, "true", permission_config_ptr->children))
01092 return true;
01093
01094 if (config_ptr == NULL)
01095 return false;
01096
01097
01098
01099 if (findConfigNodeByName(PLUGIN_ELEMENT_NAME, config_ptr) != NULL) {
01100
01101
01102 std::string workspace_id;
01103 if (! ConfigManager::getConfigOption(Reactor::WORKSPACE_ELEMENT_NAME, workspace_id, config_ptr))
01104 throw Reactor::MissingWorkspaceException();
01105 if (ConfigManager::findConfigNodeByContent(WORKSPACE_QUALIFIER_ELEMENT_NAME, workspace_id, permission_config_ptr->children))
01106 return true;
01107 } else if (findConfigNodeByName(FROM_ELEMENT_NAME, config_ptr) != NULL) {
01108
01109
01110 std::string source_reactor_id;
01111 if (! ConfigManager::getConfigOption(FROM_ELEMENT_NAME, source_reactor_id, config_ptr))
01112 throw BadConnectionConfigException();
01113 std::string sink_reactor_id;
01114 if (! ConfigManager::getConfigOption(TO_ELEMENT_NAME, sink_reactor_id, config_ptr))
01115 throw BadConnectionConfigException();
01116
01117 const Reactor* source_reactor_ptr = m_plugins.get(source_reactor_id);
01118 if (source_reactor_ptr == NULL)
01119 throw ReactorNotFoundException(source_reactor_id);
01120 const Reactor* sink_reactor_ptr = m_plugins.get(sink_reactor_id);
01121 if (sink_reactor_ptr == NULL)
01122 throw ReactorNotFoundException(sink_reactor_id);
01123
01124 if (ConfigManager::findConfigNodeByContent(WORKSPACE_QUALIFIER_ELEMENT_NAME,
01125 source_reactor_ptr->getWorkspace(),
01126 permission_config_ptr->children)
01127 && ConfigManager::findConfigNodeByContent(WORKSPACE_QUALIFIER_ELEMENT_NAME,
01128 sink_reactor_ptr->getWorkspace(),
01129 permission_config_ptr->children)) {
01130 return true;
01131 }
01132
01133 } else {
01134
01135
01136 return false;
01137 }
01138
01139 return false;
01140 }
01141
01142 bool ReactionEngine::updateAllowed(xmlNodePtr permission_config_ptr, const std::string& id, xmlNodePtr config_ptr) const
01143 {
01144 if (permission_config_ptr == NULL)
01145 return false;
01146
01147 if (ConfigManager::findConfigNodeByContent(UNRESTRICTED_ELEMENT_NAME, "true", permission_config_ptr->children))
01148 return true;
01149
01150 if (hasPlugin(id)) {
01151
01152
01153 if (config_ptr == NULL)
01154 return false;
01155
01156 const Reactor* reactor_ptr = m_plugins.get(id);
01157 if (reactor_ptr == NULL)
01158 throw ReactorNotFoundException(id);
01159
01160
01161 if (ConfigManager::findConfigNodeByContent(ReactionEngine::WORKSPACE_QUALIFIER_ELEMENT_NAME, reactor_ptr->getWorkspace(), permission_config_ptr->children)) {
01162
01163 std::string workspace_id;
01164 if (! ConfigManager::getConfigOption(Reactor::WORKSPACE_ELEMENT_NAME, workspace_id, config_ptr))
01165 throw Reactor::MissingWorkspaceException();
01166 if (ConfigManager::findConfigNodeByContent(ReactionEngine::WORKSPACE_QUALIFIER_ELEMENT_NAME, workspace_id, permission_config_ptr->children))
01167 return true;
01168 }
01169 } else if (hasWorkspace(id)) {
01170
01171
01172 if (ConfigManager::findConfigNodeByContent(ReactionEngine::WORKSPACE_QUALIFIER_ELEMENT_NAME, id, permission_config_ptr->children))
01173 return true;
01174 }
01175
01176 return false;
01177 }
01178
01179 bool ReactionEngine::removalAllowed(xmlNodePtr permission_config_ptr, const std::string& id) const
01180 {
01181 if (permission_config_ptr == NULL)
01182 return false;
01183
01184 if (ConfigManager::findConfigNodeByContent(UNRESTRICTED_ELEMENT_NAME, "true", permission_config_ptr->children))
01185 return true;
01186
01187
01188 if (hasPlugin(id)) {
01189
01190
01191 std::string workspace_id = m_plugins.get(id)->getWorkspace();
01192 if (ConfigManager::findConfigNodeByContent(WORKSPACE_QUALIFIER_ELEMENT_NAME, workspace_id, permission_config_ptr->children))
01193 return true;
01194 } else if (hasWorkspace(id)) {
01195
01196
01197 if (ConfigManager::findConfigNodeByContent(WORKSPACE_QUALIFIER_ELEMENT_NAME, id, permission_config_ptr->children))
01198 return true;
01199 } else {
01200
01201
01202 ReactorConnectionList::const_iterator i = m_reactor_connections.begin();
01203 while (i != m_reactor_connections.end()) {
01204 if (i->m_connection_id == id)
01205 break;
01206 ++i;
01207 }
01208 if (i == m_reactor_connections.end())
01209 return false;
01210
01211
01212
01213 const Reactor* source_reactor_ptr = m_plugins.get(i->m_from_id);
01214 if (source_reactor_ptr == NULL)
01215 throw ReactorNotFoundException(i->m_from_id);
01216 const Reactor* sink_reactor_ptr = m_plugins.get(i->m_to_id);
01217 if (sink_reactor_ptr == NULL)
01218 throw ReactorNotFoundException(i->m_to_id);
01219
01220 if (ConfigManager::findConfigNodeByContent(WORKSPACE_QUALIFIER_ELEMENT_NAME,
01221 source_reactor_ptr->getWorkspace(),
01222 permission_config_ptr->children)
01223 && ConfigManager::findConfigNodeByContent(WORKSPACE_QUALIFIER_ELEMENT_NAME,
01224 sink_reactor_ptr->getWorkspace(),
01225 permission_config_ptr->children)) {
01226 return true;
01227 }
01228 }
01229
01230 return false;
01231 }
01232
01233 bool ReactionEngine::accessAllowed(xmlNodePtr permission_config_ptr, const std::string& reactor_id) const
01234 {
01235 if (permission_config_ptr == NULL)
01236 return false;
01237
01238 if (reactor_id.empty())
01239 return true;
01240
01241 if (ConfigManager::findConfigNodeByContent(UNRESTRICTED_ELEMENT_NAME, "true", permission_config_ptr->children))
01242 return true;
01243
01244
01245 const Reactor* reactor_ptr = m_plugins.get(reactor_id);
01246 if (reactor_ptr == NULL)
01247 throw ReactorNotFoundException(reactor_id);
01248 std::string workspace_id = reactor_ptr->getWorkspace();
01249
01250
01251 if (ConfigManager::findConfigNodeByContent(WORKSPACE_QUALIFIER_ELEMENT_NAME, workspace_id, permission_config_ptr->children))
01252 return true;
01253
01254 return false;
01255 }
01256
01257
01258 }
01259 }