hpp-manipulation-urdf  6.0.0
Implementation of a parser for hpp-manipulation.
parser.hh
Go to the documentation of this file.
1 // Copyright (c) 2014, LAAS-CNRS
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4 
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // 1. Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28 
29 #ifndef HPP_MANIPULATION_PARSER_HH
30 #define HPP_MANIPULATION_PARSER_HH
31 
32 #include <tinyxml2.h>
33 
34 #include <hpp/manipulation/fwd.hh>
35 #include <iostream>
36 #include <list>
37 #include <map>
38 #include <string>
39 
40 namespace hpp {
41 namespace manipulation {
42 namespace parser {
48 
49 class RootFactory;
50 
57 
60 
86  public:
87  typedef std::vector<ObjectFactory*> ObjectFactoryList;
88 
89  ObjectFactory(ObjectFactory* parent = NULL, const XMLElement* element = NULL);
90 
91  virtual ~ObjectFactory() {}
92 
95 
98  virtual bool init();
99 
106  void setAttribute(const XMLAttribute* attr);
107 
109  virtual void addTextChild(const XMLText* text);
110 
113  virtual bool finishAttributes();
114 
116  virtual void finishTags();
117 
119  virtual void finishFile();
120 
122 
125 
128  std::string tagName() const;
129 
132  std::string name() const;
133 
135  bool hasAttribute(const std::string& attr) const;
136 
138  std::string getAttribute(const std::string& attr) const;
139 
142 
148  bool getChildOfType(std::string type, ObjectFactory*& o);
149 
151 
155  void name(const std::string& n);
156 
158  void name(const char* n);
159 
161  template <typename T>
162  T* as() {
163  if (!dynamic_cast<T*>(this)) {
164  std::ostringstream oss;
165  oss << "Unexpected tag: " << this->tagName();
166  throw std::invalid_argument(oss.str().c_str());
167  }
168  return static_cast<T*>(this);
169  }
170 
171  protected:
173 
175 
177 
178  bool hasParent() const;
179 
181 
182  virtual void impl_setAttribute(const XMLAttribute* attr);
183 
184  void addChild(ObjectFactory* child);
185 
186  virtual std::ostream& print(std::ostream& os) const;
187 
188  private:
189  ObjectFactory* parent_;
190  RootFactory* root_;
191  typedef std::map<std::string, ObjectFactoryList> ChildrenMap;
192  ChildrenMap children_;
193 
194  const XMLElement* element_;
195 
196  typedef std::map<std::string, std::string> AttributeMap;
197  AttributeMap attrMap_;
198  std::string name_;
199  int id_;
200 
201  friend std::ostream& operator<<(std::ostream&, const ObjectFactory&);
202 };
203 
205 class RootFactory : public ObjectFactory {
206  public:
207  virtual ~RootFactory() {}
208  RootFactory(const DevicePtr_t dev = DevicePtr_t());
209 
210  DevicePtr_t device() const;
211 
212  inline std::string prependPrefix(const std::string& in) const {
213  if (prefix_.empty()) return in;
214  return prefix_ + in;
215  }
216 
217  inline std::string removePrefix(const std::string& in) const {
218  if (prefix_.empty()) return in;
219  assert(in.compare(0, prefix_.size(), prefix_) == 0);
220  return in.substr(prefix_.size());
221  }
222 
223  void prefix(const std::string& prefix) {
224  if (prefix.empty()) return;
225  prefix_ = prefix + "/";
226  }
227 
228  private:
229  DevicePtr_t device_;
230  std::string prefix_;
231 };
232 
234 
237 template <typename T>
239  const XMLElement* element = NULL) {
240  return new T(parent, element);
241 }
242 
248 class Parser {
249  public:
250  typedef ObjectFactory* (*FactoryType)(ObjectFactory*, const XMLElement*);
252 
259  Parser(bool fillWithDefaultFactories = true,
260  FactoryType defaultFactory = create<ObjectFactory>);
261 
263 
264  void addObjectFactory(const std::string& tagname, FactoryType factory);
265 
266  void parseString(const std::string& xmlString, DevicePtr_t robot);
267 
268  void parseFile(const std::string& filename, DevicePtr_t robot);
269 
270  const ObjectFactoryList& objectFactories() const { return objectFactories_; }
271 
273  void prefix(const std::string& prefix) { prefix_ = prefix; }
274 
275  private:
276  XMLDocument doc_;
277  RootFactory* root_;
278  DevicePtr_t device_;
279 
280  void loadFile(const char* filename);
281 
282  void loadString(const char* xmlstring);
283 
284  void parse();
285 
286  void parseElement(const XMLElement* element, ObjectFactory* parent);
287 
288  typedef std::map<std::string, FactoryType> ObjectFactoryMap;
289  typedef std::pair<std::string, FactoryType> ObjectFactoryPair;
290  typedef std::pair<ObjectFactoryMap::iterator, bool> ObjectFactoryInsertRet;
291  ObjectFactoryMap objFactoryMap_;
292  FactoryType defaultFactory_;
293 
294  ObjectFactoryList objectFactories_;
295 
296  std::string prefix_;
297 
298  std::ostream& print(std::ostream&) const;
299  friend std::ostream& operator<<(std::ostream&, const Parser&);
300 };
301 
302 std::ostream& operator<<(std::ostream&, const ObjectFactory&);
303 std::ostream& operator<<(std::ostream&, const Parser&);
304 } // namespace parser
305 } // namespace manipulation
306 } // namespace hpp
307 
308 #endif // HPP_MANIPULATION_PARSER_HH
Class that catch XML Parser events for a specific tag and build the corresponding Object.
Definition: parser.hh:85
friend std::ostream & operator<<(std::ostream &, const ObjectFactory &)
virtual ~ObjectFactory()
Definition: parser.hh:91
std::vector< ObjectFactory * > ObjectFactoryList
Definition: parser.hh:87
virtual void finishFile()
Called when parsing is finished.
void name(const std::string &n)
void setAttribute(const XMLAttribute *attr)
void addChild(ObjectFactory *child)
ObjectFactoryList getChildrenOfType(std::string type)
Get a list of ObjectFactory whose tag name is type.
T * as()
Cast this class to any child class.
Definition: parser.hh:162
void name(const char *n)
See name(const std::string&)
virtual void finishTags()
Called when all the child tags have been processed.
virtual void impl_setAttribute(const XMLAttribute *attr)
ObjectFactory(ObjectFactory *parent=NULL, const XMLElement *element=NULL)
bool hasAttribute(const std::string &attr) const
Check if an attribute was set.
virtual std::ostream & print(std::ostream &os) const
std::string getAttribute(const std::string &attr) const
Return a given attributes.
bool getChildOfType(std::string type, ObjectFactory *&o)
virtual void addTextChild(const XMLText *text)
Add Text child.
Parse an XML document.
Definition: parser.hh:248
Parser(bool fillWithDefaultFactories=true, FactoryType defaultFactory=create< ObjectFactory >)
const ObjectFactoryList & objectFactories() const
Definition: parser.hh:270
void prefix(const std::string &prefix)
Set the prefix of all joints.
Definition: parser.hh:273
friend std::ostream & operator<<(std::ostream &, const Parser &)
void addObjectFactory(const std::string &tagname, FactoryType factory)
ObjectFactory *(* FactoryType)(ObjectFactory *, const XMLElement *)
Definition: parser.hh:250
void parseString(const std::string &xmlString, DevicePtr_t robot)
ObjectFactory::ObjectFactoryList ObjectFactoryList
Definition: parser.hh:251
void parseFile(const std::string &filename, DevicePtr_t robot)
Represent a XML document.
Definition: parser.hh:205
virtual ~RootFactory()
Definition: parser.hh:207
std::string removePrefix(const std::string &in) const
Definition: parser.hh:217
RootFactory(const DevicePtr_t dev=DevicePtr_t())
void prefix(const std::string &prefix)
Definition: parser.hh:223
std::string prependPrefix(const std::string &in) const
Definition: parser.hh:212
std::ostream & operator<<(std::ostream &, const ObjectFactory &)
tinyxml2::XMLAttribute XMLAttribute
Definition: parser.hh:45
tinyxml2::XMLDocument XMLDocument
Definition: parser.hh:44
ObjectFactory * create(ObjectFactory *parent=NULL, const XMLElement *element=NULL)
Definition: parser.hh:238
tinyxml2::XMLElement XMLElement
Definition: parser.hh:43
tinyxml2::XMLText XMLText
Definition: parser.hh:47
tinyxml2::XMLNode XMLNode
Definition: parser.hh:46
Definition: ignoretag.hh:34