#include "orbsvcs/Log_Macros.h" #include "orbsvcs/Log_Macros.h" #include "orbsvcs/Notify/XML_Loader.h" #include "orbsvcs/Notify/Topology_Object.h" #include "ACEXML/common/DefaultHandler.h" #include "ACEXML/parser/parser/Parser.h" #include "ACEXML/common/FileCharStream.h" #include "ace/Containers_T.h" #include "tao/debug.h" #include "ace/OS_NS_unistd.h" //#define DEBUG_LEVEL 9 #ifndef DEBUG_LEVEL # define DEBUG_LEVEL TAO_debug_level #endif //DEBUG_LEVEL using namespace TAO_Notify; TAO_BEGIN_VERSIONED_NAMESPACE_DECL namespace TAO_Notify { extern const char TOPOLOGY_ID_NAME[]; } TAO_END_VERSIONED_NAMESPACE_DECL namespace { CORBA::Long makeNVPList (NVPList& nvp, ACEXML_Attributes* attrs) { CORBA::Long id = 0; for (size_t i = 0; i < attrs->getLength (); ++i) { ACE_CString name = ACE_TEXT_ALWAYS_CHAR(attrs->getQName (i)); ACE_CString value = ACE_TEXT_ALWAYS_CHAR(attrs->getValue (i)); if (ACE_OS::strcmp (name.c_str (), TAO_VERSIONED_NAMESPACE_NAME::TAO_Notify::TOPOLOGY_ID_NAME) == 0) { id = ACE_OS::atoi (value.c_str ()); } nvp.push_back (NVP (name.c_str (), value.c_str ())); } return id; } } TAO_BEGIN_VERSIONED_NAMESPACE_DECL namespace TAO_Notify { XML_Loader::XML_Loader () : live_ (false) { } XML_Loader::~XML_Loader () { } bool XML_Loader::open (const ACE_TString & base_name) { bool result = false; // if *.xml exists, use it // if it does not exist then // use the previous one was renamed to *.000 // If neither *.xml nor *.000 exist then something // "impossible" happened (or its a new system with no saved state). this->file_name_ = base_name; this->file_name_ += ACE_TEXT(".xml"); // 4 is "read permission" result = (0 == ACE_OS::access (this->file_name_.c_str (), 4)); if (result) { this->live_ = false; std::unique_ptr fstm (new ACEXML_FileCharStream); // xml input source will take ownership if (fstm->open (this->file_name_.c_str ()) == 0) { // InputSource takes ownership ACEXML_InputSource input (fstm.get ()); (void) fstm.release (); ACEXML_Parser parser; parser.setContentHandler (this); parser.setDTDHandler (this); parser.setErrorHandler (this); parser.setEntityResolver (this); try { parser.parse (&input); } catch (const ACEXML_Exception& ex) { // The only way to find out what it is, it to let it print itself, so... ORBSVCS_ERROR ((LM_ERROR, "Unable to load \"%s\".\n Will try backup file.\n", this->file_name_.c_str ())); ex.print (); result = false; } } else { ORBSVCS_DEBUG((LM_DEBUG, ACE_TEXT("Unable to open the XML input file: %s.\n Will try backup file.\n"), file_name_.c_str())); result = false; } } if (! result) { this->file_name_ = base_name; this->file_name_ += ACE_TEXT(".000"); result = (0 == ACE_OS::access (this->file_name_.c_str (), 4)); } return result; } //virtual void XML_Loader::load (Topology_Object *root) { ACE_ASSERT (root != 0); this->live_ = true; std::unique_ptr fstm (new ACEXML_FileCharStream); // xml input source will take ownership if (fstm->open (this->file_name_.c_str ()) == 0) { // InputSource takes ownership ACEXML_InputSource input (fstm.get ()); (void) fstm.release (); ACEXML_Parser parser; parser.setContentHandler (this); parser.setDTDHandler (this); parser.setErrorHandler (this); parser.setEntityResolver (this); try { object_stack_.push (root); parser.parse (&input); ACE_ASSERT (object_stack_.size () == 1); Topology_Object* cur = 0; object_stack_.pop (cur); } catch (const ACEXML_Exception& ex) { // The only way to find out what it is, it to let it print itself, so... ORBSVCS_ERROR ((LM_ERROR, "Unable to load \"%s\".\n", this->file_name_.c_str ())); ex.print (); throw CORBA::INTERNAL(); } } else { ORBSVCS_DEBUG((LM_DEBUG, ACE_TEXT("Unable to open the XML input file: %s.\n"), file_name_.c_str())); throw CORBA::INTERNAL(); } } void XML_Loader::startElement (const ACEXML_Char*, const ACEXML_Char*, const ACEXML_Char* name, ACEXML_Attributes* xml_attrs) { ACE_ASSERT (name != 0); ACE_ASSERT (xml_attrs != 0); if (this->live_) { ACE_ASSERT (object_stack_.size () > 0); Topology_Object* cur = 0; if (object_stack_.top (cur) == 0) { try { NVPList attrs; CORBA::Long id = makeNVPList (attrs, xml_attrs); if (DEBUG_LEVEL > 5) ORBSVCS_DEBUG ((LM_INFO, ACE_TEXT("(%P|%t) XML_Loader: Element %s\n"), name )); ACE_CString cname (ACE_TEXT_ALWAYS_CHAR(name)); Topology_Object* next = cur->load_child (cname, id, attrs); ACE_ASSERT(next != 0); object_stack_.push (next); } catch (const CORBA::Exception& ex) { throw ACEXML_SAXException (ACE_TEXT_CHAR_TO_TCHAR(ex._info ().c_str ())); } } } } void XML_Loader::endElement (const ACEXML_Char*, const ACEXML_Char*, const ACEXML_Char* name) { ACE_UNUSED_ARG (name); if (this->live_) { ACE_ASSERT (object_stack_.size () > 0); if (DEBUG_LEVEL > 5) { ORBSVCS_DEBUG ((LM_INFO, ACE_TEXT("(%P|%t) XML_Loader: End Element %s\n"), name)); } Topology_Object* cur = 0; object_stack_.pop (cur); } } } /* namespace TAO_Notify */ TAO_END_VERSIONED_NAMESPACE_DECL