document.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 "document.h" 00024 #include "dublincore.h" 00025 #include "image.h" 00026 #include "item.h" 00027 #include "model.h" 00028 #include "model_p.h" 00029 #include "resource.h" 00030 #include "rssvocab.h" 00031 #include "sequence.h" 00032 #include "statement.h" 00033 #include "syndicationinfo.h" 00034 #include "textinput.h" 00035 00036 #include <documentvisitor.h> 00037 #include <tools.h> 00038 00039 #include <QtCore/QList> 00040 #include <QtCore/QString> 00041 00042 using namespace boost; 00043 00044 namespace Syndication { 00045 namespace RDF { 00046 00047 class Document::Private 00048 { 00049 public: 00050 Private() : itemTitleContainsMarkup(false), 00051 itemTitlesGuessed(false), 00052 itemDescriptionContainsMarkup(false), 00053 itemDescGuessed(false) 00054 {} 00055 mutable bool itemTitleContainsMarkup; 00056 mutable bool itemTitlesGuessed; 00057 mutable bool itemDescriptionContainsMarkup; 00058 mutable bool itemDescGuessed; 00059 shared_ptr<Model::ModelPrivate> modelPrivate; 00060 }; 00061 00062 Document::Document() : Syndication::SpecificDocument(), 00063 ResourceWrapper(), 00064 d(new Private) 00065 { 00066 d->modelPrivate = resource()->model().d; 00067 } 00068 00069 Document::Document(ResourcePtr resource) : Syndication::SpecificDocument(), 00070 ResourceWrapper(resource), 00071 d(new Private) 00072 { 00073 d->modelPrivate = resource->model().d; 00074 } 00075 00076 Document::Document(const Document& other) : SpecificDocument(other), ResourceWrapper(other), 00077 d(new Private) 00078 { 00079 *d = *(other.d); 00080 } 00081 00082 Document::~Document() 00083 { 00084 delete d; 00085 } 00086 00087 00088 bool Document::operator==(const Document& other) const 00089 { 00090 return ResourceWrapper::operator==(other); 00091 } 00092 00093 00094 Document& Document::operator=(const Document& other) 00095 { 00096 ResourceWrapper::operator=(other); 00097 *d = *(other.d); 00098 00099 return *this; 00100 } 00101 00102 00103 bool Document::accept(DocumentVisitor* visitor) 00104 { 00105 return visitor->visitRDFDocument(this); 00106 } 00107 00108 bool Document::isValid() const 00109 { 00110 return !isNull(); 00111 } 00112 00113 QString Document::title() const 00114 { 00115 QString str = resource()->property(RSSVocab::self()->title())->asString(); 00116 return normalize(str); 00117 00118 } 00119 00120 QString Document::description() const 00121 { 00122 QString str = resource()->property(RSSVocab::self()->description())->asString(); 00123 return normalize(str); 00124 } 00125 00126 QString Document::link() const 00127 { 00128 return resource()->property(RSSVocab::self()->link())->asString(); 00129 } 00130 00131 DublinCore Document::dc() const 00132 { 00133 return DublinCore(resource()); 00134 } 00135 00136 SyndicationInfo Document::syn() const 00137 { 00138 return SyndicationInfo(resource()); 00139 } 00140 00141 QList<Item> Document::items() const 00142 { 00143 QList<Item> list; 00144 if (!resource()->hasProperty(RSSVocab::self()->items())) 00145 return list; 00146 00147 NodePtr n = resource()->property(RSSVocab::self()->items())->object(); 00148 if (n->isSequence()) 00149 { 00150 Sequence* seq = static_cast<Sequence*>(n.get()); 00151 00152 const QList<NodePtr> items = seq->items(); 00153 QList<NodePtr>::ConstIterator it = items.begin(); 00154 QList<NodePtr>::ConstIterator end = items.end(); 00155 00156 DocumentPtr doccpy(new Document(*this)); 00157 00158 for ( ; it != end; ++it) 00159 { 00160 if ((*it)->isResource()) 00161 { 00162 // well, we need it as ResourcePtr 00163 // maybe this should go to the node 00164 // interface ResourcePtr asResource()? 00165 ResourcePtr ptr = resource()->model().createResource((static_cast<Resource*>((*it).get()))->uri()); 00166 00167 list.append(Item(ptr, doccpy)); 00168 } 00169 } 00170 00171 } 00172 return list; 00173 } 00174 00175 Image Document::image() const 00176 { 00177 ResourcePtr img = resource()->property(RSSVocab::self()->image())->asResource(); 00178 00179 return img ? Image(img) : Image(); 00180 } 00181 00182 TextInput Document::textInput() const 00183 { 00184 ResourcePtr ti = resource()->property(RSSVocab::self()->textinput())->asResource(); 00185 00186 return ti ? TextInput(ti) : TextInput(); 00187 } 00188 00189 void Document::getItemTitleFormatInfo(bool* containsMarkup) const 00190 { 00191 if (!d->itemTitlesGuessed) 00192 { 00193 QString titles; 00194 QList<Item> litems = items(); 00195 00196 if (litems.isEmpty()) 00197 { 00198 d->itemTitlesGuessed = true; 00199 return; 00200 } 00201 00202 int nmax = litems.size() < 10 ? litems.size() : 10; // we check a maximum of 10 items 00203 int i = 0; 00204 00205 QList<Item>::ConstIterator it = litems.constBegin(); 00206 00207 while (i < nmax) 00208 { 00209 titles += (*it).originalTitle(); 00210 ++it; 00211 ++i; 00212 } 00213 00214 d->itemTitleContainsMarkup = stringContainsMarkup(titles); 00215 d->itemTitlesGuessed = true; 00216 } 00217 if (containsMarkup != 0L) 00218 *containsMarkup = d->itemTitleContainsMarkup; 00219 } 00220 00221 void Document::getItemDescriptionFormatInfo(bool* containsMarkup) const 00222 { 00223 if (!d->itemDescGuessed) 00224 { 00225 QString desc; 00226 QList<Item> litems = items(); 00227 00228 00229 if (litems.isEmpty()) 00230 { 00231 d->itemDescGuessed = true; 00232 return; 00233 } 00234 00235 int nmax = litems.size() < 10 ? litems.size() : 10; // we check a maximum of 10 items 00236 int i = 0; 00237 00238 QList<Item>::ConstIterator it = litems.constBegin(); 00239 00240 while (i < nmax) 00241 { 00242 desc += (*it).originalDescription(); 00243 ++it; 00244 ++i; 00245 } 00246 00247 d->itemDescriptionContainsMarkup = stringContainsMarkup(desc); 00248 d->itemDescGuessed = true; 00249 } 00250 00251 if (containsMarkup != 0L) 00252 *containsMarkup = d->itemDescriptionContainsMarkup; 00253 } 00254 00255 QString Document::debugInfo() const 00256 { 00257 QString info; 00258 info += QLatin1String("### Document: ###################\n"); 00259 info += QLatin1String("title: #") + title() + QLatin1String("#\n"); 00260 info += QLatin1String("link: #") + link() + QLatin1String("#\n"); 00261 info += QLatin1String("description: #") + description() + QLatin1String("#\n"); 00262 info += dc().debugInfo(); 00263 info += syn().debugInfo(); 00264 Image img = image(); 00265 if (!img.resource() == 0L) 00266 info += img.debugInfo(); 00267 TextInput input = textInput(); 00268 if (!input.isNull()) 00269 info += input.debugInfo(); 00270 00271 QList<Item> itlist = items(); 00272 QList<Item>::ConstIterator it = itlist.constBegin(); 00273 QList<Item>::ConstIterator end = itlist.constEnd(); 00274 for ( ; it != end; ++it) 00275 info += (*it).debugInfo(); 00276 00277 00278 info += QLatin1String("### Document end ################\n"); 00279 return info; 00280 } 00281 00282 } // namespace RDF 00283 } // namespace Syndication