XML_Saver.cpp

Go to the documentation of this file.
00001 // $Id: XML_Saver.cpp 79701 2007-09-21 23:25:30Z ossama $
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 * const 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 const now = ACE_High_Res_Timer::gettimeofday();
00122 
00123         ACE_UINT64 nowus = now.usec();
00124         static const ACE_UINT64 USECSPERSEC = 1000 * 1000;
00125         ACE_UINT64 const 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         if (this->close_out_ && this->output_ != 0)
00148           {
00149             (void) ACE_OS::fclose (this->output_);
00150           }
00151 
00152         this->output_ = 0;
00153       }
00154     }
00155     return this->output_ != 0;
00156   }
00157 
00158   bool
00159   XML_Saver::begin_object(CORBA::Long id,
00160                           const ACE_CString& type,
00161                           const NVPList& attrs,
00162                           bool /* changed */)
00163   {
00164     ACE_ASSERT(this->output_ != 0);
00165 
00166     FILE * const out = this->output_;
00167 
00168     ACE_OS::fprintf (out, "%s%s%s", indent_.c_str(), "<", type.c_str());
00169     if (id != 0)
00170     {
00171       // not all ostreams know what to do with a CORBA::Long
00172       long const lid = id;
00173       ACE_OS::fprintf (out, " %s%s%ld%s", TOPOLOGY_ID_NAME, "=\"", lid, "\"");
00174     }
00175 
00176     ACE_CString::size_type const BUF_SIZE = 512;
00177     ACE_CString tmp(BUF_SIZE);
00178     for (size_t idx = 0; idx < attrs.size(); ++idx)
00179     {
00180       ACEXML_escape_string(attrs[idx].value, tmp);
00181       ACE_OS::fprintf (out, "%s%s%s%s%s", " ",
00182         attrs[idx].name.c_str (), "=\"", tmp.c_str(), "\"");
00183     }
00184     ACE_OS::fprintf (out, ">\n");
00185     this->indent_ += "  ";
00186     return true;
00187   }
00188 
00189   void XML_Saver::end_object (CORBA::Long /* id */,
00190                               const ACE_CString& type)
00191   {
00192     ACE_ASSERT(this->output_ != 0);
00193     FILE * const out = this->output_;
00194     if (this->indent_.length() >= 2)
00195     {
00196       this->indent_ = this->indent_.substr(2);
00197     }
00198     ACE_OS::fprintf (out, "%s%s%s%s", indent_.c_str(), "</",
00199                      type.c_str(), ">\n");
00200   }
00201 } /* namespace TAO_Notify */
00202 
00203 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:45:29 2010 for TAO_CosNotification by  doxygen 1.4.7