diff options
Diffstat (limited to 'TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp')
-rw-r--r-- | TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp | 553 |
1 files changed, 553 insertions, 0 deletions
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp new file mode 100644 index 00000000000..07646142d8d --- /dev/null +++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp @@ -0,0 +1,553 @@ +#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<ImplementationRepository::ActivationMode> (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,"<?xml version=\"1.0\"?>\n"); + ACE_OS::fprintf(fp,"<!DOCTYPE %s/>\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</%s>\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,"</%s>\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<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex> >; +template class ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex>, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex>,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex>,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex>,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>; + +template class ACE_Hash_Map_Entry<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex> >; +template class ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex>, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex>,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex>,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex>,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>; + +template class ACE_Auto_Ptr<ACE_Configuration>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Hash_Map_Entry<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex> > +#pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex> ,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex> ,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex> ,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex> ,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex> + +#pragma instantiate ACE_Hash_Map_Entry<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex> > +#pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex> ,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex> ,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex> ,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ACE_CString, ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex> ,ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex> + +#pragma instantiate ACE_Auto_Ptr<ACE_Configuration> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ |