CLAM-Development  1.4.0
XercesDomDocumentHandler.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 #ifndef _XercesDomDocumentHandler_hxx_
22 #define _XercesDomDocumentHandler_hxx_
23 
24 #include "XercesEncodings.hxx"
27 #include "XercesDomReader.hxx"
28 #include "XercesDomWriter.hxx"
29 #include "XercesInitializer.hxx"
30 
31 
32 #include <xercesc/parsers/XercesDOMParser.hpp>
33 #include <xercesc/dom/DOMImplementation.hpp>
34 #include <xercesc/dom/DOMDocument.hpp>
35 #include <xercesc/dom/DOMElement.hpp>
36 
37 namespace CLAM
38 {
39 class XercesDomReadingContext;
40 class XercesDomWritingContext;
41 
47 {
48 public:
52  {
53  return _currentReadContext;
54  }
56  {
57  _currentReadContext = context;
58  }
60  {
61  return _currentWriteContext;
62  }
64  {
65  _currentWriteContext = context;
66  }
67 private:
68  ReadingContext * _currentReadContext;
69  WritingContext * _currentWriteContext;
70  xercesc::DOMDocument * _document;
71  xercesc::DOMElement * _selection;
72  xercesc::XercesDOMParser * _parser;
73 public:
75  {
76  _document = 0;
77  _selection = 0;
78  _parser = 0;
79  }
81  {
82  releaseIfAnyDocument();
83  }
84  void setDocument(xercesc::DOMDocument * document)
85  {
86  _document = document;
87  _selection = _document->getDocumentElement();
88  }
89  void selectPath(const char * path)
90  {
91  if (path[0]!='/')
92  _selection = recursiveSelection(_selection, path, 0);
93  else
94  _selection = absoluteSelection(path);
95  return;
96  }
97 
98  xercesc::DOMElement * getSelection()
99  {
100  return _selection;
101  }
102  void create(const char * rootName)
103  {
105  releaseIfAnyDocument();
106  xercesc::DOMImplementation * imp =
107  xercesc::DOMImplementation::getImplementation();
108  xercesc::DOMDocument * domDoc = imp->createDocument(0,U(rootName),0);
109  setDocument(domDoc);
110  }
111  void read(std::istream & stream)
112  {
113  XercesDomReader reader;
114  xercesc::DOMDocument * domDoc;
115  domDoc = reader.read(stream);
116  setDocument(domDoc);
117  _parser = reader.adoptParser();
118  }
119  void writeDocument(std::ostream & os, bool useIndentation=false)
120  {
121  XercesDomWriter writer;
122  writer.DoIndentedFormat(useIndentation);
123  writer.write(os,_document);
124  }
125  void writeSelection(std::ostream & os, bool useIndentation=false)
126  {
127  XercesDomWriter writer;
128  writer.DoIndentedFormat(useIndentation);
129  writer.write(os,_selection);
130  }
131 private:
132  void releaseIfAnyDocument()
133  {
134  if (!_document) return;
135  if (_parser)
136  delete _parser;
137  else
138  _document->release();
139  _parser=0;
140  _document=0;
141  }
142  xercesc::DOMElement * absoluteSelection(const std::string & path)
143  {
144  xercesc::DOMElement * root = (xercesc::DOMElement*) _document->getDocumentElement();
145  unsigned int nextSlash = std::string(path).find('/',1);
146  std::string rootStep = std::string(path).substr(1,nextSlash-1);
147  std::string rootName = L(root->getNodeName());
148  if (rootStep=="") return root;
149 
150  if (rootName== rootStep)
151  return recursiveSelection(root, path, nextSlash+1);
152 
153  throw XmlStorageErr("Wrong root name, expected '"+rootStep+"' but found '"+rootName+"'");
154  }
155  xercesc::DOMElement * recursiveSelection(xercesc::DOMElement * current, const std::string & path, unsigned int pos)
156  {
157  if (pos >= path.length()) return current;
158  unsigned int slashPosition = path.find('/', pos);
159  unsigned int stepSize =
160  slashPosition == std::string::npos ?
161  std::string::npos : slashPosition-pos;
162  std::string step = path.substr(pos, stepSize);
163  for (
164  xercesc::DOMNode * child = current->getFirstChild();
165  child;
166  child = child->getNextSibling())
167  {
168  if (child->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) continue;
169  std::string nodeName(L(child->getNodeName()));
170  if (nodeName != step) continue;
171  if (slashPosition==std::string::npos) return (xercesc::DOMElement *) child;
172  return recursiveSelection((xercesc::DOMElement *) child, path, slashPosition+1);
173  }
174  std::string msg = "Wrong path step '" + step + "'";
175  throw XmlStorageErr(msg);
176  }
177 
178 };
179 
180 
181 }
182 
188 #endif//_XercesDomDocumentHandler_hxx_
189