Go to the documentation of this file.00001
00018 #include <assert.h>
00019 #include <iostream>
00020 #include <coil/stringutil.h>
00021 #include <doil/corba/CORBAManager.h>
00022 #include <doil/ORBManager.h>
00023
00024 #define UNUSED_ARG(a) do {} while (&a == 0)
00025
00026 namespace doil
00027 {
00028 namespace CORBA
00029 {
00030
00031 CORBAManager* CORBAManager::manager = NULL;
00032 coil::Mutex CORBAManager::mutex;
00033
00034
00042 CORBAManager* CORBAManager::init(coil::Properties prop)
00043 throw()
00044 {
00045 if (!manager)
00046 {
00047 coil::Guard<coil::Mutex> guard(mutex);
00048 if (!manager)
00049 {
00050 manager = new CORBAManager();
00051 manager->initOrb(prop);
00052 }
00053 }
00054 return manager;
00055 };
00056
00064 CORBAManager& CORBAManager::instance()
00065 throw()
00066 {
00067 coil::Properties prop;
00068 return *CORBAManager::init(prop);
00069 }
00070
00078 const char* CORBAManager::name()
00079 throw()
00080 {
00081 return "corba";
00082 }
00083 void CORBAManager::run()
00084 throw()
00085 {
00086
00087 return;
00088 }
00089
00090
00091 void CORBAManager::shutdown()
00092 throw()
00093 {
00094 while (m_orb->work_pending())
00095 {
00096
00097 if (m_orb->work_pending())
00098 m_orb->perform_work();
00099 }
00100
00101 if (!::CORBA::is_nil(m_poa))
00102 {
00103 try
00104 {
00105 if (!::CORBA::is_nil(m_poaManager))
00106 m_poaManager->deactivate(false, true);
00107 m_poa->destroy(false, true);
00108 m_poa = PortableServer::POA::_nil();
00109 }
00110 catch (::CORBA::SystemException& ex)
00111 {
00112 }
00113 catch (...)
00114 {
00115 }
00116 }
00117
00118 if (!::CORBA::is_nil(m_orb))
00119 {
00120 try
00121 {
00122 m_orb->shutdown(true);
00123 m_orb = ::CORBA::ORB::_nil();
00124 }
00125 catch (::CORBA::SystemException& ex)
00126 {
00127 UNUSED_ARG(ex);
00128 }
00129 catch (...)
00130 {
00131 }
00132 }
00133 {
00134 coil::Guard<coil::Mutex> guard(mutex);
00135 delete manager;
00136 manager = NULL;
00137 }
00138 }
00139
00140
00148 ReturnCode_t CORBAManager::registerFactory(const char* id,
00149 doil::ServantNewFunc new_func,
00150 doil::ServantDeleteFunc delete_func)
00151 throw()
00152 {
00153 if (id == NULL) return INVALID_ARGS;
00154 if (new_func == NULL) return INVALID_ARGS;
00155 if (delete_func == NULL) return INVALID_ARGS;
00156
00157 bool ret;
00158 ServantFactory* factory = new ServantFactory(id, new_func, delete_func);
00159 ret = m_factory.registerObject(factory);
00160 if (ret) return OK;
00161 else return ALREADY_EXISTS;
00162 }
00163
00164
00165 ReturnCode_t CORBAManager::registerProxyFactory(const char* id,
00166 doil::ProxyNewFunc new_func,
00167 doil::ProxyDeleteFunc delete_func)
00168 throw()
00169 {
00170 if (id == NULL) return INVALID_ARGS;
00171 if (new_func == NULL) return INVALID_ARGS;
00172 if (delete_func == NULL) return INVALID_ARGS;
00173
00174 bool ret;
00175 ProxyFactory* factory = new ProxyFactory(id, new_func, delete_func);
00176 ret = m_factory_proxy.registerObject(factory);
00177 if (ret) return OK;
00178 else return ALREADY_EXISTS;
00179 }
00180
00188 ReturnCode_t CORBAManager::activateObject(doil::ImplBase* impl)
00189 throw()
00190 {
00191 if (impl == NULL) return INVALID_ARGS;
00192
00193 const char* id = impl->id();
00194 std::cout << "CORBAManager::activateObject: id " << id << std::endl;
00195 std::cout << "CORBAManager::activateObject: name " << impl->name() << std::endl;
00196 ServantFactory* factory = m_factory.find(id);
00197
00198 #if 0
00199 if (factory != NULL)
00200 {
00201 #else
00202
00203 if (factory == NULL) return NOT_FOUND;
00204 #endif
00205
00206 try
00207 {
00208 doil::ServantBase* svt = factory->create(impl);
00209 CORBAServantBase* csvt = dynamic_cast<CORBAServantBase*>(svt);
00210 if (csvt == NULL)
00211 {
00212 std::cout << "dynamic_cast<CORBAServantBase*> failed" << std::endl;
00213 delete svt;
00214 return INVALID_ARGS;
00215 }
00216 ReturnCode_t ret = activateObject(impl, csvt);
00217 if (ret != OK)
00218 delete svt;
00219 return ret;
00220 }
00221 catch (std::bad_alloc& e)
00222 {
00223 UNUSED_ARG(e);
00224 return INVALID_ARGS;
00225 }
00226 catch (...)
00227 {
00228 return UNKNOWN;
00229 }
00230 #if 0
00231
00232
00233
00234 }
00235 else
00236 {
00237 ProxyFactory* factory_proxy = m_factory_proxy.find(id);
00238 if (factory_proxy == NULL) return NOT_FOUND;
00239 doil::ServantBase* svt = factory->create(impl);
00240 }
00241 #endif
00242 return UNKNOWN;
00243 }
00244
00252 ReturnCode_t CORBAManager::activateObject(doil::ImplBase* impl,
00253 doil::ServantBase* servant)
00254 throw()
00255 {
00256 if (impl == NULL) return INVALID_ARGS;
00257 if (servant == NULL) return INVALID_ARGS;
00258
00259
00260 if (strcmp(impl->id(), servant->id()) != 0)
00261 return INVALID_ARGS;
00262
00263 doil::CORBA::CORBAServantBase* svt;
00264 svt = dynamic_cast<doil::CORBA::CORBAServantBase*>(servant);
00265
00266 if (svt == NULL) return INVALID_ARGS;
00267
00268
00269 ::PortableServer::ObjectId_var id = m_poa->activate_object(svt);
00270 ::CORBA::Object_ptr obj = m_poa->id_to_reference(id);
00271
00272 Entry* entry = new Entry(impl, svt, obj);
00273 if (m_map.registerObject(entry)) return OK;
00274 return UNKNOWN;
00275 }
00276
00284 ReturnCode_t CORBAManager::deactivateObject(doil::ImplBase* impl)
00285 throw()
00286 {
00287 if (impl == NULL) return INVALID_ARGS;
00288 return deactivateObject(impl->name());
00289 }
00290
00298 ReturnCode_t CORBAManager::deactivateObject(const char* name)
00299 throw()
00300 {
00301 if (name == NULL) return INVALID_ARGS;
00302
00303 Entry* entry = m_map.find(name);
00304 if (entry == NULL) return NOT_FOUND;
00305 if (::CORBA::is_nil(entry->objref_)) return NOT_FOUND;
00306
00307 PortableServer::ObjectId_var oid;
00308 oid = m_poa->reference_to_id(entry->objref_);
00309 m_poa->deactivate_object(oid);
00310
00311 ServantFactory* factory = m_factory.find(entry->servant_->id());
00312 factory->destroy(entry->servant_);
00313 m_map.unregisterObject(entry->impl_->name());
00314 delete entry;
00315 return OK;
00316 }
00317
00325 doil::ImplBase* CORBAManager::getImpl(const char* name)
00326 throw()
00327 {
00328 if (name == NULL) return NULL;
00329
00330 Entry* entry = m_map.find(name);
00331 if (entry == NULL) return NULL;
00332 return entry->impl_;
00333 }
00334
00342 doil::ImplBase* CORBAManager::toImpl(doil::ServantBase* servant)
00343 throw()
00344 {
00345 if (servant == NULL) return NULL;
00346
00347 std::cout << "toImpl(Servant)" << std::endl;
00348 CORBAServantBase* csvt = dynamic_cast<CORBAServantBase*>(servant);
00349
00350 std::cout << "name: " << csvt->name() << std::endl;
00351 return getImpl(csvt->name());
00352 }
00353
00361 doil::ServantBase* CORBAManager::getServant(const char* name)
00362 throw()
00363 {
00364 if (name == NULL) return NULL;
00365
00366 Entry* entry = m_map.find(name);
00367 if (entry == NULL) return NULL;
00368 return entry->servant_;
00369
00370 }
00371
00379 doil::ServantBase* CORBAManager::toServant(doil::ImplBase* impl)
00380 throw()
00381 {
00382 if (impl == NULL) return NULL;
00383 return getServant(impl->name());
00384 }
00385
00386
00387
00388
00396 doil::ImplBase* CORBAManager::toImpl(::CORBA::Object_ptr obj)
00397 throw()
00398 {
00399 PortableServer::ServantBase* svt = m_poa->reference_to_servant(obj);
00400 CORBAServantBase* csvt = dynamic_cast<CORBAServantBase*>(svt);
00401 if (csvt == NULL) return NULL;
00402 return toImpl(csvt);
00403 }
00404
00412 ::CORBA::Object_ptr CORBAManager::getReference(const char* name)
00413 throw()
00414 {
00415 Entry* entry = m_map.find(name);
00416 return entry->objref_;
00417 ;
00418 }
00419
00427 ::CORBA::Object_ptr CORBAManager::toReference(doil::ImplBase* impl)
00428 throw()
00429 {
00430 return getReference(impl->name());
00431 }
00432
00440 ::CORBA::Object_ptr CORBAManager::toReference(doil::ServantBase* servant)
00441 throw()
00442 {
00443 return getReference(servant->name());
00444 }
00445
00455 doil::ServantBase* CORBAManager::toServant(::CORBA::Object_ptr obj)
00456 throw()
00457 {
00458 PortableServer::ServantBase* svt = m_poa->reference_to_servant(obj);
00459 if (svt == NULL) return NULL;
00460 CORBAServantBase* csvt = dynamic_cast<CORBAServantBase*>(svt);
00461 if (csvt == NULL) return NULL;
00462 return csvt;
00463 }
00464
00465
00466
00467
00475 ::CORBA::ORB_ptr CORBAManager::getORB()
00476 throw()
00477 {
00478 return m_orb;
00479 }
00480
00488 ::PortableServer::POA_ptr CORBAManager::getPOA()
00489 throw()
00490 {
00491 return m_poa;
00492 }
00493
00501 ::PortableServer::POAManager_ptr CORBAManager::getPOAManager()
00502 throw()
00503 {
00504 return m_poaManager;
00505 }
00506
00507
00508
00509
00510
00511 void CORBAManager::initOrb(coil::Properties prop)
00512 {
00513 m_config = prop;
00514 std::vector<std::string> args(coil::split(createORBOptions(), " "));
00515
00516 args.insert(args.begin(), "manager");
00517 char** argv = coil::toArgv(args);
00518 int argc(args.size());
00519
00520 try
00521 {
00522
00523 m_orb = ::CORBA::ORB_init(argc, argv);
00524 assert(!::CORBA::is_nil(m_orb));
00525
00526 ::CORBA::Object_var obj = m_orb->resolve_initial_references("RootPOA");
00527 m_poa = PortableServer::POA::_narrow(obj);
00528 assert(!::CORBA::is_nil(m_poa));
00529 m_poaManager = m_poa->the_POAManager();
00530 m_poaManager->activate();
00531 }
00532 catch (...)
00533 {
00534 return;
00535 }
00536 }
00537
00538
00539 std::string CORBAManager::createORBOptions()
00540 {
00541 std::string opt(m_config["args"]);
00542 std::string corba(m_config["id"]);
00543 std::string endpoint(m_config["endpoint"]);
00544
00545 if (!endpoint.empty())
00546 {
00547 if (!opt.empty()) opt += " ";
00548 if (corba == "omniORB") opt = "-ORBendPoint giop:tcp:" + endpoint;
00549 else if (corba == "TAO") opt = "-ORBEndPoint iiop://" + endpoint;
00550 else if (corba == "MICO") opt = "-ORBIIOPAddr inet:" + endpoint;
00551 }
00552 return opt;
00553 }
00554 };
00555 };
00556
00557
00558 extern "C"
00559 {
00560 void DoilCORBAInit(coil::Properties& prop)
00561 {
00562 doil::ORBManager& mgr(doil::ORBManager::instance());
00563 mgr.addORB((doil::CORBA::CORBAManager::init(prop)));
00564 }
00565 }