XML_Saver.cpp

Go to the documentation of this file.
00001 // $Id: XML_Saver.cpp 79154 2007-08-01 11:35:45Z elliott_c $
00002 
00003 #include "orbsvcs/Notify/XML_Saver.h"
00004 
00005 #include "ACEXML/common/XML_Util.h"
00006 
00007 #include "ace/High_Res_Timer.h"
00008 #include "ace/OS_NS_stdio.h"
00009 #include "ace/OS_NS_unistd.h"
00010 
00011 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00012 
00013 namespace TAO_Notify
00014 {
00015   extern const char TOPOLOGY_ID_NAME[];
00016 
00017   XML_Saver::XML_Saver(bool timestamp)
00018     : output_ (0)
00019     , close_out_ (false)
00020     , backup_count_ (1)
00021     , timestamp_ (timestamp)
00022   {
00023   }
00024 
00025   XML_Saver::~XML_Saver()
00026   {
00027     if (this->output_ != 0)
00028     {
00029       ACE_ERROR ((LM_ERROR,
00030         ACE_TEXT ("(%P|%t) XML_Saver warning close not called or failed\n")
00031         ));
00032     }
00033   }
00034 
00035   void
00036   XML_Saver::backup_file_name (char * file_path, size_t nfile)
00037   {
00038     ACE_OS::snprintf(file_path, MAXPATHLEN, "%s.%3.3d",
00039       this->base_name_.c_str (),
00040       nfile);
00041   }
00042 
00043   void
00044   XML_Saver::close (void)
00045   {
00046     if (this->close_out_ && this->output_ != 0)
00047     {
00048       this->end_object(0, "notification_service");
00049 
00050       ACE_OS::fclose(this->output_);
00051       this->output_ = 0;
00052 
00053       // delete the oldest backup file (if it exists)
00054       size_t nfile = this->backup_count_ - 1;
00055       char old_path [MAXPATHLEN + 1];
00056       backup_file_name (old_path, nfile);
00057       ACE_OS::unlink (old_path);
00058 
00059       while (nfile != 0)
00060       {
00061         char new_path [MAXPATHLEN + 1];
00062         nfile -= 1;
00063         backup_file_name (new_path, nfile);
00064         // this may fail, we don't care
00065         ACE_OS::rename (new_path, old_path);
00066         ACE_OS::strcpy (old_path, new_path);
00067       }
00068       // old_path now contains the name of the backup file
00069       ACE_CString xml_name = this->base_name_;
00070       xml_name += ".xml";
00071 
00072       ACE_OS::rename (xml_name.c_str (), old_path);
00073 
00074       ACE_CString new_name = this->base_name_;
00075       new_name += ".new";
00076       ACE_OS::rename (new_name.c_str (), xml_name.c_str ());
00077     }
00078     this->output_ = 0;
00079   }
00080 
00081   bool
00082   XML_Saver::open(const ACE_CString & base_name, size_t backup_count)
00083   {
00084     this->base_name_ = base_name;
00085     this->backup_count_ = backup_count;
00086     if (base_name ==  "cout")
00087     {
00088       this->output_ = stdout;
00089       this->close_out_ = false;
00090     }
00091     else if (base_name ==  "cerr")
00092     {
00093       this->output_ = stderr;
00094       this->close_out_ = false;
00095     }
00096     else
00097     {
00098       ACE_CString file_name = base_name;
00099       file_name += ".new";
00100 
00101       this->output_ = ACE_OS::fopen (file_name.c_str(), ACE_TEXT("wb"));
00102       if (this->output_) {
00103         this->close_out_ = true;
00104       } else {
00105         ACE_ERROR ((LM_ERROR,
00106           ACE_TEXT ("(%P|%t) XML_Saver unable to open %s\n"),
00107             base_name.c_str()));
00108       }
00109     }
00110     if (this->output_ != 0)
00111     {
00112       FILE *out = this->output_;
00113 
00114       ACE_OS::fprintf (out, "<?xml version=\"1.0\"?>\n");
00115 
00116       try
00117       {
00118         bool changed = true;
00119         NVPList attrs;
00120 
00121         ACE_Time_Value now = ACE_High_Res_Timer::gettimeofday();
00122 
00123         ACE_UINT64 nowus = now.usec();
00124         static const ACE_UINT64 USECSPERSEC = 1000 * 1000;
00125         ACE_UINT64 tmpus = now.sec();
00126         nowus += tmpus * USECSPERSEC;
00127 
00128         char nowusstr[128];
00129 #ifdef ACE_LACKS_LONGLONG_T
00130         nowus.as_string(nowusstr);
00131 #else
00132         ACE_OS::sprintf(nowusstr, ACE_UINT64_FORMAT_SPECIFIER, nowus);
00133 #endif /* ACE_LACKS_LONGLONG_T */
00134 
00135         attrs.push_back(NVP("version", "1.0"));
00136         if (this->timestamp_)
00137         {
00138           attrs.push_back(NVP("timestamp", nowusstr));
00139         }
00140         this->begin_object(0, "notification_service", attrs, changed);
00141       }
00142       catch (const CORBA::Exception& ex)
00143       {
00144         ex._tao_print_exception (
00145           ACE_TEXT (
00146             "(%P|%t) XML_Saver Unknown exception\n"));
00147         delete this->output_;
00148         this->output_ = 0;
00149       }
00150     }
00151     return this->output_ != 0;
00152   }
00153 
00154   bool XML_Saver::begin_object(CORBA::Long id,
00155     const ACE_CString& type,
00156     const NVPList& attrs,
00157     bool /* changed */)
00158   {
00159     ACE_ASSERT(this->output_ != 0);
00160 
00161     FILE *out = this->output_;
00162 
00163     ACE_OS::fprintf (out, "%s%s%s", indent_.c_str(), "<", type.c_str());
00164     if (id != 0)
00165     {
00166       // not all ostreams know what to do with a CORBA::Long
00167       long lid = id;
00168       ACE_OS::fprintf (out, " %s%s%ld%s", TOPOLOGY_ID_NAME, "=\"", lid, "\"");
00169     }
00170 
00171     const size_t BUF_SIZE = 512;
00172     ACE_CString tmp(BUF_SIZE);
00173     for (size_t idx = 0; idx < attrs.size(); idx++)
00174     {
00175       ACEXML_escape_string(attrs[idx].value, tmp);
00176       ACE_OS::fprintf (out, "%s%s%s%s%s", " ",
00177         attrs[idx].name.c_str (), "=\"", tmp.c_str(), "\"");
00178     }
00179     ACE_OS::fprintf (out, ">\n");
00180     this->indent_ += "  ";
00181     return true;
00182   }
00183 
00184   void XML_Saver::end_object (CORBA::Long /* id */,
00185                               const ACE_CString& type)
00186   {
00187     ACE_ASSERT(this->output_ != 0);
00188     FILE *out = this->output_;
00189     if (this->indent_.length() >= 2)
00190     {
00191       this->indent_ = this->indent_.substr(2);
00192     }
00193     ACE_OS::fprintf (out, "%s%s%s%s", indent_.c_str(), "</",
00194                      type.c_str(), ">\n");
00195   }
00196 } /* namespace TAO_Notify */
00197 
00198 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 15:40:02 2008 for TAO_CosNotification by doxygen 1.3.6