#include "TheORB.hpp" #include "DebugLog.hpp" #include "CORBAutil.hpp" #include using std::string; namespace { omni_mutex lock; // Class for turning a vector of strings // into a C style argument list // has a proper destructor to clean up // complicated because ORB_init likes to mutate // the argument list you send it class CArgList { public: CArgList(const std::vector& args); ~CArgList(); char** argv() { return _argv; } int& argc() { return _argc; } // has to be a reference private: int _argc; char** _argv; int _origargc; char** _origargv; }; } TheORB* TheORB::_instance = 0; TheORB* TheORB::instance() { return _instance; } TheORB::TheORB(const std::vector& args) { // build c style argument list CArgList arglist(args); try { _orb = CORBA::ORB_init(arglist.argc(), arglist.argv()); } catch (CORBA::Exception& x) { debugLog("TheORB","init","Caught exception while calling ORB_init()"); throw; } CORBA::Object_var obj = _orb->resolve_initial_references("RootPOA"); _rootpoa = PortableServer::POA::_narrow(obj); // check for a name service try { obj = _orb->resolve_initial_references("NameService"); // Narrow the reference returned. CORBA::String_var s = _orb->object_to_string(obj); std::string name(s); _nameservice.push_back(std::make_pair(name,CosNaming::NamingContext::_narrow(obj))); } catch (const CORBA::NO_RESOURCES& ex) {} // do nothing if not specified catch (const CORBA::Exception& ex) { debugLog("TheORB","TheORB","Caught exception while resolving initial NameService value"); throw; } } TheORB::~TheORB() {} TheORB* TheORB::init(const std::vector& args) { if(!_instance) { static TheORB inst(args); _instance = &inst; } return _instance; } CosNaming::NamingContext_var TheORB::addNameService(const std::string& nsior) { try { CORBA::Object_var obj = _orb->string_to_object(nsior.c_str()); // Narrow the reference returned. CosNaming::NamingContext_var ns = CosNaming::NamingContext::_narrow(obj); if (CORBA::is_nil(ns)) return CosNaming::NamingContext_var(); // only need to synchronise modifications to _nameservice omni_mutex_lock l(lock); _nameservice.push_back(std::make_pair(nsior,ns)); return ns; } catch (const CORBA::BAD_PARAM& ex) {} catch (const CORBA::COMM_FAILURE& ex) {} catch (const CORBA::TRANSIENT& ex) {} catch (const CORBA::Exception& ex) { debugLog("TheORB","addNameService","Exception caught while adding nameservice: " + CORBAutil::exceptionToString(ex)); } debugLog("TheORB","addNameService","Name service invalid or unavailable: " + nsior); return CosNaming::NamingContext_var(); } CosNaming::NamingContext_var TheORB::getPrimaryNS() { omni_mutex_lock l(lock); return !_nameservice.empty() ? _nameservice.front().second : CosNaming::NamingContext_var(); } const TheORB::NSvector& TheORB::getNameService() { omni_mutex_lock l(lock); return _nameservice; } void TheORB::run() { _orb->run(); } void TheORB::destroy() { debugLog("TheORB","destroy","About to destroy ORB",4); _orb->shutdown(1); _orb->destroy(); debugLog("TheORB","destroy","ORB has been destroyed",4); } bool TheORB::bind(CORBA::Object_ptr objref, string name, string kind, bool force) { // check we have a nameservice to bind in if (_nameservice.empty()) { debugLog("TheORB","bind","No valid nameservice(s) defined"); return false; } // bind the name in all the nameservices we know about CosNaming::Name objectName; objectName.length(1); objectName[0].id = CORBA::string_dup(name.c_str()); // string copied objectName[0].kind = CORBA::string_dup(kind.c_str()); // string copied bool retval = true; NSvector::iterator it; for(it = _nameservice.begin(); it != _nameservice.end(); ++it) { try { CORBA::Object_var testobjref; // Test the existing name to see if it is already bound if (!force) { try { testobjref = (it->second)->resolve(objectName); } catch (const CosNaming::NamingContext::NotFound& ex) {} } if(!CORBA::is_nil(testobjref) && CORBAutil::serverIsAlive(testobjref)) { debugLog("TheORB","bind", "Name " + name + ":" + kind + " is already bound and exists - not rebinding"); retval = false; } else { // name is not already bound, or server is dead it->second->rebind(objectName, objref); std::string n = name; if (!kind.empty()) n += ":" + kind; debugLog("TheORB","bind","Registered object reference named '" + n + "' with naming service '" + it->first + "'",2); } } catch(const CORBA::TRANSIENT& ex) { debugLog("TheORB","bind", "Caught system exception TRANSIENT -- unable to contact the naming service."); retval = false; } catch(const CORBA::COMM_FAILURE& ex) { debugLog("TheORB","bind", "Caught system exception COMM_FAILURE -- unable to contact the naming service."); retval = false; } catch(const CORBA::Exception& ex) { debugLog("TheORB","bind","Caught a CORBA::Exception while using the naming service: " + CORBAutil::exceptionToString(ex) ); retval = false; } } return retval; } bool TheORB::unbind(std::string name, std::string kind) { // Bind objref with name Echo to the rootContext: CosNaming::Name objectName; objectName.length(1); objectName[0].id = CORBA::string_dup(name.c_str()); // string copied objectName[0].kind = CORBA::string_dup(kind.c_str()); // string copied bool retval = true; NSvector::iterator it; for(it = _nameservice.begin(); it != _nameservice.end(); ++it) { try { it->second->unbind(objectName); std::string n = name; if (!kind.empty()) n += ":" + kind; debugLog("TheORB","unbind","Unregistered object reference named '" +n+ "' from naming service '" + it->first +"'",2); } catch (CosNaming::NamingContext::NotFound& ex) {} catch(const CORBA::TRANSIENT& ex) { debugLog("TheORB","unbind", "Caught system exception TRANSIENT -- unable to contact the naming service."); retval = false; } catch(const CORBA::COMM_FAILURE& ex) { debugLog("TheORB","unbind", "Caught system exception COMM_FAILURE -- unable to contact the naming service."); retval = false; } catch(const CORBA::Exception& ex) { debugLog("TheORB","unbind","Caught a CORBA::Exception while using the naming service: " + CORBAutil::exceptionToString(ex) ); retval = false; } } return retval; } CORBA::Object_ptr TheORB::find(std::string name, std::string kind) { CosNaming::Name objectName; objectName.length(1); objectName[0].id = CORBA::string_dup(name.c_str()); // string copied objectName[0].kind = CORBA::string_dup(kind.c_str()); // string copied try { return _nameservice.front().second->resolve(objectName); } catch(const CosNaming::NamingContext::NotFound& ex) { // This exception is thrown if any of the components of the // path [contexts or the object] aren't found: debugLog("TheORB","find","Name '" + name + "' not found in naming service"); } catch(const CORBA::UserException& ex) { debugLog("TheORB","find"," User exception while attempting to use naming service"); } catch(const CORBA::COMM_FAILURE& ex) { debugLog("TheORB","find", "Caught system exception COMM_FAILURE -- unable to contact the naming service."); } catch(const CORBA::TRANSIENT& ex) { debugLog("TheORB","find", "Caught system exception TRANSIENT -- unable to contact the naming service."); } catch(const CORBA::Exception& ex) { debugLog("TheORB","find","Caught a CORBA::Exception while using the naming service: " + CORBAutil::exceptionToString(ex) ); } return CORBA::Object::_nil(); } namespace { CArgList::CArgList(const std::vector& args) { _origargc = args.size(); _argc = _origargc; _origargv = new char*[_origargc]; _argv = new char*[_argc]; for(int c=0;c<_origargc;++c) { _origargv[c] = new char[args[c].size() +1]; std::strcpy(_origargv[c],args[c].c_str()); _argv[c] = _origargv[c]; } } CArgList::~CArgList() { // delete the original arguments // - _argv and _argc may have been changed for(int c=0;c<_origargc;++c) { delete [] _origargv[c]; } delete [] _origargv; delete [] _argv; } }