Locator_Repository.cpp

Go to the documentation of this file.
00001 #include "Locator_Repository.h"
00002 #include "Locator_XMLHandler.h"
00003 #include "utils.h"
00004 #include "ace/OS_NS_stdio.h"
00005 #include "ace/OS_NS_ctype.h"
00006 #include "ace/OS_NS_unistd.h"
00007 
00008 #include "ACEXML/parser/parser/Parser.h"
00009 #include "ACEXML/common/FileCharStream.h"
00010 #include "ACEXML/common/XML_Util.h"
00011 
00012 ACE_RCSID (ImplRepo_Service, Locator_Repository, "Locator_Repository.cpp,v 1.11 2006/01/04 16:10:11 giovannd Exp")
00013 
00014 static const char* STARTUP_COMMAND = "StartupCommand";
00015 static const char* WORKING_DIR = "WorkingDir";
00016 static const char* ENVIRONMENT = "Environment";
00017 static const char* ACTIVATION = "Activation";
00018 static const char* PARTIAL_IOR = "Location";
00019 static const char* IOR = "IOR";
00020 static const char* START_LIMIT = "StartLimit";
00021 static const char* ACTIVATOR = "Activator";
00022 static const char* SERVERS_ROOT_KEY = "Servers";
00023 static const char* ACTIVATORS_ROOT_KEY = "Activators";
00024 static const char* TOKEN = "Token";
00025 
00026 #if defined (ACE_WIN32)
00027 static const char* WIN32_REG_KEY = "Software\\TAO\\ImplementationRepository";
00028 #endif
00029 
00030 static ACE_CString lcase (const ACE_CString& s)
00031 {
00032   ACE_CString ret(s);
00033   for (size_t i = 0; i < ret.length (); ++i)
00034     {
00035       ret[i] = static_cast<char>(ACE_OS::ace_tolower (s[i]));
00036     }
00037   return ret;
00038 }
00039 
00040 static void loadActivatorsAsBinary (ACE_Configuration& config, Locator_Repository::AIMap& map)
00041 {
00042   ACE_Configuration_Section_Key root;
00043   int err = config.open_section (config.root_section (), ACTIVATORS_ROOT_KEY, 0, root);
00044   if (err == 0)
00045     {
00046       int index = 0;
00047       ACE_CString name;
00048       while (config.enumerate_sections (root, index, name) == 0)
00049         {
00050           ACE_CString ior;
00051           u_int token;
00052 
00053           ACE_Configuration_Section_Key key;
00054 
00055           // Can't fail, because we're enumerating
00056           config.open_section (root, name.c_str(), 0, key);
00057 
00058           config.get_string_value (key, IOR, ior);
00059           config.get_integer_value (key, TOKEN, token);
00060 
00061           Activator_Info_Ptr info (new Activator_Info (name, token, ior));
00062           map.bind (lcase (name), info);
00063           index++;
00064         }
00065     }
00066 }
00067 
00068 static void loadServersAsBinary(ACE_Configuration& config, Locator_Repository::SIMap& map)
00069 {
00070   ACE_Configuration_Section_Key root;
00071   int err = config.open_section (config.root_section (), SERVERS_ROOT_KEY, 0, root);
00072   if (err == 0)
00073     {
00074       int index = 0;
00075       ACE_CString name;
00076       while (config.enumerate_sections (root, index, name) == 0)
00077         {
00078           ACE_CString cmdline, dir, envstr, partial_ior, ior, aname;
00079           u_int amodeint = ImplementationRepository::MANUAL;
00080           u_int start_limit;
00081 
00082           ACE_Configuration_Section_Key key;
00083 
00084           // Can't fail, because we're enumerating
00085           config.open_section (root, name.c_str (), 0, key);
00086 
00087           // Ignore any missing values. Server name is enough on its own.
00088           config.get_string_value (key, ACTIVATOR, aname);
00089           config.get_string_value (key, STARTUP_COMMAND, cmdline);
00090           config.get_string_value (key, WORKING_DIR, dir);
00091           config.get_string_value (key, ENVIRONMENT, envstr);
00092           config.get_integer_value(key, ACTIVATION, amodeint);
00093           config.get_string_value (key, PARTIAL_IOR, partial_ior);
00094           config.get_string_value (key, IOR, ior);
00095           config.get_integer_value(key, START_LIMIT, start_limit);
00096 
00097           ImplementationRepository::ActivationMode amode =
00098             static_cast <ImplementationRepository::ActivationMode> (amodeint);
00099 
00100           ImplementationRepository::EnvironmentList env_vars =
00101             ImR_Utils::parseEnvList (envstr);
00102 
00103           Server_Info_Ptr info (new Server_Info(name, aname, cmdline,
00104             env_vars, dir, amode, start_limit, partial_ior, ior));
00105           map.bind (name, info);
00106           index++;
00107         }
00108     }
00109 }
00110 
00111 static void loadAsBinary (ACE_Configuration& config, Locator_Repository& repo)
00112 {
00113   loadServersAsBinary (config, repo.servers ());
00114   loadActivatorsAsBinary (config, repo.activators ());
00115 }
00116 
00117 // Note : There is no saveAsBinary(), because the ACE_Configuration class
00118 // supports saving of individual entries.
00119 
00120 static void convertEnvList (const Locator_XMLHandler::EnvList& in, ImplementationRepository::EnvironmentList& out)
00121 {
00122   CORBA::ULong sz = in.size ();
00123   out.length (sz);
00124   for (CORBA::ULong i = 0; i < sz; ++i)
00125     {
00126       out[i].name = in[i].name.c_str ();
00127       out[i].value = in[i].value.c_str ();
00128     }
00129 }
00130 
00131 class Server_Repo_XML_Callback : public Locator_XMLHandler::Callback
00132 {
00133 public:
00134   Server_Repo_XML_Callback(Locator_Repository& repo)
00135     : repo_ (repo)
00136   {
00137   }
00138   virtual void next_server (const ACE_CString& name,
00139     const ACE_CString& aname, const ACE_CString& cmdline,
00140     const Locator_XMLHandler::EnvList& envlst, const ACE_CString& dir,
00141     const ACE_CString& amodestr, int start_limit,
00142     const ACE_CString& partial_ior, const ACE_CString& ior)
00143   {
00144     ImplementationRepository::ActivationMode amode =
00145       ImR_Utils::parseActivationMode (amodestr);
00146 
00147     ImplementationRepository::EnvironmentList env_vars;
00148     convertEnvList (envlst, env_vars);
00149 
00150     int limit = start_limit < 1 ? 1 : start_limit;
00151 
00152     Server_Info_Ptr si (new Server_Info (name, aname, cmdline,
00153       env_vars, dir, amode, limit, partial_ior, ior));
00154 
00155     this->repo_.servers ().bind (name, si);
00156   }
00157   virtual void next_activator (const ACE_CString& aname,
00158     long token,
00159     const ACE_CString& ior)
00160   {
00161     Activator_Info_Ptr si (new Activator_Info (aname, token, ior));
00162     this->repo_.activators ().bind (lcase (aname), si);
00163   }
00164 private:
00165   Locator_Repository& repo_;
00166 };
00167 
00168 static int loadAsXML (const ACE_CString& fname, Locator_Repository& repo)
00169 {
00170   ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream; // xml input source will take ownership
00171 
00172   if (fstm->open (fname.c_str()) != 0)
00173     {
00174       // This is not a real error. The xml file may not exist yet.
00175       delete fstm;
00176       return 0;
00177     }
00178 
00179   Server_Repo_XML_Callback cb (repo);
00180 
00181   Locator_XMLHandler handler (cb);
00182 
00183   ACEXML_Parser parser;
00184 
00185   // InputSource takes ownership
00186   ACEXML_InputSource input (fstm);
00187 
00188   parser.setContentHandler (&handler);
00189   parser.setDTDHandler (&handler);
00190   parser.setErrorHandler (&handler);
00191   parser.setEntityResolver (&handler);
00192 
00193   ACEXML_TRY_NEW_ENV
00194     {
00195       parser.parse (&input ACEXML_ENV_ARG_PARAMETER);
00196       ACEXML_TRY_CHECK;
00197     }
00198   ACEXML_CATCH (ACEXML_Exception, ex)
00199     {
00200       ACE_ERROR ((LM_ERROR, "Error during load of ImR persistence xml file."));
00201       ex.print ();
00202       return -1;
00203     }
00204   ACEXML_ENDTRY;
00205   return 0;
00206 }
00207 
00208 // Note : Would pass servers by const&, but ACE hash map const_iterator is broken.
00209 static void saveAsXML (const ACE_CString& fname, Locator_Repository& repo)
00210 {
00211   FILE* fp = ACE_OS::fopen (fname.c_str (), "w");
00212   if (fp == 0)
00213     {
00214       ACE_ERROR ((LM_ERROR, "Couldn't write to file %s\n", fname.c_str()));
00215       return;
00216     }
00217   ACE_OS::fprintf (fp,"<?xml version=\"1.0\"?>\n");
00218   ACE_OS::fprintf (fp,"<%s>\n", Locator_XMLHandler::ROOT_TAG);
00219 
00220   // Save servers
00221   Locator_Repository::SIMap::ENTRY* sientry = 0;
00222   Locator_Repository::SIMap::ITERATOR siit (repo.servers ());
00223   for (; siit.next (sientry); siit.advance() )
00224     {
00225       Server_Info_Ptr& info = sientry->int_id_;
00226 
00227       ACE_CString name = ACEXML_escape_string (info->name);
00228       ACE_CString activator = ACEXML_escape_string (info->activator);
00229       ACE_CString cmdline = ACEXML_escape_string (info->cmdline);
00230       ACE_CString wdir = ACEXML_escape_string (info->dir);
00231       ACE_CString partial_ior = ACEXML_escape_string (info->partial_ior);
00232       ACE_CString ior = ACEXML_escape_string (info->ior);
00233 
00234       ACE_OS::fprintf (fp,"\t<%s", Locator_XMLHandler::SERVER_INFO_TAG);
00235       ACE_OS::fprintf (fp," name=\"%s\"", name.c_str ());
00236       ACE_OS::fprintf (fp," activator=\"%s\"", activator.c_str ());
00237       ACE_OS::fprintf (fp," command_line=\"%s\"", cmdline.c_str ());
00238       ACE_OS::fprintf (fp," working_dir=\"%s\"", wdir.c_str ());
00239       ACE_CString amodestr = ImR_Utils::activationModeToString (info->activation_mode);
00240       ACE_OS::fprintf (fp," activation_mode=\"%s\"", amodestr.c_str ());
00241       ACE_OS::fprintf (fp," start_limit=\"%d\"", info->start_limit);
00242       ACE_OS::fprintf (fp," partial_ior=\"%s\"", partial_ior.c_str ());
00243       ACE_OS::fprintf (fp," ior=\"%s\"", ior.c_str ());
00244       ACE_OS::fprintf (fp,">\n");
00245 
00246       for (CORBA::ULong i = 0; i < info->env_vars.length (); ++i)
00247         {
00248           ACE_OS::fprintf (fp,"\t\t<%s", Locator_XMLHandler::ENVIRONMENT_TAG);
00249           ACE_OS::fprintf (fp," name=\"%s\"", info->env_vars[i].name.in ());
00250           ACE_CString val = ACEXML_escape_string (info->env_vars[i].value.in ());
00251           ACE_OS::fprintf (fp," value=\"%s\"", val.c_str ());
00252           ACE_OS::fprintf (fp,"/>\n");
00253         }
00254 
00255       ACE_OS::fprintf (fp,"\t</%s>\n", Locator_XMLHandler::SERVER_INFO_TAG);
00256     }
00257 
00258   // Save Activators
00259   Locator_Repository::AIMap::ENTRY* aientry = 0;
00260   Locator_Repository::AIMap::ITERATOR aiit (repo.activators ());
00261   for (; aiit.next (aientry); aiit.advance ())
00262     {
00263       ACE_CString aname = aientry->ext_id_;
00264       Activator_Info_Ptr& info = aientry->int_id_;
00265       ACE_OS::fprintf (fp,"\t<%s", Locator_XMLHandler::ACTIVATOR_INFO_TAG);
00266       ACE_OS::fprintf( fp," name=\"%s\"", aname.c_str ());
00267       ACE_OS::fprintf (fp," token=\"%d\"", info->token);
00268       ACE_OS::fprintf (fp," ior=\"%s\"", info->ior.c_str ());
00269       ACE_OS::fprintf (fp,"/>\n");
00270     }
00271 
00272   ACE_OS::fprintf (fp,"</%s>\n", Locator_XMLHandler::ROOT_TAG);
00273   ACE_OS::fclose (fp);
00274 }
00275 
00276 Locator_Repository::Locator_Repository ()
00277 : rmode_ (Options::REPO_NONE)
00278 , config_ (0)
00279 {
00280 }
00281 
00282 int
00283 Locator_Repository::init(const Options& opts)
00284 {
00285   this->rmode_ = opts.repository_mode ();
00286   this->fname_ = opts.persist_file_name ();
00287 
00288   int err = 0;
00289   switch (this->rmode_)
00290     {
00291     case Options::REPO_NONE:
00292       {
00293         break;
00294       }
00295     case Options::REPO_HEAP_FILE:
00296       {
00297         if (opts.repository_erase ())
00298         {
00299           ACE_OS::unlink ( this->fname_.c_str () );
00300         }
00301         ACE_Configuration_Heap* heap = new ACE_Configuration_Heap ();
00302         this->config_.reset (heap);
00303         err = heap->open (this->fname_.c_str ());
00304         if (err == 0)
00305         {
00306           loadAsBinary (*this->config_, *this);
00307         }
00308         break;
00309       }
00310     case Options::REPO_REGISTRY:
00311       {
00312 #if defined (ACE_WIN32)
00313         if (opts.repository_erase ())
00314           {
00315             ACE_Configuration_Win32Registry config ( HKEY_LOCAL_MACHINE );
00316             ACE_Configuration_Section_Key root;
00317             config.open_section (config.root_section(), "Software\\TAO", 0, root);
00318             config.remove_section (root, "ImplementationRepository", 1);
00319           }
00320         HKEY root = ACE_Configuration_Win32Registry::
00321           resolve_key (HKEY_LOCAL_MACHINE, WIN32_REG_KEY);
00322         this->config_.reset (new ACE_Configuration_Win32Registry( root));
00323         loadAsBinary (*this->config_, *this);
00324 #else
00325         ACE_ERROR ((LM_ERROR, "Registry persistence is only "
00326                               "supported on Windows\n"));
00327         err = -1;
00328 #endif
00329         break;
00330       }
00331     case Options::REPO_XML_FILE:
00332       {
00333         if (opts.repository_erase ())
00334           {
00335             ACE_OS::unlink ( this->fname_.c_str() );
00336           }
00337         err = loadAsXML (this->fname_, *this);
00338         break;
00339       }
00340     default:
00341       {
00342         bool invalid_rmode_specified = false;
00343         ACE_ASSERT (invalid_rmode_specified);
00344         ACE_UNUSED_ARG (invalid_rmode_specified);
00345         err = -1;
00346       }
00347     }
00348   return err;
00349 }
00350 
00351 int
00352 Locator_Repository::add_server (const ACE_CString& name,
00353                         const ACE_CString& aname,
00354                         const ACE_CString& startup_command,
00355                         const ImplementationRepository::EnvironmentList& env_vars,
00356                         const ACE_CString& working_dir,
00357                         ImplementationRepository::ActivationMode activation,
00358                         int start_limit,
00359                         const ACE_CString& partial_ior,
00360                         const ACE_CString& ior,
00361                         ImplementationRepository::ServerObject_ptr svrobj)
00362 {
00363   int limit = start_limit < 1 ? 1 : start_limit;
00364   Server_Info_Ptr info(new Server_Info (name, aname, startup_command,
00365     env_vars, working_dir, activation, limit, partial_ior, ior, svrobj));
00366 
00367   int err = servers ().bind (name, info);
00368   if (err != 0)
00369     {
00370       return err;
00371     }
00372   this->update_server (*info);
00373   return 0;
00374 }
00375 
00376 int
00377 Locator_Repository::add_activator (const ACE_CString& name,
00378                         const CORBA::Long token,
00379                         const ACE_CString& ior,
00380                         ImplementationRepository::Activator_ptr act)
00381 {
00382   Activator_Info_Ptr info (new Activator_Info (name, token, ior, act));
00383 
00384   int err = activators ().bind (lcase (name), info);
00385   if (err != 0)
00386     {
00387       return err;
00388     }
00389   this->update_activator (*info);
00390   return 0;
00391 }
00392 
00393 int
00394 Locator_Repository::update_server (const Server_Info& info)
00395 {
00396   if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
00397     {
00398       ACE_ASSERT (this->config_.get () != 0);
00399 
00400       ACE_Configuration& cfg = *this->config_;
00401 
00402       ACE_Configuration_Section_Key root;
00403       ACE_Configuration_Section_Key key;
00404       int err = cfg.open_section (cfg.root_section(), SERVERS_ROOT_KEY, 1, root);
00405       if (err != 0)
00406         {
00407           ACE_ERROR ((LM_ERROR, "Unable to open config section:%s\n", SERVERS_ROOT_KEY));
00408           return err;
00409         }
00410       err = cfg.open_section (root, info.name.c_str (), 1, key);
00411       if (err != 0)
00412         {
00413           ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str()));
00414           return err;
00415         }
00416 
00417       ACE_CString envstr = ImR_Utils::envListToString(info.env_vars);
00418 
00419       cfg.set_string_value (key, ACTIVATOR, info.activator.c_str ());
00420       cfg.set_string_value (key, STARTUP_COMMAND, info.cmdline.c_str ());
00421       cfg.set_string_value (key, WORKING_DIR, info.dir.c_str ());
00422       cfg.set_string_value (key, ENVIRONMENT, envstr);
00423       cfg.set_integer_value (key, ACTIVATION, info.activation_mode);
00424       cfg.set_integer_value (key, START_LIMIT, info.start_limit);
00425       cfg.set_string_value (key, PARTIAL_IOR, info.partial_ior.c_str ());
00426       cfg.set_string_value (key, IOR, info.ior.c_str());
00427     }
00428   else if (rmode_ == Options::REPO_XML_FILE)
00429     {
00430       saveAsXML (this->fname_, *this);
00431     }
00432   return 0;
00433 }
00434 
00435 int
00436 Locator_Repository::update_activator (const Activator_Info& info)
00437 {
00438   if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
00439     {
00440       ACE_ASSERT(this->config_.get () != 0);
00441 
00442       ACE_Configuration& cfg = *this->config_;
00443 
00444       ACE_Configuration_Section_Key root;
00445       ACE_Configuration_Section_Key key;
00446       int err = cfg.open_section (cfg.root_section(), ACTIVATORS_ROOT_KEY, 1, root);
00447       if (err != 0)
00448         {
00449           ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", ACTIVATORS_ROOT_KEY));
00450           return err;
00451         }
00452       err = cfg.open_section (root, info.name.c_str (), 1, key);
00453       if (err != 0)
00454         {
00455           ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str()));
00456           return err;
00457         }
00458 
00459       cfg.set_integer_value (key, TOKEN, info.token);
00460       cfg.set_string_value (key, IOR, info.ior.c_str ());
00461     }
00462   else if (rmode_ == Options::REPO_XML_FILE)
00463     {
00464       saveAsXML( this->fname_, *this);
00465     }
00466   return 0;
00467 }
00468 
00469 Server_Info_Ptr
00470 Locator_Repository::get_server (const ACE_CString& name)
00471 {
00472   Server_Info_Ptr server (0);
00473   servers ().find (name, server);
00474   return server;
00475 }
00476 
00477 Activator_Info_Ptr
00478 Locator_Repository::get_activator (const ACE_CString& name)
00479 {
00480   Activator_Info_Ptr activator (0);
00481   activators ().find (lcase (name), activator);
00482   return activator;
00483 }
00484 
00485 bool
00486 Locator_Repository::has_activator (const ACE_CString& name)
00487 {
00488   Activator_Info_Ptr activator (0);
00489   return activators().find (lcase (name), activator) == 0;
00490 }
00491 
00492 int
00493 Locator_Repository::remove_server (const ACE_CString& name)
00494 {
00495   int ret = this->servers().unbind (name);
00496   if (ret != 0)
00497     {
00498       return ret;
00499     }
00500 
00501   if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
00502     {
00503       ACE_ASSERT (this->config_.get() != 0);
00504       ACE_Configuration& cfg = *this->config_;
00505       ACE_Configuration_Section_Key root;
00506       int err = cfg.open_section (cfg.root_section (), SERVERS_ROOT_KEY, 0, root);
00507       if (err != 0)
00508         {
00509           return 0; // Already gone.
00510         }
00511       ret = cfg.remove_section (root, name.c_str (), 1);
00512     }
00513   else if (rmode_ == Options::REPO_XML_FILE)
00514     {
00515       saveAsXML (this->fname_, *this);
00516     }
00517   return ret;
00518 }
00519 
00520 int
00521 Locator_Repository::remove_activator (const ACE_CString& name)
00522 {
00523   int ret = activators().unbind (lcase(name));
00524   if (ret != 0)
00525     {
00526       return ret;
00527     }
00528 
00529   if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
00530     {
00531       ACE_ASSERT (this->config_.get () != 0);
00532       ACE_Configuration& cfg = *this->config_;
00533       ACE_Configuration_Section_Key root;
00534       int err = cfg.open_section (cfg.root_section (), ACTIVATORS_ROOT_KEY, 0, root);
00535       if (err != 0)
00536       {
00537         return 0; // Already gone.
00538       }
00539       ret = cfg.remove_section (root, name.c_str (), 1);
00540     }
00541   else if (rmode_ == Options::REPO_XML_FILE)
00542   {
00543     saveAsXML (this->fname_, *this);
00544   }
00545   return ret;
00546 }
00547 
00548 Locator_Repository::SIMap&
00549 Locator_Repository::servers (void)
00550 {
00551   return server_infos_;
00552 }
00553 
00554 Locator_Repository::AIMap&
00555 Locator_Repository::activators (void)
00556 {
00557   return activator_infos_;
00558 }
00559 
00560 const char*
00561 Locator_Repository::repo_mode ()
00562 {
00563   switch (rmode_)
00564   {
00565   case Options::REPO_XML_FILE:
00566   case Options::REPO_HEAP_FILE:
00567     return fname_.c_str ();
00568   case Options::REPO_REGISTRY:
00569     return "Registry";
00570   case Options::REPO_NONE:
00571     return "Disabled";
00572   }
00573   return "Disabled";
00574 }

Generated on Thu Nov 9 13:36:20 2006 for TAO_Implementation_Repository by doxygen 1.3.6