Warning, file /office/calligra/libs/text/KoTextRdfCore.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 2010 KO GmbH <ben.martin@kogmbh.com> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "KoTextRdfCore.h" 0021 0022 #include "TextDebug.h" 0023 #include <KoStoreDevice.h> 0024 #include <KoXmlWriter.h> 0025 #include <QFile> 0026 0027 using namespace Soprano; 0028 0029 bool KoTextRdfCore::saveRdf( QSharedPointer<Soprano::Model> model, Soprano::StatementIterator triples, KoStore *store, KoXmlWriter *manifestWriter, const QString &fileName) 0030 { 0031 bool ok = false; 0032 0033 if (! store->open(fileName)) { 0034 return false; 0035 } 0036 0037 KoStoreDevice dev(store); 0038 QTextStream oss(&dev); 0039 0040 QString serialization = "application/rdf+xml"; 0041 const Soprano::Serializer* serializer 0042 = Soprano::PluginManager::instance()->discoverSerializerForSerialization( 0043 Soprano::SerializationRdfXml); 0044 0045 if (serializer) { 0046 QString data; 0047 QTextStream tss(&data); 0048 if (serializer->serialize(triples, tss, Soprano::SerializationRdfXml)) { 0049 tss.flush(); 0050 oss << data; 0051 debugText << "fileName:" << fileName << " data.sz:" << data.size(); 0052 debugText << "model.sz:" << model->statementCount(); 0053 ok = true; 0054 } else { 0055 debugText << "serialization of Rdf failed!"; 0056 } 0057 } 0058 oss.flush(); 0059 store->close(); 0060 manifestWriter->addManifestEntry(fileName, "application/rdf+xml"); 0061 return ok; 0062 } 0063 0064 bool KoTextRdfCore::createAndSaveManifest(QSharedPointer<Soprano::Model> docmodel, const QMap<QString, QString> &idmap, KoStore *store, KoXmlWriter *manifestWriter) 0065 { 0066 QSharedPointer<Soprano::Model> tmpmodel(Soprano::createModel()); 0067 QMap<QString, QString>::const_iterator iditer = idmap.constBegin(); 0068 QMap<QString, QString>::const_iterator idend = idmap.constEnd(); 0069 for (; iditer != idend; ++iditer) { 0070 QString oldID = iditer.key(); 0071 QString newID = iditer.value(); 0072 debugText << "oldID:" << oldID << " newID:" << newID; 0073 QString sparqlQuery; 0074 QTextStream queryss(&sparqlQuery); 0075 queryss << "" 0076 << "prefix pkg: <http://docs.oasis-open.org/ns/office/1.2/meta/pkg#> \n" 0077 << "" 0078 << "select ?s ?p ?o \n" 0079 << "where { \n" 0080 << " ?s pkg:idref ?xmlid . \n" 0081 << " ?s ?p ?o . \n" 0082 << " filter( str(?xmlid) = \"" << oldID << "\" ) \n" 0083 << "}\n"; 0084 0085 Soprano::QueryResultIterator it = 0086 docmodel->executeQuery(sparqlQuery, 0087 Soprano::Query::QueryLanguageSparql); 0088 while (it.next()) { 0089 Soprano::Node pred = it.binding("p"); 0090 Soprano::Node obj = it.binding("o"); 0091 if (pred.toString() == "http://docs.oasis-open.org/ns/office/1.2/meta/pkg#idref") { 0092 debugText << "changing idref, oldID:" << oldID << " newID:" << newID; 0093 obj = Node::createLiteralNode(newID); 0094 } 0095 Statement s(it.binding("s"), pred, obj); 0096 tmpmodel->addStatement(s); 0097 } 0098 } 0099 debugText << "exporting triples model.sz:" << tmpmodel->statementCount(); 0100 // save tmpmodel as manifest.rdf in C+P ODF file. 0101 Soprano::StatementIterator triples = tmpmodel->listStatements(); 0102 bool ret = saveRdf(tmpmodel, triples, store, manifestWriter, "manifest.rdf"); 0103 return ret; 0104 } 0105 0106 bool KoTextRdfCore::loadManifest(KoStore *store, QSharedPointer<Soprano::Model> model) 0107 { 0108 bool ok = true; 0109 QString fileName = "manifest.rdf"; 0110 if (!store->open(fileName)) { 0111 debugText << "Entry " << fileName << " not found!"; 0112 return false; 0113 } 0114 Soprano::Node context(QUrl("http://www.calligra.org/Rdf/path/" + fileName)); 0115 QUrl BaseURI = QUrl(""); 0116 debugText << "Loading external Rdf/XML from:" << fileName; 0117 0118 QString rdfxmlData(store->device()->readAll()); 0119 const Soprano::Parser *parser = 0120 Soprano::PluginManager::instance()->discoverParserForSerialization( 0121 Soprano::SerializationRdfXml); 0122 Soprano::StatementIterator it = parser->parseString(rdfxmlData, 0123 BaseURI, 0124 Soprano::SerializationRdfXml); 0125 QList<Statement> allStatements = it.allElements(); 0126 debugText << "Found " << allStatements.size() << " triples..."; 0127 foreach (const Soprano::Statement &s, allStatements) { 0128 Error::ErrorCode err = model->addStatement(s.subject(), s.predicate(), 0129 s.object(), context); 0130 if (err != Error::ErrorNone) { 0131 debugText << "Error adding triple! s:" << s.subject() 0132 << " p:" << s.predicate() 0133 << " o:" << s.object(); 0134 ok = false; 0135 break; 0136 } 0137 } 0138 store->close(); 0139 return ok; 0140 } 0141 0142 void KoTextRdfCore::dumpModel(const QString &msg, QSharedPointer<Soprano::Model> m) 0143 { 0144 #ifndef NDEBUG 0145 QList<Soprano::Statement> allStatements = m->listStatements().allElements(); 0146 debugText << "----- " << msg << " ----- model size:" << allStatements.size() << endl; 0147 foreach (const Soprano::Statement &s, allStatements) { 0148 debugText << s; 0149 } 0150 #else 0151 Q_UNUSED(msg); 0152 Q_UNUSED(m); 0153 #endif 0154 } 0155 0156 QList<Soprano::Statement> KoTextRdfCore::loadList(QSharedPointer<Soprano::Model> model, Soprano::Node ListHeadSubject) 0157 { 0158 Node rdfNil = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil")); 0159 Node rdfFirst = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#first")); 0160 Node rdfRest = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest")); 0161 0162 Soprano::Node listBNode = ListHeadSubject; 0163 QList<Statement> ret; 0164 debugText << "finding all nodes in the list..."; 0165 while (true) { 0166 ret << model->listStatements(listBNode, rdfFirst, Node()).allElements(); 0167 Soprano::Node obj = KoTextRdfCore::getObject(model, listBNode, rdfRest); 0168 debugText << "ret:" << ret; 0169 debugText << "rest:" << obj; 0170 if (!obj.isValid()) { 0171 break; 0172 } 0173 if (obj.toString() == rdfNil.toString()) { 0174 break; 0175 } 0176 listBNode = obj; 0177 } 0178 return ret; 0179 } 0180 0181 static void removeList(QSharedPointer<Soprano::Model> model, Soprano::Node ListHeadSubject) 0182 { 0183 Node rdfNil = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil")); 0184 Node rdfFirst = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#first")); 0185 Node rdfRest = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest")); 0186 // 0187 // Chain down the list recursively so we delete from 0188 // the list tail back to the head. 0189 // 0190 Soprano::Node obj = KoTextRdfCore::getObject(model, ListHeadSubject, rdfRest); 0191 if (obj.isValid()) { 0192 if (obj.toString() != rdfNil.toString()) { 0193 removeList(model, obj); 0194 } 0195 } 0196 model->removeAllStatements(ListHeadSubject, rdfFirst, Node()); 0197 model->removeAllStatements(ListHeadSubject, rdfRest, Node()); 0198 } 0199 0200 void KoTextRdfCore::saveList(QSharedPointer<Soprano::Model> model, Soprano::Node ListHeadSubject, QList<Soprano::Node> &dataBNodeList, Soprano::Node context) 0201 { 0202 Node rdfNil = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil")); 0203 Node rdfFirst = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#first")); 0204 Node rdfRest = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest")); 0205 0206 debugText << "header:" << ListHeadSubject.toString(); 0207 debugText << "list.sz:" << dataBNodeList.size(); 0208 debugText << "context:" << context.toString(); 0209 0210 removeList(model, ListHeadSubject); 0211 0212 Soprano::Node listBNode = ListHeadSubject; 0213 Soprano::Node prevListBNode; 0214 0215 foreach (const Soprano::Node &dataBNode, dataBNodeList) { 0216 // Link the list in Rdf 0217 model->addStatement(listBNode, rdfFirst, dataBNode, context); 0218 if (prevListBNode.isValid()) { 0219 debugText << "prev:" << prevListBNode << " current:" << listBNode; 0220 model->addStatement(prevListBNode, rdfRest, listBNode, context); 0221 } 0222 prevListBNode = listBNode; 0223 listBNode = model->createBlankNode(); 0224 } 0225 0226 debugText << "at end, prev.isValid:" << prevListBNode.isValid(); 0227 if (prevListBNode.isValid()) { 0228 model->addStatement(prevListBNode, rdfRest, listBNode, context); 0229 } 0230 model->addStatement(listBNode, rdfRest, rdfNil, context); 0231 } 0232 0233 void KoTextRdfCore::removeStatementsIfTheyExist( QSharedPointer<Soprano::Model> m, const QList<Soprano::Statement> &removeList) 0234 { 0235 foreach (const Soprano::Statement &s, removeList) { 0236 StatementIterator it = m->listStatements(s.subject(), s.predicate(), s.object(), s.context()); 0237 QList<Statement> allStatements = it.allElements(); 0238 foreach(const Soprano::Statement &z, allStatements) { 0239 debugText << "found:" << z; 0240 m->removeStatement(z); 0241 } 0242 } 0243 } 0244 0245 Soprano::Node KoTextRdfCore::getObject(QSharedPointer<Soprano::Model> model, Soprano::Node s, Soprano::Node p) 0246 { 0247 QList<Statement> all; 0248 all = model->listStatements(s, p, Node()).allElements(); 0249 if (all.isEmpty()) { 0250 return Soprano::Node(); 0251 } 0252 return all.first().object(); 0253 } 0254 0255 QByteArray KoTextRdfCore::fileToByteArray(const QString &fileName) 0256 { 0257 QFile t(fileName); 0258 t.open(QIODevice::ReadOnly); 0259 return t.readAll(); 0260 } 0261 0262 QString KoTextRdfCore::getProperty(QSharedPointer<Soprano::Model> m, Soprano::Node subj, Soprano::Node pred, const QString &defval) 0263 { 0264 StatementIterator it = m->listStatements(subj, pred, Node()); 0265 QList<Statement> allStatements = it.allElements(); 0266 foreach (const Soprano::Statement &s, allStatements) { 0267 return s.object().toString(); 0268 } 0269 return defval; 0270 } 0271 0272 QString KoTextRdfCore::optionalBindingAsString(Soprano::QueryResultIterator &it, const QString &bindingName, const QString &def) 0273 { 0274 if (it.binding(bindingName).isValid()) { 0275 return it.binding(bindingName).toString(); 0276 } 0277 return def; 0278 }