XercesDomDocumentHandler.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 #ifndef _XercesDomDocumentHandler_hxx_
00022 #define _XercesDomDocumentHandler_hxx_
00023 
00024 #include "XercesEncodings.hxx"
00025 #include "XercesDomReadingContext.hxx"
00026 #include "XercesDomWritingContext.hxx"
00027 #include "XercesDomReader.hxx"
00028 #include "XercesDomWriter.hxx"
00029 #include "XercesInitializer.hxx"
00030 
00031 
00032 #include <xercesc/parsers/XercesDOMParser.hpp>
00033 #include <xercesc/dom/DOMImplementation.hpp>
00034 #include <xercesc/dom/DOMDocument.hpp>
00035 #include <xercesc/dom/DOMElement.hpp>
00036 
00037 namespace CLAM 
00038 {
00039 class XercesDomReadingContext;
00040 class XercesDomWritingContext;
00041 
00046 class XercesDomDocumentHandler
00047 {
00048 public:
00049         typedef XercesDomWritingContext WritingContext;
00050         typedef XercesDomReadingContext ReadingContext;
00051         ReadingContext * GetReadingContext()
00052         {
00053                 return _currentReadContext;
00054         }
00055         void SetReadingContext(ReadingContext * context)
00056         {
00057                 _currentReadContext = context;
00058         }
00059         WritingContext * GetWritingContext()
00060         {
00061                 return _currentWriteContext;
00062         }
00063         void SetWritingContext(WritingContext * context)
00064         {
00065                 _currentWriteContext = context;
00066         }
00067 private:
00068         ReadingContext * _currentReadContext;
00069         WritingContext * _currentWriteContext;
00070         xercesc::DOMDocument * _document;
00071         xercesc::DOMElement * _selection;
00072         xercesc::XercesDOMParser * _parser;
00073 public:
00074         XercesDomDocumentHandler()
00075         {
00076                 _document = 0;
00077                 _selection = 0;
00078                 _parser = 0;
00079         }
00080         ~XercesDomDocumentHandler()
00081         {
00082                 releaseIfAnyDocument();
00083         }
00084         void setDocument(xercesc::DOMDocument * document)
00085         {
00086                 _document = document;
00087                 _selection = _document->getDocumentElement();
00088         }
00089         void selectPath(const char * path)
00090         {
00091                 if (path[0]!='/') 
00092                         _selection = recursiveSelection(_selection, path, 0);
00093                 else
00094                         _selection = absoluteSelection(path);
00095                 return;
00096         }
00097         
00098         xercesc::DOMElement * getSelection()
00099         {
00100                 return _selection;
00101         }
00102         void create(const char * rootName)
00103         {
00104                 XercesInitializer::require();
00105                 releaseIfAnyDocument();
00106                 xercesc::DOMImplementation * imp =
00107                         xercesc::DOMImplementation::getImplementation();
00108                 xercesc::DOMDocument * domDoc = imp->createDocument(0,U(rootName),0);
00109                 setDocument(domDoc);
00110         }
00111         void read(std::istream & stream)
00112         {
00113                 XercesDomReader reader;
00114                 xercesc::DOMDocument * domDoc;
00115                 domDoc = reader.read(stream);
00116                 setDocument(domDoc);
00117                 _parser = reader.adoptParser();
00118         }
00119         void writeDocument(std::ostream & os, bool useIndentation=false)
00120         {
00121                 XercesDomWriter writer;
00122                 writer.DoIndentedFormat(useIndentation);
00123                 writer.write(os,_document);
00124         }
00125         void writeSelection(std::ostream & os, bool useIndentation=false)
00126         {
00127                 XercesDomWriter writer;
00128                 writer.DoIndentedFormat(useIndentation);
00129                 writer.write(os,_selection);
00130         }
00131 private:
00132         void releaseIfAnyDocument()
00133         {
00134                 if (!_document) return;
00135                 if (_parser)
00136                         delete _parser;
00137                 else 
00138                         _document->release();
00139                 _parser=0;
00140                 _document=0;
00141         }
00142         xercesc::DOMElement * absoluteSelection(const std::string & path)
00143         {
00144                 xercesc::DOMElement * root = (xercesc::DOMElement*) _document->getDocumentElement();
00145                 unsigned int nextSlash = std::string(path).find('/',1);
00146                 std::string rootStep = std::string(path).substr(1,nextSlash-1);
00147                 std::string rootName = L(root->getNodeName());
00148                 if (rootStep=="") return root;
00149 
00150                 if (rootName== rootStep)
00151                         return recursiveSelection(root, path, nextSlash+1);
00152 
00153                 throw XmlStorageErr("Wrong root name, expected '"+rootStep+"' but found '"+rootName+"'");
00154         }
00155         xercesc::DOMElement * recursiveSelection(xercesc::DOMElement * current, const std::string & path, unsigned int pos)
00156         {
00157                 if (pos >= path.length()) return current;
00158                 unsigned int slashPosition = path.find('/', pos);
00159                 unsigned int stepSize = 
00160                         slashPosition == std::string::npos ? 
00161                                 std::string::npos : slashPosition-pos;
00162                 std::string step = path.substr(pos, stepSize);
00163                 for (
00164                         xercesc::DOMNode * child = current->getFirstChild();
00165                         child;
00166                         child = child->getNextSibling())
00167                 {
00168                         if (child->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) continue;
00169                         std::string nodeName(L(child->getNodeName()));
00170                         if (nodeName != step) continue;
00171                         if (slashPosition==std::string::npos) return (xercesc::DOMElement *) child;
00172                         return recursiveSelection((xercesc::DOMElement *) child, path, slashPosition+1);
00173                 }
00174                 std::string msg = "Wrong path step '" + step + "'";
00175                 throw XmlStorageErr(msg);
00176         }
00177 
00178 };
00179 
00180 
00181 }
00182 
00188 #endif//_XercesDomDocumentHandler_hxx_
00189 
Generated by  doxygen 1.6.3