• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • Contact Us
 

syndication/rdf

parser.cpp
00001 /*
00002  * This file is part of the syndication library
00003  *
00004  * Copyright (C) 2006 Frank Osterfeld <osterfeld@kde.org>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Library General Public License
00017  * along with this library; see the file COPYING.LIB.  If not, write to
00018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "parser.h"
00024 #include "document.h"
00025 #include "model.h"
00026 #include "modelmaker.h"
00027 #include "property.h"
00028 #include "rdfvocab.h"
00029 #include "resource.h"
00030 #include "rssvocab.h"
00031 #include "statement.h"
00032 
00033 #include <documentsource.h>
00034 
00035 #include <QtXml/QDomDocument>
00036 #include <QtXml/QDomNodeList>
00037 #include <QtCore/QHash>
00038 #include <QtCore/QList>
00039 #include <QtCore/QMap>
00040 #include <QtCore/QString>
00041 #include <QtCore/QStringList>
00042 
00043 namespace Syndication {
00044 namespace RDF {
00045 
00046 class Parser::ParserPrivate
00047 {
00048     public:
00049     QDomDocument addEnumeration(const QDomDocument& doc); 
00050     void map09to10(Model model);
00051     void addSequenceFor09(Model model);
00052     
00053     QString strInternalNs;
00054     QString strItemIndex;
00055 };
00056 
00057 bool Parser::accept(const DocumentSource& source) const
00058 {
00059     QDomDocument doc = source.asDomDocument();
00060     
00061     if (doc.isNull())
00062         return false;
00063     QDomElement root = doc.documentElement();
00064     
00065     if (!root.isElement())
00066         return false;
00067     
00068     return root.namespaceURI() == RDFVocab::self()->namespaceURI();
00069 }
00070 
00071 SpecificDocumentPtr Parser::parse(const DocumentSource& source) const
00072 {
00073     QDomDocument doc = source.asDomDocument();
00074     
00075     if (doc.isNull())
00076         return Syndication::SpecificDocumentPtr(new Document());
00077     
00078     doc = d->addEnumeration(doc);
00079     
00080     ModelMaker maker;
00081     Model model = maker.createFromXML(doc);
00082     
00083     bool is09 = !model.resourcesWithType(RSS09Vocab::self()->channel()).isEmpty();
00084     
00085     if (is09)
00086     {
00087         d->map09to10(model);
00088         d->addSequenceFor09(model);
00089     }
00090     
00091     QList<ResourcePtr> channels = model.resourcesWithType(RSSVocab::self()->channel());
00092     
00093     if (channels.isEmpty())
00094         return Syndication::SpecificDocumentPtr(new Document());
00095   
00096     return DocumentPtr(new Document(*(channels.begin())));
00097 }
00098 
00099 QDomDocument Parser::ParserPrivate::addEnumeration(const QDomDocument& docp)
00100 {
00101     QDomDocument doc(docp);
00102     
00103     QDomNodeList list = doc.elementsByTagNameNS(RSS09Vocab::self()->namespaceURI(),
00104             QLatin1String("item"));
00105     
00106     for (int i = 0; i < list.size(); ++i)
00107     {
00108         QDomElement item = list.item(i).toElement();
00109         if (!item.isNull())
00110         {
00111             QDomElement ie = doc.createElementNS(strInternalNs, strItemIndex);
00112             item.appendChild(ie);
00113             ie.appendChild(doc.createTextNode(QString::number(i)));
00114             
00115         }
00116     }
00117     
00118     return doc;
00119 }
00120 
00121 void Parser::ParserPrivate::map09to10(Model model)
00122 {
00123     QHash<QString, PropertyPtr> hash;
00124     
00125     hash.insert(RSS09Vocab::self()->title()->uri(), RSSVocab::self()->title());
00126     hash.insert(RSS09Vocab::self()->description()->uri(), RSSVocab::self()->description());
00127     hash.insert(RSS09Vocab::self()->link()->uri(), RSSVocab::self()->link());
00128     hash.insert(RSS09Vocab::self()->name()->uri(), RSSVocab::self()->name());
00129     hash.insert(RSS09Vocab::self()->url()->uri(), RSSVocab::self()->url());
00130     hash.insert(RSS09Vocab::self()->image()->uri(), RSSVocab::self()->image());
00131     hash.insert(RSS09Vocab::self()->textinput()->uri(), RSSVocab::self()->textinput());
00132     
00133     QStringList uris09 = RSS09Vocab::self()->properties();
00134     
00135     // map statement predicates to RSS 1.0
00136     
00137     QList<StatementPtr> statements = model.statements();
00138     QList<StatementPtr>::ConstIterator it = statements.constBegin();
00139     QList<StatementPtr>::ConstIterator end = statements.constEnd();
00140     
00141     for ( ; it != end; ++it)
00142     {
00143         StatementPtr stmt = *it;
00144         
00145         QString predUri = stmt->predicate()->uri();
00146         if (uris09.contains(predUri))
00147         {
00148             model.addStatement(stmt->subject(), hash[predUri], stmt->object());
00149         }
00150     }
00151     // map channel type
00152     QList<ResourcePtr> channels = model.resourcesWithType(RSS09Vocab::self()->channel());
00153     
00154     ResourcePtr channel;
00155     
00156     if (!channels.isEmpty())
00157     {
00158         channel = *(channels.begin());
00159         
00160         model.removeStatement(channel, RDFVocab::self()->type(), RSS09Vocab::self()->channel());
00161         model.addStatement(channel, RDFVocab::self()->type(), RSSVocab::self()->channel());
00162     }
00163 }
00164 
00165 void Parser::ParserPrivate::addSequenceFor09(Model model)
00166 {
00167     const QList<ResourcePtr> items = model.resourcesWithType(RSS09Vocab::self()->item());
00168     
00169     if (items.isEmpty())
00170         return;
00171     
00172     const QList<ResourcePtr> channels = model.resourcesWithType(RSSVocab::self()->channel());
00173     
00174     if (channels.isEmpty())
00175         return;
00176     
00177     PropertyPtr itemIndex = model.createProperty(strInternalNs + strItemIndex);
00178     
00179     // use QMap here, not QHash. as we need the sorting functionality 
00180     QMap<uint, ResourcePtr> sorted;
00181     
00182     foreach (const ResourcePtr &i, items)
00183     {
00184         QString numstr = i->property(itemIndex)->asString();
00185         bool ok = false;
00186         uint num = numstr.toUInt(&ok);
00187         if (ok)
00188         {
00189             sorted[num] = i;
00190         }
00191     }
00192     
00193     SequencePtr seq = model.createSequence();
00194     model.addStatement(channels.first(), RSSVocab::self()->items(), seq);
00195         
00196     foreach (const ResourcePtr &i, sorted)
00197     {
00198         seq->append(i);
00199         model.addStatement(seq, RDFVocab::self()->li(), i);
00200     }
00201 }
00202 
00203 Parser::Parser() : d(new ParserPrivate)
00204 {
00205     d->strInternalNs = QLatin1String("http://akregator.sf.net/libsyndication/internal#");
00206     d->strItemIndex = QLatin1String("itemIndex");
00207 }
00208 
00209 Parser::~Parser() 
00210 {
00211     delete d;
00212 }
00213 
00214 Parser::Parser(const Parser& other) : AbstractParser(other), d(0) {}
00215 Parser& Parser::operator=(const Parser& /*other*/) { return *this; }
00216        
00217 QString Parser::format() const
00218 {
00219     return QLatin1String("rdf");
00220 }
00221 
00222         
00223 } // namespace RDF
00224 } // namespace Syndication

syndication/rdf

Skip menu "syndication/rdf"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal