Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

XercesLoader.cpp

Go to the documentation of this file.
00001 #include "XercesLoader.h"
00002 #include "XercesFileElement.h"
00003 #include "NodeCreationProxy.h"
00004 #include "X3DAbstractNode.h"
00005 #include "Scene.h"
00006 
00007 #include <xercesc/util/XMLString.hpp>
00008 #include <xercesc/sax2/DefaultHandler.hpp>
00009 #include <xercesc/sax2/XMLReaderFactory.hpp>
00010 #include <xercesc/util/PlatformUtils.hpp>
00011 
00012 #include <iostream>
00013 
00014 using namespace X3DTK;
00015 using namespace std;
00016 XERCES_CPP_NAMESPACE_USE
00017 
00018 namespace X3DTK {
00019 
00020 class SAX2X3DHandler : public DefaultHandler
00021 {
00022 public: 
00023   SAX2X3DHandler(NodeCreationProxy *nodeCreationProxy);
00024   ~SAX2X3DHandler();
00025   
00026   void startDocument();
00027   void startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const XERCES_CPP_NAMESPACE_QUALIFIER Attributes &attrs);
00028   void endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname);  
00029   void endDocument();
00030   void fatalError(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException& exception);
00031   void error(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException& exception);
00032   
00033   inline Scene *getScene() const {return _scene;};
00034   
00035 private:
00036   MFNode _nodeStack;
00037   Scene *_scene;
00038   NodeCreationProxy *_ncp;
00039   bool _sceneDescription;
00040   unsigned int _depth;
00041 };
00042 
00043 }
00044 
00045 X3DTK::SAX2X3DHandler::SAX2X3DHandler(NodeCreationProxy *nodeCreationProxy)
00046 : _scene(0), _ncp(nodeCreationProxy), _sceneDescription(false), _depth(0)
00047 {
00048 }
00049 
00050 X3DTK::SAX2X3DHandler::~SAX2X3DHandler()
00051 {
00052 }
00053 
00054 void X3DTK::SAX2X3DHandler::startDocument()
00055 {
00056   _scene = 0;
00057   _sceneDescription = false;
00058   _depth = 0;
00059 }
00060 
00061 void X3DTK::SAX2X3DHandler::startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes &attrs)
00062 {
00063   //_depth == 0, meaning that all the fathers of the node are defined nodes(have a Creation Function)
00064   //This variable is used to jump a sub-tree of the graph scene, when an unknown node is met.
00065   if (_depth == 0)
00066   {
00067     XercesFileElement e(XMLString::transcode(qname), &attrs);
00068 
00069     int index;  
00070     if (_sceneDescription)
00071     {
00072       SFNode Father = _nodeStack.back();
00073       SFNode N;
00074       index = e.getIndexAttribute("USE");
00075       
00076       if (index != -1)
00077       {
00078         N = X3DAbstractNode::DEFDict.getNodeOfName(e.getAttribute(index));
00079       }  
00080       else  
00081       {
00082         N = _ncp->createFromName(e.getName());
00083         if (N == 0)
00084         {
00085           _depth = 1;
00086           return;
00087         }
00088         N->loadAttributes(&e);
00089       }
00090       index = e.getIndexAttribute("DEF");
00091       if (index != -1)
00092         X3DAbstractNode::DEFDict.insert(e.getAttribute(index), N);
00093 
00094       Father->setChild(N);
00095       _nodeStack.push_back(N);  
00096     }  
00097   
00098     if (e.getName() == "Scene")
00099     {
00100       _sceneDescription = true;
00101       _scene = new Scene();
00102      _nodeStack.push_back(_scene);
00103     } 
00104   }
00105   else
00106     ++_depth;
00107 }
00108 
00109 void X3DTK::SAX2X3DHandler::endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname)
00110 {
00111   if (_sceneDescription)
00112   {
00113     if ((_depth == 0) && (_nodeStack.size() > 0))
00114       _nodeStack.pop_back();
00115     else
00116       --_depth;  
00117   }
00118 }
00119 
00120 void X3DTK::SAX2X3DHandler::endDocument()
00121 {
00122   X3DAbstractNode::DEFDict.makeDEFNonAmbiguous();
00123   _nodeStack.clear();
00124 }
00125 
00126 void X3DTK::SAX2X3DHandler::error(const SAXParseException& exception)
00127 {
00128   char* message = XMLString::transcode(exception.getMessage());
00129   cout << "Error: " << message
00130        << " at line: " << exception.getLineNumber()
00131        << endl;
00132 }
00133 
00134 void X3DTK::SAX2X3DHandler::fatalError(const SAXParseException& exception)
00135 {
00136   char* message = XMLString::transcode(exception.getMessage());
00137   cout << "Fatal Error: " << message
00138        << " at line: " << exception.getLineNumber()
00139        << endl;
00140 }
00141 
00142 class X3DTK::XercesLoaderImplementation
00143 {     
00144 public:
00145   XercesLoaderImplementation(){};
00146   
00147   XERCES_CPP_NAMESPACE_QUALIFIER SAX2XMLReader* _parser;
00148   SAX2X3DHandler *_handler;
00149 };
00150 
00151 XercesLoader::XercesLoader(NodeCreationProxy *nodeCreationProxy)
00152 : _impl(new XercesLoaderImplementation())
00153 {
00154   ncp = nodeCreationProxy;
00155   
00156   try 
00157   {
00158     XMLPlatformUtils::Initialize();
00159   }
00160   catch (const XMLException& toCatch) 
00161   {
00162     char* message = XMLString::transcode(toCatch.getMessage());
00163     cout << "Error during initialization! :\n";
00164     cout << "Exception message is: \n" << message << "\n";
00165     XMLString::release(&message);
00166   }
00167   
00168   _impl->_parser = XMLReaderFactory::createXMLReader();
00169   _impl->_parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
00170   _impl->_parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
00171   _impl->_parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, false);
00172   
00173   _impl->_handler = new SAX2X3DHandler(nodeCreationProxy);
00174   _impl->_parser->setContentHandler(_impl->_handler);
00175   _impl->_parser->setErrorHandler(_impl->_handler);
00176   _impl->_parser->setDTDHandler(_impl->_handler);
00177 }
00178 
00179 XercesLoader::~XercesLoader()
00180 {
00181   delete _impl->_parser;
00182   delete _impl->_handler;
00183 }
00184 
00185 Scene *XercesLoader::load(const char *file, bool fileValidation) const 
00186 {
00187   if (fileValidation)
00188   {
00189     _impl->_parser->setFeature(XMLUni::fgXercesLoadExternalDTD, true);
00190     _impl->_parser->setFeature(XMLUni::fgXercesSchema, true);
00191     _impl->_parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
00192   }
00193   else
00194   {
00195     _impl->_parser->setFeature(XMLUni::fgXercesLoadExternalDTD, false);
00196     _impl->_parser->setFeature(XMLUni::fgXercesSchema, false);
00197     _impl->_parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
00198   }  
00199   
00200   try 
00201   {
00202     _impl->_parser->parse(file);
00203   }
00204   catch (const XMLException& toCatch) 
00205   {
00206     char* message = XMLString::transcode(toCatch.getMessage());
00207     cout << "Exception message is: \n"
00208          << message << "\n";
00209             XMLString::release(&message);
00210   }
00211   catch (const SAXParseException& toCatch) 
00212   {
00213     char* message = XMLString::transcode(toCatch.getMessage());
00214     cout << "Exception message is: \n"
00215          << message << "\n";
00216             XMLString::release(&message);
00217   }
00218   catch (...) 
00219   {
00220     cout << "Unexpected Exception \n" ;
00221   }
00222   
00223   Scene *scene = _impl->_handler->getScene();
00224   if (scene != 0)
00225     scene->setFileName(file);
00226     
00227   return scene;
00228 }
00229 

Generated on Wed May 14 10:03:13 2003 for X3DToolKit by doxygen1.3