serialize.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <ctime>
00014 #include <fstream>
00015 #include <sstream>
00016 #include <streambuf>
00017 
00018 #include "zypp/base/Logger.h"
00019 #include "zypp/CapFactory.h"
00020 #include "zypp/Source.h"
00021 #include "zypp/Url.h"
00022 
00023 #include "zypp/ResObject.h"
00024 #include "zypp/detail/ImplConnect.h"
00025 #include "zypp/detail/ResObjectImplIf.h"
00026 #include "zypp/detail/SelectionImplIf.h"
00027 
00028 #include "serialize.h"
00029 #include "xml_escape_parser.hpp"
00030 
00031 using namespace std;
00033 namespace zypp
00034 { 
00035 namespace storage
00036 { 
00037 
00038 std::string xml_escape( const std::string &text )
00039 {
00040   iobind::parser::xml_escape_parser parser;
00041   return parser.escape(text);
00042 }
00043 
00044 std::string xml_tag_enclose( const std::string &text, const std::string &tag, bool escape = false )
00045 {
00046   std::string result;
00047   result += "<" + tag + ">";
00048 
00049   if ( escape)
00050    result += xml_escape(text);
00051   else
00052    result += text;
00053 
00054   result += "</" + tag + ">";
00055   return result;
00056 }
00057 
00064 static std::string translatedTextToXML(const TranslatedText &text, const std::string &tagname)
00065 {
00066   std::set<Locale> locales = text.locales();
00067   //ERR << "locale contains " << locales.size() << " translations" << std::endl;
00068   std::stringstream out;
00069   for ( std::set<Locale>::const_iterator it = locales.begin(); it != locales.end(); ++it)
00070   {
00071     //ERR << "serializing " << (*it).code() << std::endl;
00072     if ( *it == Locale() )
00073       out << "<" << tagname << ">" << xml_escape(text.text(*it)) << "</" << tagname << ">" << std::endl;
00074     else
00075       out << "<" << tagname << " lang=\"" << (*it).code() << "\">" << xml_escape(text.text(*it)) << "</" << tagname << ">" << std::endl;
00076   }
00077   return out.str();
00078 }
00079 
00080 template<class T>
00081 std::string toXML( const T &obj ); //undefined
00082 
00083 template<> 
00084 std::string toXML( const Edition &edition )
00085 {
00086   stringstream out;
00087   // sad the yum guys did not acll it edition
00088   out << "<version ver=\"" << xml_escape(edition.version()) << "\" rel=\"" << xml_escape(edition.release()) << "\"/>";
00089   return out.str();
00090 }
00091 
00092 template<> 
00093 std::string toXML( const Arch &arch )
00094 {
00095   stringstream out;
00096   out << xml_tag_enclose(xml_escape(arch.asString()), "arch");
00097   return out.str();
00098 }
00099 
00100 template<> 
00101 std::string toXML( const Capability &cap )
00102 {
00103   stringstream out;
00104   CapFactory factory;
00105 
00106   out << "<capability kind=\"" << cap.refers() << "\" >" <<  xml_escape(factory.encode(cap)) << "</capability>" << std::endl;
00107   return out.str();
00108 }
00109 
00110 template<> 
00111 std::string toXML( const CapSet &caps )
00112 {
00113   stringstream out;
00114   CapSet::iterator it = caps.begin();
00115   for ( ; it != caps.end(); ++it)
00116   {
00117     out << toXML((*it));
00118   }
00119   return out.str();
00120 }
00121 
00122 template<> 
00123 std::string toXML( const Dependencies &dep )
00124 {
00125   stringstream out;
00126   if ( dep[Dep::PROVIDES].size() > 0 )
00127     out << "    " << xml_tag_enclose(toXML(dep[Dep::PROVIDES]), "provides") << std::endl;
00128   if ( dep[Dep::PREREQUIRES].size() > 0 )
00129     out << "    " << xml_tag_enclose(toXML(dep[Dep::PREREQUIRES]), "prerequires") << std::endl;
00130   if ( dep[Dep::CONFLICTS].size() > 0 )
00131     out << "    " << xml_tag_enclose(toXML(dep[Dep::CONFLICTS]), "conflicts") << std::endl;
00132   if ( dep[Dep::OBSOLETES].size() > 0 )
00133     out << "    " << xml_tag_enclose(toXML(dep[Dep::OBSOLETES]), "obsoletes") << std::endl;
00134   // why the YUM tag is freshen without s????
00135   if ( dep[Dep::FRESHENS].size() > 0 )
00136     out << "    " << xml_tag_enclose(toXML(dep[Dep::FRESHENS]), "freshens") << std::endl;
00137   if ( dep[Dep::REQUIRES].size() > 0 )
00138     out << "    " << xml_tag_enclose(toXML(dep[Dep::REQUIRES]), "requires") << std::endl;  
00139   if ( dep[Dep::RECOMMENDS].size() > 0 )
00140     out << "    " << xml_tag_enclose(toXML(dep[Dep::RECOMMENDS]), "recommends") << std::endl;
00141   if ( dep[Dep::ENHANCES].size() > 0 )
00142     out << "    " << xml_tag_enclose(toXML(dep[Dep::ENHANCES]), "enhances") << std::endl;
00143   if ( dep[Dep::SUPPLEMENTS].size() > 0 )
00144     out << "    " << xml_tag_enclose(toXML(dep[Dep::SUPPLEMENTS]), "supplements") << std::endl;
00145   if ( dep[Dep::SUGGESTS].size() > 0 )
00146     out << "    " << xml_tag_enclose(toXML(dep[Dep::SUGGESTS]), "suggests") << std::endl;
00147   return out.str();
00148 
00149 }
00150 
00151 template<> 
00152 std::string toXML( const Resolvable::constPtr &obj )
00153 {
00154   stringstream out;
00155 
00156   out << "  <name>" << xml_escape(obj->name()) << "</name>" << std::endl;
00157   // is this shared? uh
00158   out << "  " << toXML(obj->edition()) << std::endl;
00159   out << "  " << toXML(obj->arch()) << std::endl;
00160   out << "  " << toXML(obj->deps()) << std::endl;
00161   return out.str();
00162 }
00163 
00164 template<> 
00165 std::string toXML( const Package::constPtr &obj )
00166 {
00167   stringstream out;
00168   out << "<package>" << std::endl;
00169   // reuse Resolvable information serialize function
00170   toXML(static_cast<Resolvable::constPtr>(obj));
00171   //out << "  <do>" << std::endl;
00172   //out << "      " << obj->do_script() << std::endl;
00173   //out << "  </do>" << std::endl;
00174   out << "</package>" << std::endl;
00175   return out.str();
00176 }
00177 
00178 template<> 
00179 std::string toXML( const Script::constPtr &obj )
00180 {
00181   stringstream out;
00182   out << "<script>" << std::endl;
00183   // reuse Resolvable information serialize function
00184   out << toXML(static_cast<Resolvable::constPtr>(obj));
00185   out << "  <do>" << std::endl;
00186   out << "  <![CDATA[" << std::endl;
00187   
00188   // read script
00189   ifstream infile;
00190   infile.open(obj->do_script().asString().c_str());
00191   while (infile.good())
00192   {
00193     char c = (char)infile.get();
00194     if (! infile.eof())
00195       out << c;
00196   }
00197   infile.close();
00198   
00199   out << "  ]]>" << std::endl;
00200   out << "  </do>" << std::endl;
00201 
00202   if ( obj->undo_available() )
00203   {
00204     out << "  <undo>" << std::endl;
00205     out << "  <![CDATA[" << std::endl;
00206   
00207   // read script
00208     infile.open(obj->undo_script().asString().c_str());
00209     while (infile.good())
00210     {
00211       char c = (char)infile.get();
00212       if (! infile.eof())
00213         out << c;
00214     }
00215     infile.close();
00216   
00217     out << "  ]]>" << std::endl;
00218     out << "  </undo>" << std::endl;
00219 
00220   }
00221   out << "</script>" << std::endl;
00222   return out.str();
00223 }
00224 
00225 template<> 
00226 std::string toXML( const Message::constPtr &obj )
00227 {
00228   stringstream out;
00229   out << "<message>" << std::endl;
00230   // reuse Resolvable information serialize function
00231   out << toXML(static_cast<Resolvable::constPtr>(obj));
00232   out << "  <text>" << xml_escape(obj->text().text()) << "</text>" << std::endl;
00233   out << "</message>" << std::endl;
00234   return out.str();
00235 }
00236 
00237 template<> 
00238 std::string toXML( const Language::constPtr &obj )
00239 {
00240   stringstream out;
00241   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00242   out << "<language xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl;
00243   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00244   out << "</language>" << std::endl;
00245   return out.str();
00246 }
00247 
00248 
00249 template<> 
00250 std::string toXML( const Selection::constPtr &obj )
00251 {
00252   stringstream out;
00253   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00254   out << "<pattern xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl;
00255   
00256   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00257 
00258   // access implementation
00259   detail::ResImplTraits<Selection::Impl>::constPtr sipp( detail::ImplConnect::resimpl( obj ) );
00260   out << translatedTextToXML(sipp->summary(), "summary");
00261   out << translatedTextToXML(sipp->description(), "description");
00262   //out << "  <default>" << (obj->isDefault() ? "true" : "false" ) << "</default>" << std::endl;
00263   out << "  <uservisible>" << (obj->visible() ? "true" : "false" ) << "</uservisible>" << std::endl;
00264   out << "  <category>" << xml_escape(obj->category()) << "</category>" << std::endl;
00265   out << "  <icon></icon>" << std::endl;
00266   out << "</pattern>" << std::endl;
00267   return out.str();
00268 }
00269 
00270 template<> 
00271 std::string toXML( const Atom::constPtr &obj )
00272 {
00273   stringstream out;
00274   out << "<atom>" << std::endl;
00275   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00276   out << "</atom>" << std::endl;
00277   return out.str();
00278 }
00279 
00280 template<> 
00281 std::string toXML( const Pattern::constPtr &obj )
00282 {
00283   stringstream out;
00284   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00285   out << "<pattern xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl;
00286 
00287   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00288 
00289   // access implementation
00290   detail::ResImplTraits<Pattern::Impl>::constPtr pipp( detail::ImplConnect::resimpl( obj ) );
00291   out << translatedTextToXML(pipp->summary(), "summary");
00292   out << translatedTextToXML(pipp->description(), "description");
00293   
00294   out << "  <default>" << (obj->isDefault() ? "true" : "false" ) << "</default>" << std::endl;
00295   out << "  <uservisible>" << (obj->userVisible() ? "true" : "false" ) << "</uservisible>" << std::endl;
00296   out << "  <category>" << xml_escape(obj->category()) << "</category>" << std::endl;
00297   out << "  <icon>" << xml_escape(obj->icon().asString()) << "</icon>" << std::endl;
00298   out << "  <script>" << xml_escape(obj->script().asString()) << "</script>" << std::endl;
00299   out << "</pattern>" << std::endl;
00300   return out.str();
00301 }
00302 
00303 template<> 
00304 std::string toXML( const Product::constPtr &obj )
00305 {
00306   stringstream out;
00307   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00308   out << "<product xmlns=\"http://www.novell.com/metadata/zypp/xml-store\" type=\"" << xml_escape(obj->category()) << "\">" << std::endl;
00309   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00310   #warning "FIXME description and displayname of products"
00311   
00312   // access implementation
00313   detail::ResImplTraits<Product::Impl>::constPtr pipp( detail::ImplConnect::resimpl( obj ) );
00314   out << translatedTextToXML(pipp->summary(), "summary");
00315   out << translatedTextToXML(pipp->description(), "description");
00316   out << translatedTextToXML(pipp->shortName(), "shortname");
00317   
00318   out << "  <vendor>" << xml_escape(obj->vendor()) << "</vendor>" << std::endl;
00319   out << "  <source>" << xml_escape(obj->source().alias()) << "</source>" << std::endl;  
00320   out << "  <release-notes-url>" << xml_escape(obj->releaseNotesUrl().asString()) << "</release-notes-url>" << std::endl;
00321   out << "  <update-urls>" << std::endl;
00322   std::list<Url> updateUrls = obj->updateUrls();
00323   for ( std::list<Url>::const_iterator it = updateUrls.begin(); it != updateUrls.end(); ++it)
00324   {
00325     out << "    <update-url>" << xml_escape(it->asString()) << "</update-url>" << std::endl; 
00326   }
00327   out << "  </update-urls>" << std::endl;
00328   out << "  <product-flags>" << std::endl;
00329   std::list<std::string> flags = obj->flags();
00330   for ( std::list<std::string>::const_iterator it = flags.begin(); it != flags.end(); ++it)
00331   {
00332     out << "    <product-flag>" << xml_escape(*it) << "</product-flag>" << std::endl; 
00333   }
00334   out << "  </product-flags>" << std::endl;
00335   
00336   out << "</product>" << std::endl;
00337 
00338   return out.str();
00339 }
00340 
00341 
00342 std::string castedToXML( const Resolvable::constPtr &resolvable )
00343 {
00344   stringstream out;
00345   if ( isKind<Package>(resolvable) )
00346      out << toXML(asKind<const Package>(resolvable)) << std::endl;
00347   if ( isKind<Patch>(resolvable) )
00348      out << toXML(asKind<const Patch>(resolvable)) << std::endl;
00349   if ( isKind<Message>(resolvable) )
00350      out << toXML(asKind<const Message>(resolvable)) << std::endl;
00351   if ( isKind<Script>(resolvable) )
00352      out << toXML(asKind<const Script>(resolvable)) << std::endl;
00353   if ( isKind<Atom>(resolvable) )
00354      out << toXML(asKind<const Atom>(resolvable)) << std::endl;
00355   if ( isKind<Product>(resolvable) )
00356      out << toXML(asKind<const Product>(resolvable)) << std::endl;
00357   if ( isKind<Pattern>(resolvable) )
00358      out << toXML(asKind<const Pattern>(resolvable)) << std::endl;
00359   if ( isKind<Selection>(resolvable) )
00360      out << toXML(asKind<const Selection>(resolvable)) << std::endl;
00361   if ( isKind<Language>(resolvable) )
00362     out << toXML(asKind<const Language>(resolvable)) << std::endl;
00363   return out.str();
00364 }
00365 
00366 std::string resolvableTypeToString( const Resolvable::constPtr &resolvable, bool plural )
00367 {
00368   return resolvableKindToString(resolvable->kind(), plural);
00369 }
00370 
00371 std::string resolvableKindToString( const Resolvable::Kind &kind, bool plural)
00372 {
00373   std::string k = kind.asString();
00374   if (k.substr(k.size() - 2, 2) == "ch")
00375     return k + (plural?"es":"");
00376   else
00377     return k + (plural?"s":"");
00378 }
00379 
00380 template<> 
00381 std::string toXML( const Patch::constPtr &obj )
00382 {
00383   stringstream out;
00384   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00385   out << "<patch xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl; 
00386   
00387   // reuse Resolvable information serialize function
00388   out << toXML(static_cast<Resolvable::constPtr>(obj));
00389   
00390   // access implementation
00391   detail::ResImplTraits<Patch::Impl>::constPtr pipp( detail::ImplConnect::resimpl( obj ) );
00392   out << translatedTextToXML(pipp->summary(), "summary");
00393   out << translatedTextToXML(pipp->description(), "description");
00394   
00395   out << "<id>" << xml_escape(obj->id()) << "</id>" << std::endl;
00396   out << "<timestamp>" << obj->timestamp().asSeconds() << "</timestamp>" << std::endl;
00397   
00398   out << "<category>" << obj->category() << "</category>" << std::endl;
00399   out << "<affects-package-manager>" << ( obj->affects_pkg_manager() ? "true" : "false" ) << "</affects-package-manager>" << std::endl;
00400   out << "<reboot-needed>" << ( obj->reboot_needed() ? "true" : "false" ) << "</reboot-needed>" << std::endl;
00401   out << "<interactive>" << ( obj->interactive() ? "true" : "false" ) << "</interactive>" << std::endl;
00402   
00403   Patch::AtomList at = obj->atoms();
00404   out << "  <atoms>" << std::endl;
00405   for (Patch::AtomList::iterator it = at.begin(); it != at.end(); it++)
00406   {
00407     Resolvable::Ptr one_atom = *it;
00408     out << castedToXML(one_atom) << std::endl;
00409   }
00410   out << "  </atoms>" << std::endl;
00411   out << "</patch>" << std::endl;
00412   return out.str();
00413 }
00414 
00415 template<> 
00416 std::string toXML( const PersistentStorage::SourceData &obj )
00417 {
00418   stringstream out;
00419   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00420   out << "<source  xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl;
00421   out << "  <enabled>" << (obj.enabled ? "true" : "false" ) << "</enabled>" << std::endl;
00422   out << "  <auto-refresh>" << ( obj.autorefresh ? "true" : "false" ) << "</auto-refresh>" << std::endl;
00423   out << "  <product-dir>" << obj.product_dir << "</product-dir>" << std::endl;
00424   out << "  <cache-dir>" << obj.cache_dir << "</cache-dir>" << std::endl;
00425   out << "  <type>" << xml_escape(obj.type) << "</type>" << std::endl;
00426   out << "  <url>" << xml_escape(obj.url.asString()) << "</url>" << std::endl;
00427   out << "  <alias>" << xml_escape(obj.alias) << "</alias>" << std::endl;
00428   out << "</source>" << std::endl;
00429   return out.str();
00430 }
00431 
00433 } // namespace storage
00436 } // namespace zypp

Generated on Thu May 4 16:03:30 2006 for zypp by  doxygen 1.4.6