00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef OPENMS_FORMAT_HANDLERS_XMLHANDLER_H
00036 #define OPENMS_FORMAT_HANDLERS_XMLHANDLER_H
00037
00038 #include <iostream>
00039
00040 #include <OpenMS/CONCEPT/Types.h>
00041 #include <OpenMS/CONCEPT/Macros.h>
00042
00043 #include <OpenMS/DATASTRUCTURES/DateTime.h>
00044 #include <OpenMS/METADATA/MetaInfoInterface.h>
00045
00046 #include <xercesc/sax2/DefaultHandler.hpp>
00047 #include <xercesc/sax/Locator.hpp>
00048 #include <xercesc/sax2/Attributes.hpp>
00049
00050 #include <algorithm>
00051
00052 namespace OpenMS
00053 {
00054 namespace Internal
00055 {
00056
00058 class OPENMS_DLLAPI StringManager
00059 {
00060 public:
00062 StringManager();
00063
00065 ~StringManager();
00066
00068 void clear();
00069
00071 XMLCh * convert(const char * str) const;
00072
00074 XMLCh * convert(const std::string & str) const;
00075
00077 XMLCh * convert(const String & str) const;
00078
00080 char * convert(const XMLCh * str) const;
00081 private:
00082 mutable std::vector<XMLCh *> xml_strings_;
00083 mutable std::vector<char *> c_strings_;
00084 };
00085
00089 class OPENMS_DLLAPI XMLHandler :
00090 public xercesc::DefaultHandler
00091 {
00092 public:
00094 class OPENMS_DLLAPI EndParsingSoftly :
00095 public Exception::BaseException
00096 {
00097 public:
00098 EndParsingSoftly(const char * file, int line, const char * function) :
00099 Exception::BaseException(file, line, function)
00100 {
00101 }
00102
00103 };
00104
00106 enum ActionMode
00107 {
00108 LOAD,
00109 STORE
00110 };
00111
00113 XMLHandler(const String & filename, const String & version);
00115 virtual ~XMLHandler();
00116
00118 void reset();
00119
00120
00127 void fatalError(const xercesc::SAXParseException & exception);
00128 void error(const xercesc::SAXParseException & exception);
00129 void warning(const xercesc::SAXParseException & exception);
00131
00133 void fatalError(ActionMode mode, const String & msg, UInt line = 0, UInt column = 0) const;
00135 void error(ActionMode mode, const String & msg, UInt line = 0, UInt column = 0) const;
00137 void warning(ActionMode mode, const String & msg, UInt line = 0, UInt column = 0) const;
00138
00140 virtual void characters(const XMLCh * const chars, const XMLSize_t length);
00142 virtual void startElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname, const xercesc::Attributes & attrs);
00144 virtual void endElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname);
00145
00147 virtual void writeTo(std::ostream & )
00148 {
00149 }
00150
00152 String errorString();
00153
00154 protected:
00156 mutable String error_message_;
00157
00159 String file_;
00160
00162 String version_;
00163
00165 StringManager sm_;
00166
00172 std::vector<String> open_tags_;
00173
00175 inline bool equal_(const XMLCh * a, const XMLCh * b)
00176 {
00177 return xercesc::XMLString::compareString(a, b) == 0;
00178 }
00179
00181
00182
00184 void writeUserParam_(const String & tag_name, std::ostream & os, const MetaInfoInterface & meta, UInt indent) const;
00185
00187
00189
00190
00192 std::vector<std::vector<String> > cv_terms_;
00193
00196 inline SignedSize cvStringToEnum_(const Size section, const String & term, const char * message, const SignedSize result_on_error = 0)
00197 {
00198 OPENMS_PRECONDITION(section < cv_terms_.size(), "cvStringToEnum_: Index overflow (section number too large)");
00199
00200 std::vector<String>::const_iterator it = std::find(cv_terms_[section].begin(), cv_terms_[section].end(), term);
00201 if (it != cv_terms_[section].end())
00202 {
00203 return it - cv_terms_[section].begin();
00204 }
00205 else
00206 {
00207 warning(LOAD, String("Unexpected CV entry '") + message + "'='" + term + "'");
00208 return result_on_error;
00209 }
00210 }
00211
00213
00215
00216
00218 inline Int asInt_(const String & in)
00219 {
00220 Int res = 0;
00221 try
00222 {
00223 res = in.toInt();
00224 }
00225 catch (Exception::ConversionError)
00226 {
00227 error(LOAD, String("Int conversion error of \"") + in + "\"");
00228 }
00229 return res;
00230 }
00231
00233 inline Int asInt_(const XMLCh * in)
00234 {
00235 return xercesc::XMLString::parseInt(in);
00236 }
00237
00239 inline UInt asUInt_(const String & in)
00240 {
00241 UInt res = 0;
00242 try
00243 {
00244 Int tmp = in.toInt();
00245 if (tmp < 0)
00246 {
00247 Exception::ConversionError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "");
00248 }
00249 res = UInt(tmp);
00250 }
00251 catch (Exception::ConversionError)
00252 {
00253 error(LOAD, String("UInt conversion error of \"") + in + "\"");
00254 }
00255 return res;
00256 }
00257
00259 inline double asDouble_(const String & in)
00260 {
00261 double res = 0.0;
00262 try
00263 {
00264 res = in.toDouble();
00265 }
00266 catch (Exception::ConversionError)
00267 {
00268 error(LOAD, String("Double conversion error of \"") + in + "\"");
00269 }
00270 return res;
00271 }
00272
00274 inline float asFloat_(const String & in)
00275 {
00276 float res = 0.0;
00277 try
00278 {
00279 res = in.toFloat();
00280 }
00281 catch (Exception::ConversionError)
00282 {
00283 error(LOAD, String("Float conversion error of \"") + in + "\"");
00284 }
00285 return res;
00286 }
00287
00294 inline bool asBool_(const String & in)
00295 {
00296 if (in == "true" || in == "TRUE" || in == "True" || in == "1")
00297 {
00298 return true;
00299 }
00300 else if (in == "false" || in == "FALSE" || in == "False" || in == "0")
00301 {
00302 return false;
00303 }
00304 else
00305 {
00306 error(LOAD, String("Boolean conversion error of \"") + in + "\"");
00307 }
00308 return false;
00309 }
00310
00312 inline DateTime asDateTime_(String date_string)
00313 {
00314 DateTime date_time;
00315 if (date_string != "")
00316 {
00317 try
00318 {
00319
00320 date_string.trim();
00321 date_string = date_string.substr(0, 19);
00322 date_time.set(date_string);
00323 }
00324 catch (Exception::ParseError err)
00325 {
00326 error(LOAD, String("DateTime conversion error of \"") + date_string + "\"");
00327 }
00328 }
00329 return date_time;
00330 }
00331
00333
00335
00336
00338 inline char * attributeAsString_(const xercesc::Attributes & a, const char * name) const
00339 {
00340 const XMLCh * val = a.getValue(sm_.convert(name));
00341 if (val == 0) fatalError(LOAD, String("Required attribute '") + name + "' not present!");
00342 return sm_.convert(val);
00343 }
00344
00346 inline Int attributeAsInt_(const xercesc::Attributes & a, const char * name) const
00347 {
00348 const XMLCh * val = a.getValue(sm_.convert(name));
00349 if (val == 0) fatalError(LOAD, String("Required attribute '") + name + "' not present!");
00350 return xercesc::XMLString::parseInt(val);
00351 }
00352
00354 inline DoubleReal attributeAsDouble_(const xercesc::Attributes & a, const char * name) const
00355 {
00356 const XMLCh * val = a.getValue(sm_.convert(name));
00357 if (val == 0) fatalError(LOAD, String("Required attribute '") + name + "' not present!");
00358 return String(sm_.convert(val)).toDouble();
00359 }
00360
00362 inline DoubleList attributeAsDoubleList_(const xercesc::Attributes & a, const char * name) const
00363 {
00364 String tmp(expectList_(attributeAsString_(a, name)));
00365 return DoubleList::create(tmp.substr(1, tmp.size() - 2));
00366 }
00367
00369 inline IntList attributeAsIntList_(const xercesc::Attributes & a, const char * name) const
00370 {
00371 String tmp(expectList_(attributeAsString_(a, name)));
00372 return IntList::create(tmp.substr(1, tmp.size() - 2));
00373 }
00374
00376 inline StringList attributeAsStringList_(const xercesc::Attributes & a, const char * name) const
00377 {
00378 String tmp(expectList_(attributeAsString_(a, name)));
00379 return StringList::create(tmp.substr(1, tmp.size() - 2));
00380 }
00381
00387 inline bool optionalAttributeAsString_(String & value, const xercesc::Attributes & a, const char * name) const
00388 {
00389 const XMLCh * val = a.getValue(sm_.convert(name));
00390 if (val != 0)
00391 {
00392 value = sm_.convert(val);
00393 return true;
00394 }
00395 return false;
00396 }
00397
00403 inline bool optionalAttributeAsInt_(Int & value, const xercesc::Attributes & a, const char * name) const
00404 {
00405 const XMLCh * val = a.getValue(sm_.convert(name));
00406 if (val != 0)
00407 {
00408 value = xercesc::XMLString::parseInt(val);
00409 return true;
00410 }
00411 return false;
00412 }
00413
00419 inline bool optionalAttributeAsUInt_(UInt & value, const xercesc::Attributes & a, const char * name) const
00420 {
00421 const XMLCh * val = a.getValue(sm_.convert(name));
00422 if (val != 0)
00423 {
00424 value = xercesc::XMLString::parseInt(val);
00425 return true;
00426 }
00427 return false;
00428 }
00429
00435 inline bool optionalAttributeAsDouble_(DoubleReal & value, const xercesc::Attributes & a, const char * name) const
00436 {
00437 const XMLCh * val = a.getValue(sm_.convert(name));
00438 if (val != 0)
00439 {
00440 value = String(sm_.convert(val)).toDouble();
00441 return true;
00442 }
00443 return false;
00444 }
00445
00451 inline bool optionalAttributeAsDoubleList_(DoubleList & value, const xercesc::Attributes & a, const char * name) const
00452 {
00453 const XMLCh * val = a.getValue(sm_.convert(name));
00454 if (val != 0)
00455 {
00456 value = attributeAsDoubleList_(a, name);
00457 return true;
00458 }
00459 return false;
00460 }
00461
00467 inline bool optionalAttributeAsStringList_(StringList & value, const xercesc::Attributes & a, const char * name) const
00468 {
00469 const XMLCh * val = a.getValue(sm_.convert(name));
00470 if (val != 0)
00471 {
00472 value = attributeAsStringList_(a, name);
00473 return true;
00474 }
00475 return false;
00476 }
00477
00483 inline bool optionalAttributeAsIntList_(IntList & value, const xercesc::Attributes & a, const char * name) const
00484 {
00485 const XMLCh * val = a.getValue(sm_.convert(name));
00486 if (val != 0)
00487 {
00488 value = attributeAsIntList_(a, name);
00489 return true;
00490 }
00491 return false;
00492 }
00493
00495 inline char * attributeAsString_(const xercesc::Attributes & a, const XMLCh * name) const
00496 {
00497 const XMLCh * val = a.getValue(name);
00498 if (val == 0) fatalError(LOAD, String("Required attribute '") + sm_.convert(name) + "' not present!");
00499 return sm_.convert(val);
00500 }
00501
00503 inline Int attributeAsInt_(const xercesc::Attributes & a, const XMLCh * name) const
00504 {
00505 const XMLCh * val = a.getValue(name);
00506 if (val == 0) fatalError(LOAD, String("Required attribute '") + sm_.convert(name) + "' not present!");
00507 return xercesc::XMLString::parseInt(val);
00508 }
00509
00511 inline DoubleReal attributeAsDouble_(const xercesc::Attributes & a, const XMLCh * name) const
00512 {
00513 const XMLCh * val = a.getValue(name);
00514 if (val == 0) fatalError(LOAD, String("Required attribute '") + sm_.convert(name) + "' not present!");
00515 return String(sm_.convert(val)).toDouble();
00516 }
00517
00519 inline DoubleList attributeAsDoubleList_(const xercesc::Attributes & a, const XMLCh * name) const
00520 {
00521 String tmp(expectList_(attributeAsString_(a, name)));
00522 return DoubleList::create(tmp.substr(1, tmp.size() - 2));
00523 }
00524
00526 inline IntList attributeAsIntList_(const xercesc::Attributes & a, const XMLCh * name) const
00527 {
00528 String tmp(expectList_(attributeAsString_(a, name)));
00529 return IntList::create(tmp.substr(1, tmp.size() - 2));
00530 }
00531
00533 inline StringList attributeAsStringList_(const xercesc::Attributes & a, const XMLCh * name) const
00534 {
00535 String tmp(expectList_(attributeAsString_(a, name)));
00536 return StringList::create(tmp.substr(1, tmp.size() - 2));
00537 }
00538
00540 inline bool optionalAttributeAsString_(String & value, const xercesc::Attributes & a, const XMLCh * name) const
00541 {
00542 const XMLCh * val = a.getValue(name);
00543 if (val != 0)
00544 {
00545 char * tmp2 = sm_.convert(val);
00546 if (String(tmp2) != "")
00547 {
00548 value = tmp2;
00549 return true;
00550 }
00551 }
00552 return false;
00553 }
00554
00556 inline bool optionalAttributeAsInt_(Int & value, const xercesc::Attributes & a, const XMLCh * name) const
00557 {
00558 const XMLCh * val = a.getValue(name);
00559 if (val != 0)
00560 {
00561 value = xercesc::XMLString::parseInt(val);
00562 return true;
00563 }
00564 return false;
00565 }
00566
00568 inline bool optionalAttributeAsUInt_(UInt & value, const xercesc::Attributes & a, const XMLCh * name) const
00569 {
00570 const XMLCh * val = a.getValue(name);
00571 if (val != 0)
00572 {
00573 value = xercesc::XMLString::parseInt(val);
00574 return true;
00575 }
00576 return false;
00577 }
00578
00580 inline bool optionalAttributeAsDouble_(DoubleReal & value, const xercesc::Attributes & a, const XMLCh * name) const
00581 {
00582 const XMLCh * val = a.getValue(name);
00583 if (val != 0)
00584 {
00585 value = String(sm_.convert(val)).toDouble();
00586 return true;
00587 }
00588 return false;
00589 }
00590
00596 inline bool optionalAttributeAsDoubleList_(DoubleList & value, const xercesc::Attributes & a, const XMLCh * name) const
00597 {
00598 const XMLCh * val = a.getValue(name);
00599 if (val != 0)
00600 {
00601 value = attributeAsDoubleList_(a, name);
00602 return true;
00603 }
00604 return false;
00605 }
00606
00612 inline bool optionalAttributeAsIntList_(IntList & value, const xercesc::Attributes & a, const XMLCh * name) const
00613 {
00614 const XMLCh * val = a.getValue(name);
00615 if (val != 0)
00616 {
00617 value = attributeAsIntList_(a, name);
00618 return true;
00619 }
00620 return false;
00621 }
00622
00628 inline bool optionalAttributeAsStringList_(StringList & value, const xercesc::Attributes & a, const XMLCh * name) const
00629 {
00630 const XMLCh * val = a.getValue(name);
00631 if (val != 0)
00632 {
00633 value = attributeAsStringList_(a, name);
00634 return true;
00635 }
00636 return false;
00637 }
00638
00640
00641 private:
00643 XMLHandler();
00644
00645 inline String expectList_(const char * str) const
00646 {
00647 String tmp(str);
00648 if (!(tmp.hasPrefix('[') && tmp.hasSuffix(']')))
00649 {
00650 fatalError(LOAD, String("List argument is not a string representation of a list!"));
00651 }
00652 return tmp;
00653 }
00654
00655 };
00656
00657 }
00658 }
00659
00660 #endif // OPENMS_FORMAT_HANDLERS_XMLHANDLER_H