XML_Saver.cpp

Go to the documentation of this file.
00001 // XML_Saver.cpp,v 1.9 2006/03/14 06:14:34 jtc Exp
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, int 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 (ACE_ENV_SINGLE_ARG_DECL)
00045   {
00046     if (this->close_out_ && this->output_ != 0)
00047     {
00048       this->end_object(0, "notification_service" ACE_ENV_ARG_PARAMETER);
00049       ACE_CHECK;
00050 
00051       ACE_OS::fclose(this->output_);
00052       this->output_ = 0;
00053 
00054       // delete the oldest backup file (if it exists)
00055       size_t nfile = this->backup_count_ - 1;
00056       char old_path [MAXPATHLEN + 1];
00057       backup_file_name (old_path, nfile);
00058       ACE_OS::unlink (old_path);
00059 
00060       while (nfile != 0)
00061       {
00062         char new_path [MAXPATHLEN + 1];
00063         nfile -= 1;
00064         backup_file_name (new_path, nfile);
00065         // this may fail, we don't care
00066         ACE_OS::rename (new_path, old_path);
00067         ACE_OS::strcpy (old_path, new_path);
00068       }
00069       // old_path now contains the name of the backup file
00070       ACE_CString xml_name = this->base_name_;
00071       xml_name += ".xml";
00072 
00073       ACE_OS::rename (xml_name.c_str (), old_path);
00074 
00075       ACE_CString new_name = this->base_name_;
00076       new_name += ".new";
00077       ACE_OS::rename (new_name.c_str (), xml_name.c_str ());
00078     }
00079     this->output_ = 0;
00080   }
00081 
00082   bool
00083   XML_Saver::open(const ACE_CString & base_name, size_t backup_count)
00084   {
00085     this->base_name_ = base_name;
00086     this->backup_count_ = backup_count;
00087     if (base_name ==  "cout")
00088     {
00089       this->output_ = stdout;
00090       this->close_out_ = false;
00091     }
00092     else if (base_name ==  "cerr")
00093     {
00094       this->output_ = stderr;
00095       this->close_out_ = false;
00096     }
00097     else
00098     {
00099       ACE_CString file_name = base_name;
00100       file_name += ".new";
00101 
00102       this->output_ = ACE_OS::fopen (file_name.c_str(), ACE_TEXT("wb"));
00103       if (this->output_) {
00104         this->close_out_ = true;
00105       } else {
00106         ACE_ERROR ((LM_ERROR,
00107           ACE_TEXT ("(%P|%t) XML_Saver unable to open %s\n"),
00108             base_name.c_str()));
00109       }
00110     }
00111     if (this->output_ != 0)
00112     {
00113       FILE *out = this->output_;
00114 
00115       ACE_OS::fprintf (out, "<?xml version=\"1.0\"?>\n");
00116 
00117       ACE_DECLARE_NEW_CORBA_ENV;
00118       ACE_TRY
00119       {
00120         bool changed = true;
00121         NVPList attrs;
00122 
00123         ACE_Time_Value now = ACE_High_Res_Timer::gettimeofday();
00124 
00125         ACE_UINT64 nowus = now.usec();
00126         static const ACE_UINT64 USECSPERSEC = 1000 * 1000;
00127         ACE_UINT64 tmpus = now.sec();
00128         nowus += tmpus * USECSPERSEC;
00129 
00130         char nowusstr[128];
00131 #ifdef ACE_LACKS_LONGLONG_T
00132         nowus.as_string(nowusstr);
00133 #else
00134         ACE_OS::sprintf(nowusstr, ACE_UINT64_FORMAT_SPECIFIER, nowus);
00135 #endif /* ACE_LACKS_LONGLONG_T */
00136 
00137         attrs.push_back(NVP("version", "1.0"));
00138         if (this->timestamp_)
00139         {
00140           attrs.push_back(NVP("timestamp", nowusstr));
00141         }
00142         this->begin_object(0, "notification_service", attrs, changed ACE_ENV_ARG_PARAMETER);
00143         ACE_TRY_CHECK;
00144       }
00145       ACE_CATCHANY
00146       {
00147         ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
00148           ACE_TEXT ("(%P|%t) XML_Saver Unknown exception\n"));
00149         delete this->output_;
00150         this->output_ = 0;
00151       }
00152       ACE_ENDTRY;
00153     }
00154     return this->output_ != 0;
00155   }
00156 
00157   bool XML_Saver::begin_object(CORBA::Long id,
00158     const ACE_CString& type,
00159     const NVPList& attrs,
00160     bool /* changed */
00161     ACE_ENV_ARG_DECL_NOT_USED)
00162   {
00163     ACE_ASSERT(this->output_ != 0);
00164 
00165     FILE *out = this->output_;
00166 
00167     ACE_OS::fprintf (out, "%s%s%s", indent_.c_str(), "<", type.c_str());
00168     if (id != 0)
00169     {
00170       // not all ostreams know what to do with a CORBA::Long
00171       long lid = id;
00172       ACE_OS::fprintf (out, " %s%s%ld%s", TOPOLOGY_ID_NAME, "=\"", lid, "\"");
00173     }
00174 
00175     const size_t BUF_SIZE = 512;
00176     ACE_CString tmp(BUF_SIZE);
00177     for (size_t idx = 0; idx < attrs.size(); idx++)
00178     {
00179       ACEXML_escape_string(attrs[idx].value, tmp);
00180       ACE_OS::fprintf (out, "%s%s%s%s%s", " ",
00181         attrs[idx].name.c_str (), "=\"", tmp.c_str(), "\"");
00182     }
00183     ACE_OS::fprintf (out, ">\n");
00184     this->indent_ += "  ";
00185     return true;
00186   }
00187 
00188   void XML_Saver::end_object (CORBA::Long /* id */,
00189                               const ACE_CString& type
00190                               ACE_ENV_ARG_DECL_NOT_USED)
00191   {
00192     ACE_ASSERT(this->output_ != 0);
00193     FILE *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 Thu Nov 9 13:24:17 2006 for TAO_CosNotification by doxygen 1.3.6