Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages

XMLHandler.h

Go to the documentation of this file.
00001 // --------------------------------------------------------------------------
00002 //                   OpenMS -- Open-Source Mass Spectrometry
00003 // --------------------------------------------------------------------------
00004 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
00005 // ETH Zurich, and Freie Universitaet Berlin 2002-2012.
00006 //
00007 // This software is released under a three-clause BSD license:
00008 //  * Redistributions of source code must retain the above copyright
00009 //    notice, this list of conditions and the following disclaimer.
00010 //  * Redistributions in binary form must reproduce the above copyright
00011 //    notice, this list of conditions and the following disclaimer in the
00012 //    documentation and/or other materials provided with the distribution.
00013 //  * Neither the name of any author or any participating institution
00014 //    may be used to endorse or promote products derived from this software
00015 //    without specific prior written permission.
00016 // For a full list of authors, refer to the file AUTHORS.
00017 // --------------------------------------------------------------------------
00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
00022 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00024 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00025 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00027 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00028 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 //
00030 // --------------------------------------------------------------------------
00031 // $Maintainer: Chris Bielow $
00032 // $Authors: Marc Sturm, Chris Bielow $
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 & /*os*/)
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             //strip away milliseconds
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   }   // namespace Internal
00658 } // namespace OpenMS
00659 
00660 #endif // OPENMS_FORMAT_HANDLERS_XMLHANDLER_H

OpenMS / TOPP release 1.10.0 Documentation generated on Thu Mar 7 2013 09:42:46 using doxygen 1.7.1