00001
00002
00003 #include "orbsvcs/Notify/XML_Loader.h"
00004 #include "orbsvcs/Notify/Topology_Object.h"
00005
00006 #include "ACEXML/common/DefaultHandler.h"
00007 #include "ACEXML/parser/parser/Parser.h"
00008 #include "ACEXML/common/FileCharStream.h"
00009
00010 #include "ace/Containers_T.h"
00011 #include "tao/debug.h"
00012 #include "ace/OS_NS_unistd.h"
00013
00014
00015 #ifndef DEBUG_LEVEL
00016 # define DEBUG_LEVEL TAO_debug_level
00017 #endif //DEBUG_LEVEL
00018
00019 using namespace TAO_Notify;
00020
00021 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00022
00023 namespace TAO_Notify {
00024 extern const char TOPOLOGY_ID_NAME[];
00025 }
00026
00027 TAO_END_VERSIONED_NAMESPACE_DECL
00028
00029 namespace {
00030 CORBA::Long makeNVPList (NVPList& nvp, ACEXML_Attributes* attrs)
00031 {
00032 CORBA::Long id = 0;
00033 for (size_t i = 0; i < attrs->getLength (); ++i)
00034 {
00035 const char * name = attrs->getQName (i);
00036 const char * value = attrs->getValue (i);
00037 if (ACE_OS::strcmp (name,
00038 TAO_VERSIONED_NAMESPACE_NAME::TAO_Notify::TOPOLOGY_ID_NAME) == 0)
00039 {
00040 id = ACE_OS::atoi (value);
00041 }
00042 nvp.push_back (NVP (name, value));
00043 }
00044 return id;
00045 }
00046 }
00047
00048 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00049
00050 namespace TAO_Notify
00051 {
00052 XML_Loader::XML_Loader ()
00053 : input_ (0)
00054 , live_ (false)
00055 {
00056 }
00057
00058 XML_Loader::~XML_Loader ()
00059 {
00060 }
00061
00062 bool
00063 XML_Loader::open (const ACE_CString & base_name)
00064 {
00065 bool result = false;
00066
00067
00068
00069
00070
00071
00072
00073 this->file_name_ = base_name;
00074 this->file_name_ += ".xml";
00075
00076
00077 result = (0 == ACE_OS::access (this->file_name_.c_str (), 4));
00078 if (result)
00079 {
00080 this->live_ = false;
00081 ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream;
00082
00083
00084 if (fstm->open (this->file_name_.c_str ()) == 0)
00085 {
00086
00087 ACEXML_InputSource input (fstm);
00088
00089 ACEXML_Parser parser;
00090 parser.setContentHandler (this);
00091 parser.setDTDHandler (this);
00092 parser.setErrorHandler (this);
00093 parser.setEntityResolver (this);
00094
00095 ACEXML_TRY_NEW_ENV
00096 {
00097 parser.parse (&input ACEXML_ENV_ARG_PARAMETER);
00098 ACEXML_TRY_CHECK;
00099 }
00100 ACEXML_CATCH (ACEXML_Exception, ex)
00101 {
00102
00103 ACE_ERROR ((LM_ERROR, "Unable to load \"%s\".\n Will try backup file.\n", this->file_name_.c_str ()));
00104 ex.print ();
00105 result = false;
00106 }
00107 ACEXML_ENDTRY;
00108 }
00109 else
00110 {
00111 ACE_DEBUG((LM_DEBUG, ACE_TEXT("Unable to open the XML input file: %s.\n Will try backup file.\n"), file_name_.c_str()));
00112 result = false;
00113 }
00114 }
00115
00116 if (! result)
00117 {
00118 this->file_name_ = base_name;
00119 this->file_name_ += ".000";
00120 result = (0 == ACE_OS::access (this->file_name_.c_str (), 4));
00121 }
00122 return result;
00123 }
00124
00125
00126 void
00127 XML_Loader::load (Topology_Object *root ACE_ENV_ARG_DECL)
00128 {
00129 ACE_ASSERT (root != 0);
00130 this->live_ = true;
00131
00132 ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream;
00133
00134
00135 if (fstm->open (this->file_name_.c_str ()) == 0)
00136 {
00137
00138 ACEXML_InputSource input (fstm);
00139
00140 ACEXML_Parser parser;
00141 parser.setContentHandler (this);
00142 parser.setDTDHandler (this);
00143 parser.setErrorHandler (this);
00144 parser.setEntityResolver (this);
00145
00146 ACEXML_TRY_NEW_ENV
00147 {
00148 object_stack_.push (root);
00149 parser.parse (&input ACEXML_ENV_ARG_PARAMETER);
00150 ACEXML_TRY_CHECK;
00151 ACE_ASSERT (object_stack_.size () == 1);
00152 Topology_Object* cur;
00153 object_stack_.pop (cur);
00154 }
00155 ACEXML_CATCH (ACEXML_Exception, ex)
00156 {
00157
00158 ACE_ERROR ((LM_ERROR, "Unable to load \"%s\".\n", this->file_name_.c_str ()));
00159 ex.print ();
00160 ACE_THROW(CORBA::INTERNAL());
00161 }
00162 ACEXML_ENDTRY;
00163 }
00164 else
00165 {
00166 ACE_DEBUG((LM_DEBUG, ACE_TEXT("Unable to open the XML input file: %s.\n"), file_name_.c_str()));
00167 ACE_THROW(CORBA::INTERNAL());
00168 }
00169 }
00170
00171 void
00172 XML_Loader::startElement (const ACEXML_Char*,
00173 const ACEXML_Char*,
00174 const ACEXML_Char* name,
00175 ACEXML_Attributes* xml_attrs ACEXML_ENV_ARG_DECL)
00176 ACE_THROW_SPEC ( (ACEXML_SAXException))
00177 {
00178 ACE_ASSERT (name != 0);
00179 ACE_ASSERT (xml_attrs != 0);
00180 if (this->live_)
00181 {
00182 ACE_ASSERT (object_stack_.size () > 0);
00183 Topology_Object* cur = 0;
00184 if (object_stack_.top (cur) == 0)
00185 {
00186 ACE_DECLARE_NEW_ENV;
00187 ACE_TRY
00188 {
00189 NVPList attrs;
00190 CORBA::Long id = makeNVPList (attrs, xml_attrs);
00191
00192 if (DEBUG_LEVEL > 5) ACE_DEBUG ((LM_INFO,
00193 ACE_TEXT("(%P|%t) XML_Loader: Element %s\n"),
00194 name
00195 ));
00196
00197 ACE_CString cname (name);
00198 Topology_Object* next = cur->load_child (
00199 cname, id, attrs ACE_ENV_ARG_PARAMETER);
00200 ACE_ASSERT(next != 0);
00201 ACE_TRY_CHECK;
00202 object_stack_.push (next);
00203 }
00204 ACE_CATCHANY
00205 {
00206 ACEXML_THROW (ACEXML_SAXException (ACE_ANY_EXCEPTION._info ().c_str ()));
00207 }
00208 ACE_ENDTRY;
00209 }
00210 }
00211 }
00212
00213 void
00214 XML_Loader::endElement (const ACEXML_Char*,
00215 const ACEXML_Char*,
00216 const ACEXML_Char* name ACEXML_ENV_ARG_DECL_NOT_USED)
00217 ACE_THROW_SPEC ( (ACEXML_SAXException))
00218 {
00219 ACE_UNUSED_ARG (name);
00220 if (this->live_)
00221 {
00222 ACE_ASSERT (object_stack_.size () > 0);
00223 if (DEBUG_LEVEL > 5) ACE_DEBUG ((LM_INFO,
00224 ACE_TEXT("(%P|%t) XML_Loader: End Element %s\n"),
00225 name
00226 ));
00227 Topology_Object* cur;
00228 object_stack_.pop (cur);
00229 }
00230 }
00231
00232 }
00233
00234 TAO_END_VERSIONED_NAMESPACE_DECL