Vaucanson 1.4
printers.hxx
00001 // printers.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2005, 2006, 2007, 2008, 2009 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 
00018 #ifndef VCSN_XML_PRINTERS_HXX
00019 # define VCSN_XML_PRINTERS_HXX
00020 
00021 # include <fstream>
00022 
00023 # include <vaucanson/xml/strings.hh>
00024 # include <vaucanson/xml/tools.hh>
00025 # include <vaucanson/xml/builders.hh>
00026 
00027 # include <vaucanson/xml/internal/ios.hh>
00028 
00029 namespace vcsn
00030 {
00031   namespace xml
00032   {
00033     /*
00034      * Printer class.
00035      */
00036 
00037     Printer::Printer ()
00038     {
00039     };
00040 
00041     Printer::~Printer ()
00042     {
00043     }
00044 
00045     /*
00046      * AutPrinter class.
00047      */
00048     template <typename Auto>
00049     AutPrinter<Auto>::AutPrinter (const Auto& aut, const std::string& name)
00050       : aut_(aut), name_(name)
00051     {
00052     }
00053 
00054     template <typename Auto>
00055     AutPrinter<Auto>::~AutPrinter ()
00056     {
00057     }
00058 
00059     template <typename Auto>
00060     void
00061     AutPrinter<Auto>::print (std::ostream& out)
00062     {
00063       AUTOMATON_TYPES(Auto);
00064       using namespace xercesc;
00065 
00066       state2str_.clear();
00067 
00068       // Document creation.
00069       impl_ = DOMImplementationRegistry::getDOMImplementation(transcode("LS"));
00070       doc_ = impl_->createDocument(transcode(VCSN_XMLNS),
00071                                    transcode("fsmxml"), 0);
00072       root_ = doc_->getDocumentElement();
00073 
00074       tools::set_attribute(root_, "version", "1.0"); // FIXME should be... a macro?
00075 
00076       DOMElement* automaton = tools::create_element(doc_, "automaton");
00077       root_->appendChild(automaton);
00078       tools::set_attribute(automaton, "name", aut_.geometry().name());
00079 
00080       DOMElement* valueType = tools::create_element(doc_, "valueType");
00081       automaton->appendChild(valueType);
00082       builders::create_type_writingData_node(aut_, doc_, valueType);
00083       builders::create_semiring_node(aut_, doc_, valueType);
00084       builders::create_monoid_node(aut_, doc_, valueType);
00085 
00086       DOMElement* content = tools::create_element(doc_, "automatonStruct");
00087       automaton->appendChild(content);
00088 
00089       // Create states.
00090       DOMElement* node = tools::create_element(doc_, "states");
00091       content->appendChild(node);
00092       for_all_states(s, aut_)
00093         state2str_[*s] = create_state(*s, node);
00094 
00095       // Create transitions.
00096       node = tools::create_element(doc_, "transitions");
00097       content->appendChild(node);
00098       for_all_transitions(e, aut_)
00099         create_transition(*e, node);
00100 
00101       // Create initial transitions.
00102       for_all_initial_states(i, aut_)
00103         create_initial(*i, node);
00104 
00105       // Create final transitions.
00106       for_all_final_states(f, aut_)
00107         create_final(*f, node);
00108 
00109       // Print it!
00110       print_xml(out, impl_, root_);
00111       out << std::endl;
00112 
00113       delete doc_;
00114     }
00115 
00116     template <class Auto>
00117     void
00118     AutPrinter<Auto>::create_geometry(hstate_t& key,
00119                         xercesc::DOMElement* root)
00120     {
00121       typedef typename Auto::geometry_t::states_geometry_map_t gmap_t;
00122       typename gmap_t::const_iterator iter;
00123       gmap_t map = aut_.geometry().states();
00124       if ((iter = map.find(key)) != map.end())
00125       {
00126         std::ostringstream osx, osy;
00127         osx << iter->second.first;
00128         xercesc::DOMElement* nd = tools::create_element(doc_, "geometricData");
00129         root->appendChild(nd);
00130         tools::set_attribute(nd, "x", osx.str());
00131         osy << iter->second.second;
00132         tools::set_attribute(nd, "y", osy.str());
00133       }
00134     }
00135 
00136     template <class Auto>
00137     std::string
00138     AutPrinter<Auto>::create_state(hstate_t s,
00139                                    xercesc::DOMElement* root)
00140     {
00141       xercesc::DOMElement* node = tools::create_element(doc_, "state");
00142       root->appendChild(node);
00143       std::ostringstream os;
00144       os << "s" << s;
00145       tools::set_attribute(node, "id", os.str());
00146       create_geometry(s, node);
00147       return os.str();
00148     }
00149 
00150     template <class Auto>
00151     void
00152     AutPrinter<Auto>::create_transition(htransition_t e,
00153                                         xercesc::DOMElement* root)
00154     {
00155       xercesc::DOMElement* node = tools::create_element(doc_, "transition");
00156       root->appendChild(node);
00157       tools::set_attribute(node, "source", state2str_[aut_.src_of(e)]);
00158       tools::set_attribute(node, "target", state2str_[aut_.dst_of(e)]);
00159       builders::create_regexp_node(aut_.series_of(e), doc_, node);
00160     }
00161     template <class Auto>
00162     void
00163     AutPrinter<Auto>::create_initial(hstate_t s,
00164                                      xercesc::DOMElement* root)
00165     {
00166       xercesc::DOMElement* node = tools::create_element(doc_, "initial");
00167       root->appendChild(node);
00168       tools::set_attribute(node, "state", state2str_[s]);
00169       typename Auto::series_set_elt_t tmp = aut_.get_initial(s);
00170       if (tmp != algebra::identity_as<typename Auto::series_set_elt_t::value_t>::of(aut_.series()).value())
00171         builders::create_regexp_node(tmp, doc_, node);
00172     }
00173     template <class Auto>
00174     void
00175     AutPrinter<Auto>::create_final(hstate_t s,
00176                                      xercesc::DOMElement* root)
00177     {
00178       xercesc::DOMElement* node = tools::create_element(doc_, "final");
00179       root->appendChild(node);
00180       tools::set_attribute(node, "state", state2str_[s]);
00181       typename Auto::series_set_elt_t tmp = aut_.get_final(s);
00182       if (tmp != algebra::identity_as<typename Auto::series_set_elt_t::value_t>::of(aut_.series()).value())
00183         builders::create_regexp_node(tmp, doc_, node);
00184     }
00185 
00186     /*
00187      * RegExpPrinter class.
00188      */
00189     template <typename RE>
00190     RegExpPrinter<RE>::RegExpPrinter (const RE& regexp, const std::string& name)
00191       : regexp_(regexp), name_(name)
00192     {
00193     }
00194 
00195     template <typename RE>
00196     RegExpPrinter<RE>::~RegExpPrinter ()
00197     {
00198     }
00199 
00200     template <typename RE>
00201     void
00202     RegExpPrinter<RE>::print (std::ostream& out)
00203     {
00204       using namespace xercesc;
00205 
00206       // Document creation.
00207       impl_ = DOMImplementationRegistry::getDOMImplementation(transcode("LS"));
00208       doc_ = impl_->createDocument(transcode(VCSN_XMLNS),
00209                                    transcode("fsmxml"), 0);
00210       root_ = doc_->getDocumentElement();
00211 
00212       tools::set_attribute(root_, "version", "1.0"); // FIXME should be... a macro?
00213 
00214       DOMElement* regexp = tools::create_element(doc_, "regExp");
00215       root_->appendChild(regexp);
00216 
00217       DOMElement* valueType = tools::create_element(doc_, "valueType");
00218       regexp->appendChild(valueType);
00219       builders::create_type_writingData_node(regexp_, doc_, valueType);
00220       builders::create_semiring_node(regexp_, doc_, valueType);
00221       builders::create_monoid_node(regexp_, doc_, valueType);
00222 
00223       builders::create_regexp_node(regexp_, doc_, regexp, "typedRegExp");
00224 
00225       // Print it!
00226       print_xml(out, impl_, root_);
00227       out << std::endl;
00228 
00229       delete doc_;
00230     }
00231 
00232   } // !xml
00233 } // !vcsn
00234 
00235 #endif // !VCSN_XML_PRINTERS_HXX