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, 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
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
00066 ACE_OS::rename (new_path, old_path);
00067 ACE_OS::strcpy (old_path, new_path);
00068 }
00069
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
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
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
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 ,
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 }
00202
00203 TAO_END_VERSIONED_NAMESPACE_DECL