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 ResObject::constPtr &obj )
00166 {
00167   stringstream out;
00168 
00169   // access implementation
00170   detail::ResImplTraits<ResObject::Impl>::constPtr pipp( detail::ImplConnect::resimpl( obj ) );
00171   out << translatedTextToXML(pipp->summary(), "summary");
00172   out << translatedTextToXML(pipp->description(), "description");
00173   
00174   out << translatedTextToXML(pipp->insnotify(), "install-notify");
00175   out << translatedTextToXML(pipp->delnotify(), "delete-notify");
00176   //out << "  <license-to-confirm>" << xml_escape(obj->licenseToConfirm()) << "</license-to-confirm>" << std::endl;
00177   out << translatedTextToXML(pipp->licenseToConfirm(), "license-to-confirm");
00178   out << "  <vendor>" << xml_escape(obj->vendor()) << "</vendor>" << std::endl;
00179   out << "  <size>" << obj->size() << "</size>" << std::endl;
00180   out << "  <archive-size>" << obj->archivesize() << "</archive-size>" << std::endl;
00181   out << "  <install-only>" << ( obj->installOnly() ? "true" : "false" ) << "</install-only>" << std::endl;
00182   out << "  <build-time>" << obj->buildtime().asSeconds() << "</build-time>" << std::endl;
00183   // we assume we serialize on storeObject, set install time to NOW
00184   out << "  <install-time>" << Date::now() << "</install-time>" << std::endl;
00185   
00186   return out.str();
00187 }
00188 
00189 template<> 
00190 std::string toXML( const Package::constPtr &obj )
00191 {
00192   stringstream out;
00193   out << "<package>" << std::endl;
00194   // reuse Resolvable information serialize function
00195   out << toXML(static_cast<Resolvable::constPtr>(obj));
00196   out << toXML(static_cast<ResObject::constPtr>(obj));
00197   //out << "  <do>" << std::endl;
00198   //out << "      " << obj->do_script() << std::endl;
00199   //out << "  </do>" << std::endl;
00200   out << "</package>" << std::endl;
00201   return out.str();
00202 }
00203 
00204 template<> 
00205 std::string toXML( const Script::constPtr &obj )
00206 {
00207   stringstream out;
00208   out << "<script>" << std::endl;
00209   // reuse Resolvable information serialize function
00210   out << toXML(static_cast<Resolvable::constPtr>(obj));
00211   out << toXML(static_cast<ResObject::constPtr>(obj));
00212   out << "  <do>" << std::endl;
00213   out << "  <![CDATA[" << std::endl;
00214   
00215   // read script
00216   ifstream infile;
00217   infile.open(obj->do_script().asString().c_str());
00218   while (infile.good())
00219   {
00220     char c = (char)infile.get();
00221     if (! infile.eof())
00222       out << c;
00223   }
00224   infile.close();
00225   
00226   out << "  ]]>" << std::endl;
00227   out << "  </do>" << std::endl;
00228 
00229   if ( obj->undo_available() )
00230   {
00231     out << "  <undo>" << std::endl;
00232     out << "  <![CDATA[" << std::endl;
00233   
00234   // read script
00235     infile.open(obj->undo_script().asString().c_str());
00236     while (infile.good())
00237     {
00238       char c = (char)infile.get();
00239       if (! infile.eof())
00240         out << c;
00241     }
00242     infile.close();
00243   
00244     out << "  ]]>" << std::endl;
00245     out << "  </undo>" << std::endl;
00246 
00247   }
00248   out << "</script>" << std::endl;
00249   return out.str();
00250 }
00251 
00252 template<> 
00253 std::string toXML( const Message::constPtr &obj )
00254 {
00255   stringstream out;
00256   out << "<message>" << std::endl;
00257   // reuse Resolvable information serialize function
00258   out << toXML(static_cast<Resolvable::constPtr>(obj));
00259   out << toXML(static_cast<ResObject::constPtr>(obj));
00260   out << "  <text>" << xml_escape(obj->text().text()) << "</text>" << std::endl;
00261   out << "</message>" << std::endl;
00262   return out.str();
00263 }
00264 
00265 template<> 
00266 std::string toXML( const Language::constPtr &obj )
00267 {
00268   stringstream out;
00269   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00270   out << "<language xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl;
00271   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00272   out << toXML(static_cast<ResObject::constPtr>(obj));
00273   out << "</language>" << std::endl;
00274   return out.str();
00275 }
00276 
00277 
00278 template<> 
00279 std::string toXML( const Selection::constPtr &obj )
00280 {
00281   stringstream out;
00282   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00283   out << "<pattern xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl;
00284   
00285   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00286   out << toXML(static_cast<ResObject::constPtr>(obj));
00287   
00288   //out << "  <default>" << (obj->isDefault() ? "true" : "false" ) << "</default>" << std::endl;
00289   out << "  <uservisible>" << (obj->visible() ? "true" : "false" ) << "</uservisible>" << std::endl;
00290   out << "  <category>" << xml_escape(obj->category()) << "</category>" << std::endl;
00291   out << "  <icon></icon>" << std::endl;
00292   out << "</pattern>" << std::endl;
00293   return out.str();
00294 }
00295 
00296 template<> 
00297 std::string toXML( const Atom::constPtr &obj )
00298 {
00299   stringstream out;
00300   out << "<atom>" << std::endl;
00301   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00302   out << toXML(static_cast<ResObject::constPtr>(obj));
00303   out << "</atom>" << std::endl;
00304   return out.str();
00305 }
00306 
00307 template<> 
00308 std::string toXML( const Pattern::constPtr &obj )
00309 {
00310   stringstream out;
00311   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00312   out << "<pattern xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl;
00313 
00314   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00315   out << toXML(static_cast<ResObject::constPtr>(obj));
00316   
00317   out << "  <default>" << (obj->isDefault() ? "true" : "false" ) << "</default>" << std::endl;
00318   out << "  <uservisible>" << (obj->userVisible() ? "true" : "false" ) << "</uservisible>" << std::endl;
00319   out << "  <category>" << xml_escape(obj->category()) << "</category>" << std::endl;
00320   out << "  <icon>" << xml_escape(obj->icon().asString()) << "</icon>" << std::endl;
00321   out << "  <script>" << xml_escape(obj->script().asString()) << "</script>" << std::endl;
00322   out << "</pattern>" << std::endl;
00323   return out.str();
00324 }
00325 
00326 template<> 
00327 std::string toXML( const Product::constPtr &obj )
00328 {
00329   stringstream out;
00330   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00331   out << "<product xmlns=\"http://www.novell.com/metadata/zypp/xml-store\" type=\"" << xml_escape(obj->category()) << "\">" << std::endl;
00332   out << toXML(static_cast<Resolvable::constPtr>(obj)) << std::endl;
00333   #warning "FIXME description and displayname of products"
00334   
00335   out << toXML(static_cast<ResObject::constPtr>(obj));
00336   
00337   // access implementation
00338   detail::ResImplTraits<Product::Impl>::constPtr pipp( detail::ImplConnect::resimpl( obj ) );
00339   out << translatedTextToXML(pipp->shortName(), "shortname");
00340   
00341   out << "  <source>" << xml_escape(obj->source().alias()) << "</source>" << std::endl;  
00342   out << "  <release-notes-url>" << xml_escape(obj->releaseNotesUrl().asString()) << "</release-notes-url>" << std::endl;
00343   out << "  <update-urls>" << std::endl;
00344   std::list<Url> updateUrls = obj->updateUrls();
00345   for ( std::list<Url>::const_iterator it = updateUrls.begin(); it != updateUrls.end(); ++it)
00346   {
00347     out << "    <update-url>" << xml_escape(it->asString()) << "</update-url>" << std::endl; 
00348   }
00349   out << "  </update-urls>" << std::endl;
00350   out << "  <product-flags>" << std::endl;
00351   std::list<std::string> flags = obj->flags();
00352   for ( std::list<std::string>::const_iterator it = flags.begin(); it != flags.end(); ++it)
00353   {
00354     out << "    <product-flag>" << xml_escape(*it) << "</product-flag>" << std::endl; 
00355   }
00356   out << "  </product-flags>" << std::endl;
00357   
00358   out << "</product>" << std::endl;
00359 
00360   return out.str();
00361 }
00362 
00363 
00364 std::string castedToXML( const Resolvable::constPtr &resolvable )
00365 {
00366   stringstream out;
00367   if ( isKind<Package>(resolvable) )
00368      out << toXML(asKind<const Package>(resolvable)) << std::endl;
00369   if ( isKind<Patch>(resolvable) )
00370      out << toXML(asKind<const Patch>(resolvable)) << std::endl;
00371   if ( isKind<Message>(resolvable) )
00372      out << toXML(asKind<const Message>(resolvable)) << std::endl;
00373   if ( isKind<Script>(resolvable) )
00374      out << toXML(asKind<const Script>(resolvable)) << std::endl;
00375   if ( isKind<Atom>(resolvable) )
00376      out << toXML(asKind<const Atom>(resolvable)) << std::endl;
00377   if ( isKind<Product>(resolvable) )
00378      out << toXML(asKind<const Product>(resolvable)) << std::endl;
00379   if ( isKind<Pattern>(resolvable) )
00380      out << toXML(asKind<const Pattern>(resolvable)) << std::endl;
00381   if ( isKind<Selection>(resolvable) )
00382      out << toXML(asKind<const Selection>(resolvable)) << std::endl;
00383   if ( isKind<Language>(resolvable) )
00384     out << toXML(asKind<const Language>(resolvable)) << std::endl;
00385   return out.str();
00386 }
00387 
00388 std::string resolvableTypeToString( const Resolvable::constPtr &resolvable, bool plural )
00389 {
00390   return resolvableKindToString(resolvable->kind(), plural);
00391 }
00392 
00393 std::string resolvableKindToString( const Resolvable::Kind &kind, bool plural)
00394 {
00395   std::string k = kind.asString();
00396   if (k.substr(k.size() - 2, 2) == "ch")
00397     return k + (plural?"es":"");
00398   else
00399     return k + (plural?"s":"");
00400 }
00401 
00402 template<> 
00403 std::string toXML( const Patch::constPtr &obj )
00404 {
00405   stringstream out;
00406   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00407   out << "<patch xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl; 
00408   
00409   // reuse Resolvable information serialize function
00410   out << toXML(static_cast<Resolvable::constPtr>(obj));
00411   out << toXML(static_cast<ResObject::constPtr>(obj));
00412   
00413   out << "<id>" << xml_escape(obj->id()) << "</id>" << std::endl;
00414   out << "<timestamp>" << obj->timestamp().asSeconds() << "</timestamp>" << std::endl;
00415   
00416   out << "<category>" << obj->category() << "</category>" << std::endl;
00417   out << "<affects-package-manager>" << ( obj->affects_pkg_manager() ? "true" : "false" ) << "</affects-package-manager>" << std::endl;
00418   out << "<reboot-needed>" << ( obj->reboot_needed() ? "true" : "false" ) << "</reboot-needed>" << std::endl;
00419   out << "<interactive>" << ( obj->interactive() ? "true" : "false" ) << "</interactive>" << std::endl;
00420   
00421   Patch::AtomList at = obj->atoms();
00422   out << "  <atoms>" << std::endl;
00423   for (Patch::AtomList::iterator it = at.begin(); it != at.end(); it++)
00424   {
00425     Resolvable::Ptr one_atom = *it;
00426     out << castedToXML(one_atom) << std::endl;
00427   }
00428   out << "  </atoms>" << std::endl;
00429   out << "</patch>" << std::endl;
00430   return out.str();
00431 }
00432 
00433 template<> 
00434 std::string toXML( const PersistentStorage::SourceData &obj )
00435 {
00436   stringstream out;
00437   out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00438   out << "<source  xmlns=\"http://www.novell.com/metadata/zypp/xml-store\">" << std::endl;
00439   out << "  <enabled>" << (obj.enabled ? "true" : "false" ) << "</enabled>" << std::endl;
00440   out << "  <auto-refresh>" << ( obj.autorefresh ? "true" : "false" ) << "</auto-refresh>" << std::endl;
00441   out << "  <product-dir>" << obj.product_dir << "</product-dir>" << std::endl;
00442   out << "  <cache-dir>" << obj.cache_dir << "</cache-dir>" << std::endl;
00443   out << "  <type>" << xml_escape(obj.type) << "</type>" << std::endl;
00444   out << "  <url>" << xml_escape(obj.url.asCompleteString()) << "</url>" << std::endl;
00445   out << "  <alias>" << xml_escape(obj.alias) << "</alias>" << std::endl;
00446   out << "</source>" << std::endl;
00447   return out.str();
00448 }
00449 
00451 } // namespace storage
00454 } // namespace zypp

Generated on Thu Jul 6 00:07:26 2006 for zypp by  doxygen 1.4.6