#include "Locator_Repository.h" #include "Locator_XMLHandler.h" #include "utils.h" #include "ace/OS_NS_stdio.h" #include "ACEXML/parser/parser/Parser.h" #include "ACEXML/common/FileCharStream.h" ACE_RCSID (ImplRepo_Service, Locator_Repository, "$Id$") static const char* STARTUP_COMMAND = "StartupCommand"; static const char* WORKING_DIR = "WorkingDir"; static const char* ENVIRONMENT = "Environment"; static const char* ACTIVATION = "Activation"; static const char* PARTIAL_IOR = "Location"; static const char* IOR = "IOR"; static const char* START_LIMIT = "StartLimit"; static const char* ACTIVATOR = "Activator"; static const char* SERVERS_ROOT_KEY = "Servers"; static const char* ACTIVATORS_ROOT_KEY = "Activators"; static const char* TOKEN = "Token"; #if defined (ACE_WIN32) static const char* WIN32_REG_KEY = "Software\\TAO\\ImplementationRepository"; #endif static void loadActivatorsAsBinary(ACE_Configuration& config, Locator_Repository::AIMap& map) { ACE_Configuration_Section_Key root; int err = config.open_section(config.root_section(), ACTIVATORS_ROOT_KEY, 0, root); if (err == 0) { int index = 0; ACE_CString name; while (config.enumerate_sections (root, index, name) == 0) { ACE_CString ior; u_int token; ACE_Configuration_Section_Key key; // Can't fail, because we're enumerating config.open_section(root, name.c_str(), 0, key); config.get_string_value (key, IOR, ior); config.get_integer_value(key, TOKEN, token); Activator_Info_Ptr info(new Activator_Info(name, token, ior)); map.bind (name, info); index++; } } } static void loadServersAsBinary(ACE_Configuration& config, Locator_Repository::SIMap& map) { ACE_Configuration_Section_Key root; int err = config.open_section(config.root_section(), SERVERS_ROOT_KEY, 0, root); if (err == 0) { int index = 0; ACE_CString name; while (config.enumerate_sections (root, index, name) == 0) { ACE_CString cmdline, dir, envstr, partial_ior, ior, aname; u_int amodeint = ImplementationRepository::MANUAL; u_int start_limit; ACE_Configuration_Section_Key key; // Can't fail, because we're enumerating config.open_section(root, name.c_str(), 0, key); // Ignore any missing values. Server name is enough on its own. config.get_string_value (key, ACTIVATOR, aname); config.get_string_value (key, STARTUP_COMMAND, cmdline); config.get_string_value (key, WORKING_DIR, dir); config.get_string_value (key, ENVIRONMENT, envstr); config.get_integer_value(key, ACTIVATION, amodeint); config.get_string_value (key, PARTIAL_IOR, partial_ior); config.get_string_value (key, IOR, ior); config.get_integer_value(key, START_LIMIT, start_limit); ImplementationRepository::ActivationMode amode = static_cast (amodeint); ImplementationRepository::EnvironmentList env_vars = ImR_Utils::parseEnvList(envstr); Server_Info_Ptr info(new Server_Info(name, aname, cmdline, env_vars, dir, amode, start_limit, partial_ior, ior)); map.bind (name, info); index++; } } } static void loadAsBinary(ACE_Configuration& config, Locator_Repository& repo) { loadServersAsBinary(config, repo.servers()); loadActivatorsAsBinary(config, repo.activators()); } // Note : There is no saveAsBinary(), because the ACE_Configuration class // supports saving of individual entries. static void convertEnvList(const Locator_XMLHandler::EnvList& in, ImplementationRepository::EnvironmentList& out) { CORBA::ULong sz = in.size(); out.length(sz); for (CORBA::ULong i = 0; i < sz; ++i) { out[i].name = in[i].name.c_str(); out[i].value = in[i].value.c_str(); } } class Server_Repo_XML_Callback : public Locator_XMLHandler::Callback { Locator_Repository& repo_; public: Server_Repo_XML_Callback(Locator_Repository& repo) : repo_(repo) { } virtual void next_server(const ACE_CString& name, const ACE_CString& aname, const ACE_CString& cmdline, const Locator_XMLHandler::EnvList& envlst, const ACE_CString& dir, const ACE_CString& amodestr, int start_limit, const ACE_CString& partial_ior, const ACE_CString& ior) { ImplementationRepository::ActivationMode amode = ImR_Utils::parseActivationMode(amodestr); ImplementationRepository::EnvironmentList env_vars; convertEnvList(envlst, env_vars); int limit = start_limit < 1 ? 1 : start_limit; Server_Info_Ptr si(new Server_Info(name, aname, cmdline, env_vars, dir, amode, limit, partial_ior, ior)); this->repo_.servers().bind(name, si); } virtual void next_activator (const ACE_CString& aname, long token, const ACE_CString& ior) { Activator_Info_Ptr si(new Activator_Info(aname, token, ior)); this->repo_.activators().bind(aname, si); } }; static int loadAsXML(const ACE_CString& fname, Locator_Repository& repo) { ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream; // xml input source will take ownership if (fstm->open(fname.c_str()) != 0) { // This is not a real error. The xml file may not exist yet. delete fstm; return 0; } Server_Repo_XML_Callback cb(repo); Locator_XMLHandler handler(cb); ACEXML_Parser parser; // InputSource takes ownership ACEXML_InputSource input(fstm); parser.setContentHandler (&handler); parser.setDTDHandler (&handler); parser.setErrorHandler (&handler); parser.setEntityResolver (&handler); ACEXML_TRY_NEW_ENV { parser.parse (&input ACEXML_ENV_ARG_PARAMETER); ACEXML_TRY_CHECK; } ACEXML_CATCH (ACEXML_Exception, ex) { ACE_ERROR((LM_ERROR, "Error during load of ImR persistence xml file.")); ex.print(); return -1; } ACEXML_ENDTRY; return 0; } // Note : Would pass servers by const&, but ACE hash map const_iterator is broken. static void saveAsXML(const ACE_CString& fname, Locator_Repository& repo) { FILE* fp = ACE_OS::fopen (fname.c_str(), "w"); if (fp == 0) { ACE_ERROR((LM_ERROR, "Couldn't write to file %s\n", fname.c_str())); return; } ACE_OS::fprintf(fp,"\n"); ACE_OS::fprintf(fp,"\n", Locator_XMLHandler::ROOT_TAG); ACE_OS::fprintf(fp,"<%s>\n", Locator_XMLHandler::ROOT_TAG); // Save servers Locator_Repository::SIMap::ENTRY* sientry = 0; Locator_Repository::SIMap::ITERATOR siit(repo.servers()); for (; siit.next(sientry); siit.advance()) { Server_Info_Ptr& info = sientry->int_id_; ACE_OS::fprintf(fp,"\t<%s", Locator_XMLHandler::SERVER_INFO_TAG); ACE_OS::fprintf(fp," name=\"%s\"", info->name.c_str()); ACE_OS::fprintf(fp," activator=\"%s\"", info->activator.c_str()); ACE_OS::fprintf(fp," command_line=\"%s\"", info->cmdline.c_str()); ACE_OS::fprintf(fp," working_dir=\"%s\"", info->dir.c_str()); ACE_CString amodestr = ImR_Utils::activationModeToString(info->activation_mode); ACE_OS::fprintf(fp," activation_mode=\"%s\"", amodestr.c_str()); ACE_OS::fprintf(fp," start_limit=\"%d\"", info->start_limit); ACE_OS::fprintf(fp," partial_ior=\"%s\"", info->partial_ior.c_str()); ACE_OS::fprintf(fp," ior=\"%s\"", info->ior.c_str()); ACE_OS::fprintf(fp,">\n"); for (CORBA::ULong i = 0; i < info->env_vars.length(); ++i) { ACE_OS::fprintf(fp,"\t\t<%s", Locator_XMLHandler::ENVIRONMENT_TAG); ACE_OS::fprintf(fp," name=\"%s\"", info->env_vars[i].name.in()); ACE_OS::fprintf(fp," value=\"%s\"", info->env_vars[i].value.in()); ACE_OS::fprintf(fp,"/>\n"); } ACE_OS::fprintf(fp,"\t\n", Locator_XMLHandler::SERVER_INFO_TAG); } // Save Activators Locator_Repository::AIMap::ENTRY* aientry = 0; Locator_Repository::AIMap::ITERATOR aiit(repo.activators()); for (; aiit.next(aientry); aiit.advance()) { ACE_CString aname = aientry->ext_id_; Activator_Info_Ptr& info = aientry->int_id_; ACE_OS::fprintf(fp,"\t<%s", Locator_XMLHandler::ACTIVATOR_INFO_TAG); ACE_OS::fprintf(fp," name=\"%s\"", aname.c_str()); ACE_OS::fprintf(fp," token=\"%d\"", info->token); ACE_OS::fprintf(fp," ior=\"%s\"", info->ior.c_str ()); ACE_OS::fprintf(fp,"/>\n"); } ACE_OS::fprintf(fp,"\n", Locator_XMLHandler::ROOT_TAG); ACE_OS::fclose(fp); } Locator_Repository::Locator_Repository() : rmode_(Options::REPO_NONE) , config_(0) { } int Locator_Repository::init(Options::RepoMode rmode, const ACE_CString& name) { this->rmode_ = rmode; this->fname_ = name; int err = 0; switch (this->rmode_) { case Options::REPO_NONE: { break; } case Options::REPO_HEAP_FILE: { ACE_Configuration_Heap* heap = new ACE_Configuration_Heap(); this->config_.reset(heap); err = heap->open(this->fname_.c_str()); if (err == 0) { loadAsBinary(*this->config_, *this); } break; } #if defined (ACE_WIN32) case Options::REPO_REGISTRY: { HKEY root = ACE_Configuration_Win32Registry:: resolve_key(HKEY_LOCAL_MACHINE, WIN32_REG_KEY); this->config_.reset(new ACE_Configuration_Win32Registry(root)); loadAsBinary(*this->config_, *this); break; } #endif case Options::REPO_XML_FILE: { err = loadAsXML(this->fname_, *this); break; } default: { bool invalid_rmode_specified = false; ACE_ASSERT(invalid_rmode_specified); ACE_UNUSED_ARG(invalid_rmode_specified); err = -1; } } return err; } int Locator_Repository::add_server (const ACE_CString& name, const ACE_CString& aname, const ACE_CString& startup_command, const ImplementationRepository::EnvironmentList& env_vars, const ACE_CString& working_dir, ImplementationRepository::ActivationMode activation, int start_limit, const ACE_CString& partial_ior, const ACE_CString& ior, ImplementationRepository::ServerObject_ptr svrobj) { int limit = start_limit < 1 ? 1 : start_limit; Server_Info_Ptr info(new Server_Info(name, aname, startup_command, env_vars, working_dir, activation, limit, partial_ior, ior, svrobj)); int err = servers().bind (name, info); if (err != 0) { return err; } this->update_server(*info); return 0; } int Locator_Repository::add_activator (const ACE_CString& name, const CORBA::Long token, const ACE_CString& ior, ImplementationRepository::Activator_ptr act) { Activator_Info_Ptr info(new Activator_Info(name, token, ior, act)); int err = activators().bind (name, info); if (err != 0) { return err; } this->update_activator(*info); return 0; } int Locator_Repository::update_server (const Server_Info& info) { if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY) { ACE_ASSERT(this->config_.get() != 0); ACE_Configuration& cfg = *this->config_; ACE_Configuration_Section_Key root; ACE_Configuration_Section_Key key; int err = cfg.open_section (cfg.root_section(), SERVERS_ROOT_KEY, 1, root); if (err != 0) { ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", SERVERS_ROOT_KEY)); return err; } err = cfg.open_section (root, info.name.c_str(), 1, key); if (err != 0) { ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str())); return err; } ACE_CString envstr = ImR_Utils::envListToString(info.env_vars); cfg.set_string_value (key, ACTIVATOR, info.activator.c_str()); cfg.set_string_value (key, STARTUP_COMMAND, info.cmdline.c_str()); cfg.set_string_value (key, WORKING_DIR, info.dir.c_str()); cfg.set_string_value (key, ENVIRONMENT, envstr); cfg.set_integer_value (key, ACTIVATION, info.activation_mode); cfg.set_integer_value (key, START_LIMIT, info.start_limit); cfg.set_string_value (key, PARTIAL_IOR, info.partial_ior.c_str()); cfg.set_string_value (key, IOR, info.ior.c_str()); } else if (rmode_ == Options::REPO_XML_FILE) { saveAsXML(this->fname_, *this); } return 0; } int Locator_Repository::update_activator (const Activator_Info& info) { if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY) { ACE_ASSERT(this->config_.get() != 0); ACE_Configuration& cfg = *this->config_; ACE_Configuration_Section_Key root; ACE_Configuration_Section_Key key; int err = cfg.open_section (cfg.root_section(), ACTIVATORS_ROOT_KEY, 1, root); if (err != 0) { ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", ACTIVATORS_ROOT_KEY)); return err; } err = cfg.open_section (root, info.name.c_str(), 1, key); if (err != 0) { ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str())); return err; } cfg.set_integer_value (key, TOKEN, info.token); cfg.set_string_value (key, IOR, info.ior.c_str()); } else if (rmode_ == Options::REPO_XML_FILE) { saveAsXML(this->fname_, *this); } return 0; } Server_Info_Ptr Locator_Repository::get_server (const ACE_CString& name) { Server_Info_Ptr server(0); servers().find (name, server); return server; } Activator_Info_Ptr Locator_Repository::get_activator (const ACE_CString& name) { Activator_Info_Ptr activator(0); activators().find (name, activator); return activator; } int Locator_Repository::remove_server (const ACE_CString& name) { int ret = this->servers().unbind (name); if (ret != 0) { return ret; } if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY) { ACE_ASSERT(this->config_.get() != 0); ACE_Configuration& cfg = *this->config_; ACE_Configuration_Section_Key root; int err = cfg.open_section (cfg.root_section(), SERVERS_ROOT_KEY, 0, root); if (err != 0) { return 0; // Already gone. } ret = cfg.remove_section (root, name.c_str(), 1); } else if (rmode_ == Options::REPO_XML_FILE) { saveAsXML(this->fname_, *this); } return ret; } int Locator_Repository::remove_activator (const ACE_CString& name) { int ret = activators().unbind (name); if (ret != 0) { return ret; } if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY) { ACE_ASSERT(this->config_.get() != 0); ACE_Configuration& cfg = *this->config_; ACE_Configuration_Section_Key root; int err = cfg.open_section (cfg.root_section(), ACTIVATORS_ROOT_KEY, 0, root); if (err != 0) { return 0; // Already gone. } ret = cfg.remove_section (root, name.c_str(), 1); } else if (rmode_ == Options::REPO_XML_FILE) { saveAsXML(this->fname_, *this); } return ret; } Locator_Repository::SIMap& Locator_Repository::servers(void) { return server_infos_; } Locator_Repository::AIMap& Locator_Repository::activators(void) { return activator_infos_; } const char* Locator_Repository::repo_mode() { switch (rmode_) { case Options::REPO_XML_FILE: case Options::REPO_HEAP_FILE: return fname_.c_str(); case Options::REPO_REGISTRY: return "Registry"; case Options::REPO_NONE: return "Disabled"; } return "Disabled"; } #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Hash_Map_Entry >; template class ACE_Hash_Map_Manager_Ex, ACE_Hash, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Base_Ex,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Ex,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Reverse_Iterator_Ex,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Entry >; template class ACE_Hash_Map_Manager_Ex, ACE_Hash, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Base_Ex,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Ex,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Reverse_Iterator_Ex,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Auto_Ptr; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate ACE_Hash_Map_Entry > #pragma instantiate ACE_Hash_Map_Manager_Ex ,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex ,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Ex ,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex ,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Entry > #pragma instantiate ACE_Hash_Map_Manager_Ex ,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex ,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Ex ,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex ,ACE_Hash, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Auto_Ptr #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */