00001
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
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
00065 ACE_OS::rename (new_path, old_path);
00066 ACE_OS::strcpy (old_path, new_path);
00067 }
00068
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
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 )
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
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 ,
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 }
00197
00198 TAO_END_VERSIONED_NAMESPACE_DECL