CLAM-Development
1.1
|
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