35 #include <Soprano/Vocabulary/NRL>
36 #include <Soprano/Vocabulary/NAO>
37 #include <Soprano/Vocabulary/RDF>
38 #include <Soprano/Vocabulary/RDFS>
40 #include <Soprano/Graph>
41 #include <Soprano/QueryResultIterator>
42 #include <Soprano/StatementIterator>
43 #include <Soprano/NodeIterator>
44 #include <Soprano/Error/ErrorCode>
45 #include <Soprano/Parser>
46 #include <Soprano/Serializer>
47 #include <Soprano/PluginManager>
48 #include <Soprano/Util/SimpleStatementIterator>
50 #include <QtCore/QHash>
51 #include <QtCore/QCache>
52 #include <QtCore/QUrl>
53 #include <QtCore/QVariant>
54 #include <QtCore/QDateTime>
55 #include <QtCore/QUuid>
56 #include <QtCore/QSet>
57 #include <QtCore/QPair>
58 #include <QtCore/QFileInfo>
66 #include <KServiceTypeTrader>
67 #include <KProtocolInfo>
69 #include <KIO/NetAccess>
71 #define STRIGI_INDEX_GRAPH_FOR "http://www.strigi.org/fields#indexGraphFor"
73 using namespace Nepomuk2::Vocabulary;
74 using namespace Soprano::Vocabulary;
82 QStringList nodesToN3(
const QSet<Soprano::Node>& nodes) {
84 Q_FOREACH(
const Soprano::Node& node, nodes) {
90 QStringList nodesToN3(
const QList<Soprano::Node>& nodes) {
92 Q_FOREACH(
const Soprano::Node& node, nodes) {
98 QStringList urlListToN3(
const QList<QUrl>& uris) {
100 Q_FOREACH(
const QUrl& uri, uris) {
101 n3 << Soprano::Node::resourceToN3(uri);
106 QStringList urlSetToN3(
const QSet<QUrl>& uris) {
108 Q_FOREACH(
const QUrl& uri, uris) {
109 n3 << Soprano::Node::resourceToN3(uri);
114 template<
typename T> QString createResourceFilter(
const T& resources,
const QString& var,
bool exclude =
true) {
115 QString filter = QString::fromLatin1(
"%1 in (%2)").arg(var,
Nepomuk2::resourcesToN3(resources).join(QLatin1String(
",")));
117 filter = QString::fromLatin1(
"!(%1)").arg(filter);
126 QString createResourceMetadataPropertyFilter(
const QString& propVar,
bool exclude =
true) {
127 return createResourceFilter(QList<QUrl>()
129 << NAO::lastModified()
131 << NAO::userVisible()
155 inline UriState uriState(
const QUrl& uri,
bool statLocalFiles =
true) {
156 if(uri.scheme() == QLatin1String(
"nepomuk")) {
159 else if(uri.scheme() == QLatin1String(
"file")) {
160 if(!statLocalFiles ||
161 QFile::exists(uri.toLocalFile())) {
162 return ExistingFileUrl;
165 return NonExistingFileUrl;
171 else if(uri.toString().startsWith(
"_:") ) {
175 else if( KProtocolInfo::isKnownProtocol(uri) ) {
183 inline Soprano::Node convertIfBlankUri(
const QUrl &uri) {
184 if( uri.toString().startsWith(QLatin1String(
"_:")) )
185 return Soprano::Node( uri.toString().mid(2) );
187 return Soprano::Node( uri );
191 class Nepomuk2::DataManagementModel::Private
198 QSet<QUrl> m_protectedProperties;
200 QCache<QString, QUrl> m_appCache;
201 QMutex m_appCacheMutex;
203 typedef QPair<QString, bool> GraphCacheItem;
204 QCache<GraphCacheItem, QUrl> m_graphCache;
205 QMutex m_graphCacheMutex;
212 : Soprano::FilterModel(model),
215 d->m_classAndPropertyTree = tree;
218 d->m_appCache.setMaxCost( 10 );
224 d->m_protectedProperties.insert(NAO::created());
225 d->m_protectedProperties.insert(NAO::creator());
226 d->m_protectedProperties.insert(NAO::lastModified());
227 d->m_protectedProperties.insert(NAO::userVisible());
228 d->m_protectedProperties.insert(NIE::url());
231 d->m_nepomukGraph = fetchGraph(QLatin1String(
"nepomuk"));
235 if( !containsAnyStatement( QUrl(
"nepomuk:/me"), Soprano::Node(), Soprano::Node() ) ) {
236 addStatement( QUrl(
"nepomuk:/me"), RDF::type(), PIMO::Person(), d->m_nepomukGraph );
243 QLatin1String command(
"log_enable( 3 )");
244 executeQuery( command, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
249 QMutexLocker lock2( &d->m_graphCacheMutex );
250 d->m_graphCache.clear();
253 QMutexLocker lock( &d->m_appCacheMutex );
254 d->m_appCache.clear();
257 d->m_typeCache->clear();
258 d->m_nepomukGraph = fetchGraph(QLatin1String(
"nepomuk"));
262 if( !containsAnyStatement( QUrl(
"nepomuk:/me"), Soprano::Node(), Soprano::Node() ) ) {
263 addStatement( QUrl(
"nepomuk:/me"), RDF::type(), PIMO::Person(), d->m_nepomukGraph );
270 delete d->m_typeCache;
276 const QDateTime& date)
278 return updateModificationDate(QSet<QUrl>() << resource, date);
283 const QDateTime& date)
285 if(resources.isEmpty()) {
286 return Soprano::Error::ErrorNone;
293 const QString graphN3 = Soprano::Node::resourceToN3(d->m_nepomukGraph);
294 const QStringList allResN3 = urlSetToN3( resources );
297 for(
int i=0; i<allResN3.size(); i+=30) {
298 const QStringList resN3 = allResN3.mid( i, 30 );
300 QString delQ = QString::fromLatin1(
"sparql DELETE from %1 { ?res nao:lastModified ?mod . } "
301 "WHERE { ?res nao:lastModified ?mod . "
302 " FILTER(?res in (%3)) ."
304 .arg( graphN3, resN3.join(
",") );
306 executeQuery( delQ, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
308 const QString dt = Soprano::Node::literalToN3(date);
310 QString iq = QString::fromLatin1(
"sparql insert into %1 {").arg( graphN3 );
311 foreach(
const QString& res, resN3) {
312 iq += QString::fromLatin1(
" %1 nao:lastModified %2 .").arg( res, dt );
314 iq += QLatin1String(
"} ");
316 executeQuery( iq, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
318 return Soprano::Error::ErrorNone;
327 setError(QLatin1String(
"addProperty: Empty application specified. This is not supported."), Soprano::Error::ErrorInvalidArgument);
330 if(resources.isEmpty()) {
331 setError(QLatin1String(
"addProperty: No resource specified."), Soprano::Error::ErrorInvalidArgument);
334 foreach(
const QUrl & res, resources ) {
336 setError(QLatin1String(
"addProperty: Encountered empty resource URI."), Soprano::Error::ErrorInvalidArgument);
340 if(property.isEmpty()) {
341 setError(QLatin1String(
"addProperty: Property needs to be specified."), Soprano::Error::ErrorInvalidArgument);
344 if(values.isEmpty()) {
345 setError(QLatin1String(
"addProperty: Values needs to be specified."), Soprano::Error::ErrorInvalidArgument);
348 if(d->m_protectedProperties.contains(property)) {
349 setError(QString::fromLatin1(
"addProperty: %1 is a protected property which can only be set.").arg(property.toString()),
350 Soprano::Error::ErrorInvalidArgument);
358 const QSet<Soprano::Node> nodes = d->m_classAndPropertyTree->variantListToNodeSet(values, property);
359 if(nodes.isEmpty()) {
360 setError(d->m_classAndPropertyTree->lastError());
370 QList<Soprano::Node> resolvedNodes;
373 if(property == NIE::url()) {
374 if(resources.count() != 1) {
375 setError(QLatin1String(
"addProperty: no two resources can have the same nie:url."), Soprano::Error::ErrorInvalidArgument);
378 else if(nodes.count() > 1) {
379 setError(QLatin1String(
"addProperty: One resource can only have one nie:url."), Soprano::Error::ErrorInvalidArgument);
383 if(!nodes.isEmpty()) {
389 if(containsAnyStatement(Soprano::Node(), NIE::url(), *nodes.constBegin())) {
390 setError(QLatin1String(
"addProperty: No two resources can have the same nie:url at the same time."), Soprano::Error::ErrorInvalidArgument);
393 else if(containsAnyStatement(resources.first(), NIE::url(), Soprano::Node())) {
397 setError(QLatin1String(
"addProperty: One resource can only have one nie:url."), Soprano::Error::ErrorInvalidArgument);
402 resolvedNodes << *nodes.constBegin();
406 resolvedNodes = resolveNodes(nodes, app);
416 QList<QUrl> resolvedUris = resolveUrls(resources, app);
425 const int maxCardinality = d->m_classAndPropertyTree->maxCardinality(property);
426 if( maxCardinality == 1 ) {
432 if(resolvedNodes.first().isValid()) {
433 valueFilter = QString::fromLatin1(
"FILTER(?v!=%3) . ")
434 .arg(resolvedNodes.first().toN3());
438 Q_FOREACH(
const QUrl& res, resolvedUris) {
439 terms << QString::fromLatin1(
"%1 %2 ?v . %3")
440 .arg(Soprano::Node::resourceToN3(res),
441 Soprano::Node::resourceToN3(property),
445 const QString cardinalityQuery = QString::fromLatin1(
"ask where { { %1 } }")
446 .arg(terms.join(QLatin1String(
"} UNION {")));
448 if(executeQuery(cardinalityQuery, Soprano::Query::QueryLanguageSparql).boolValue()) {
449 setError(QString::fromLatin1(
"%1 has cardinality of 1. At least one of the resources already has a value set that differs from the new one.")
450 .arg(Soprano::Node::resourceToN3(property)), Soprano::Error::ErrorInvalidArgument);
459 addProperty(resolvedUris, property, resolvedNodes, app,
true );
470 if(values.isEmpty()) {
479 setError(QLatin1String(
"setProperty: Empty application specified. This is not supported."), Soprano::Error::ErrorInvalidArgument);
482 if(resources.isEmpty()) {
483 setError(QLatin1String(
"setProperty: No resource specified."), Soprano::Error::ErrorInvalidArgument);
486 foreach(
const QUrl & res, resources ) {
488 setError(QLatin1String(
"setProperty: Encountered empty resource URI."), Soprano::Error::ErrorInvalidArgument);
492 if(property.isEmpty()) {
493 setError(QLatin1String(
"setProperty: Property needs to be specified."), Soprano::Error::ErrorInvalidArgument);
501 const QSet<Soprano::Node> nodes = d->m_classAndPropertyTree->variantListToNodeSet(values, property);
502 if(nodes.isEmpty()) {
503 setError(d->m_classAndPropertyTree->lastError());
513 QList<Soprano::Node> resolvedNodes;
518 if(property == NIE::url()) {
519 if(resources.count() != 1) {
520 setError(QLatin1String(
"setProperty: no two resources can have the same nie:url."), Soprano::Error::ErrorInvalidArgument);
523 else if(nodes.count() > 1) {
524 setError(QLatin1String(
"setProperty: One resource can only have one nie:url."), Soprano::Error::ErrorInvalidArgument);
533 QString query = QString::fromLatin1(
"select ?r where { ?r nie:url %1 . }")
534 .arg( nodes.constBegin()->toN3() );
536 Soprano::QueryResultIterator it = executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
538 if( it[0] != resources.first() ) {
539 setError(QLatin1String(
"setProperty: No two resources can have the same nie:url at the same time."), Soprano::Error::ErrorInvalidArgument);
544 if(updateNieUrlOnLocalFile(resources.first(), nodes.constBegin()->uri())) {
549 resolvedNodes << *nodes.constBegin();
552 resolvedNodes = resolveNodes(nodes, app);
561 QList<QUrl> resolvedUris = resolveUrls(resources, app);
569 const QStringList uriHashN3 = urlListToN3(resolvedUris);
570 if(!uriHashN3.isEmpty()) {
572 const QSet<Soprano::Node> setValues = QSet<Soprano::Node>::fromList(resolvedNodes);
573 QList<Soprano::BindingSet> existing
574 = executeQuery(QString::fromLatin1(
"select ?r ?v where { ?r %1 ?v . FILTER(?r in (%2)) . }")
575 .arg(Soprano::Node::resourceToN3(property),
576 uriHashN3.join(QLatin1String(
","))),
577 Soprano::Query::QueryLanguageSparql).allBindings();
578 Q_FOREACH(
const Soprano::BindingSet& binding, existing) {
579 if(!setValues.contains(binding[
"v"])) {
580 removeAllStatements(binding[
"r"], property, binding[
"v"]);
581 valuesToRemove[binding[
"r"].uri()].append(binding[
"v"]);
591 if(!nodes.isEmpty()) {
592 addedValues =
addProperty(resolvedUris, property, resolvedNodes, app);
598 foreach(
const QUrl& res, resolvedUris) {
599 const QList<Soprano::Node> added = addedValues.value(res);
600 const QList<Soprano::Node> removed = valuesToRemove.value(res);
601 if(!added.isEmpty() || !removed.isEmpty()) {
602 d->m_watchManager->changeProperty(res,
608 if(!resolvedUris.isEmpty()) {
609 d->m_watchManager->changeSomething();
613 addProperty(resolvedUris, property, resolvedNodes, app,
true);
627 setError(QLatin1String(
"removeProperty: Empty application specified. This is not supported."), Soprano::Error::ErrorInvalidArgument);
630 if(resources.isEmpty()) {
631 setError(QLatin1String(
"removeProperty: No resource specified."), Soprano::Error::ErrorInvalidArgument);
634 foreach(
const QUrl & res, resources ) {
636 setError(QLatin1String(
"removeProperty: Encountered empty resource URI."), Soprano::Error::ErrorInvalidArgument);
640 if(property.isEmpty()) {
641 setError(QLatin1String(
"removeProperty: Property needs to be specified."), Soprano::Error::ErrorInvalidArgument);
644 if(values.isEmpty()) {
645 setError(QLatin1String(
"removeProperty: Values needs to be specified."), Soprano::Error::ErrorInvalidArgument);
648 if(d->m_protectedProperties.contains(property)) {
649 setError(QString::fromLatin1(
"removeProperty: %1 is a protected property which can only be changed by the data management service itself.").arg(property.toString()),
650 Soprano::Error::ErrorInvalidArgument);
654 const QSet<Soprano::Node> valueNodes = d->m_classAndPropertyTree->variantListToNodeSet(values, property);
655 if(valueNodes.isEmpty()) {
656 setError(d->m_classAndPropertyTree->lastError());
667 QSet<QUrl> resolvedResources = QSet<QUrl>::fromList(resolveUrls(resources, app,
false));
668 if(resolvedResources.isEmpty() || lastError()) {
672 QList<Soprano::Node> resolvedNodes = resolveNodes(valueNodes, app);
673 if(resolvedNodes.isEmpty() || lastError()) {
680 foreach(
const QUrl & res, resolvedResources ) {
681 QString query = QString::fromLatin1(
"select distinct ?v where { %1 %2 ?v . FILTER(?v in (%3)). }")
682 .arg( Soprano::Node::resourceToN3(res),
683 Soprano::Node::resourceToN3(property),
684 nodesToN3(resolvedNodes).join(QLatin1String(
",")) );
686 const QList<Soprano::BindingSet> valueGraphs
687 = executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference ).allBindings();
689 QList<Soprano::Node> removedValues;
690 foreach(
const Soprano::BindingSet& binding, valueGraphs) {
691 const Soprano::Node v = binding[
"v"];
692 removeAllStatements( res, property, v );
696 if(!removedValues.isEmpty()) {
697 d->m_watchManager->changeProperty( res, property, QList<Soprano::Node>(), removedValues );
701 if(!valueGraphs.isEmpty()) {
703 if(!doesResourceExist(res)) {
707 updateModificationDate(res);
723 setError(QLatin1String(
"removeProperties: Empty application specified. This is not supported."), Soprano::Error::ErrorInvalidArgument);
726 if(resources.isEmpty()) {
727 setError(QLatin1String(
"removeProperties: No resource specified."), Soprano::Error::ErrorInvalidArgument);
730 foreach(
const QUrl & res, resources ) {
732 setError(QLatin1String(
"removeProperties: Encountered empty resource URI."), Soprano::Error::ErrorInvalidArgument);
736 if(properties.isEmpty()) {
737 setError(QLatin1String(
"removeProperties: No properties specified."), Soprano::Error::ErrorInvalidArgument);
740 foreach(
const QUrl& property, properties) {
741 if(property.isEmpty()) {
742 setError(QLatin1String(
"removeProperties: Encountered empty property URI."), Soprano::Error::ErrorInvalidArgument);
745 else if(d->m_protectedProperties.contains(property)) {
746 setError(QString::fromLatin1(
"removeProperties: %1 is a protected property which can only be changed by the data management service itself.").arg(property.toString()),
747 Soprano::Error::ErrorInvalidArgument);
759 QSet<QUrl> resolvedResources = QSet<QUrl>::fromList(resolveUrls(resources, app,
false));
760 if(resolvedResources.isEmpty() || lastError()) {
768 foreach(
const QUrl & res, resolvedResources ) {
769 QSet<Soprano::Node> propertiesToRemove;
771 Soprano::QueryResultIterator it
772 = executeQuery(QString::fromLatin1(
"select distinct ?p ?v where { %1 ?p ?v . FILTER(?p in (%2)) . }")
773 .arg(Soprano::Node::resourceToN3(res),
775 Soprano::Query::QueryLanguageSparql);
777 propertiesToRemove.insert(it[
"p"]);
778 propertyValues.insert( it[
"p"].uri(), it[
"v"] );
782 foreach(
const Soprano::Node& property, propertiesToRemove) {
783 removeAllStatements( res, property, Soprano::Node() );
788 it != propertyValues.constEnd(); ) {
789 QList<Soprano::Node> values;
790 values << it.value();
792 const QUrl
property = it.key();
793 for( ++it; it != propertyValues.constEnd() && it.key() == property; ++it ) {
794 values << it.value();
797 d->m_watchManager->changeProperty(res, property, QList<Soprano::Node>(), values);
801 if(!propertiesToRemove.isEmpty()) {
803 if(!doesResourceExist(res)) {
807 updateModificationDate(res);
826 setError(QLatin1String(
"createResource: Empty application specified. This is not supported."), Soprano::Error::ErrorInvalidArgument);
829 QSet<QUrl> newTypes = types.toSet();
830 QMutableSetIterator<QUrl> iterator( newTypes );
831 while( iterator.hasNext() ) {
832 const QUrl type = iterator.next();
838 if(!d->m_classAndPropertyTree->isKnownClass(type)) {
839 QString error = QString::fromLatin1(
"createResource: Encountered invalid type URI %1").arg( Soprano::Node::resourceToN3(type) );
840 setError(error, Soprano::Error::ErrorInvalidArgument);
845 if( newTypes.isEmpty() ) {
846 newTypes << RDFS::Resource();
852 QSetIterator<QUrl> it( newTypes );
853 while( it.hasNext() ) {
854 const QUrl &type = it.next();
855 QSet<QUrl> superTypes = d->m_classAndPropertyTree->allParents( type );
857 foreach(
const QUrl& parent, superTypes ) {
858 QSet< QUrl >::iterator iter = newTypes.find( parent );
859 if( iter != newTypes.end() ) {
860 newTypes.erase( iter );
866 const QUrl graph = fetchGraph(app);
867 const QUrl resUri = createUri(ResourceUri);
868 const QString resN3 = Soprano::Node::resourceToN3(resUri);
871 QString command = QString::fromLatin1(
"sparql insert into %1 { %2 ")
872 .arg( Soprano::Node::resourceToN3(graph),
875 if(!label.isEmpty()) {
876 Soprano::LiteralValue lv = Soprano::LiteralValue::createPlainLiteral(label);
877 command += QString::fromLatin1(
" nao:prefLabel %1 ;")
878 .arg( Soprano::Node::literalToN3(lv) );
880 if(!description.isEmpty()) {
881 Soprano::LiteralValue lv = Soprano::LiteralValue::createPlainLiteral(description);
882 command += QString::fromLatin1(
" nao:description %1 ;")
883 .arg( Soprano::Node::literalToN3(lv) );
886 command += QString::fromLatin1(
"a %1 . }").arg( urlSetToN3(newTypes).join(
",") );
887 executeQuery( command, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
890 command = QString::fromLatin1(
"sparql insert into %1 { %2 ")
891 .arg( Soprano::Node::resourceToN3(d->m_nepomukGraph), resN3 );
893 Soprano::LiteralValue now( QDateTime::currentDateTime() );
894 command += QString::fromLatin1(
" nao:lastModified %1 ; nao:created %1 . }")
895 .arg( Soprano::Node::literalToN3(now) );
897 executeQuery( command, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
900 QSet<QUrl> allTypes = d->m_classAndPropertyTree->allParents( types );
901 d->m_watchManager->createResource(resUri, allTypes);
902 d->m_watchManager->changeSomething();
918 setError(QLatin1String(
"removeResources: Empty application specified. This is not supported."), Soprano::Error::ErrorInvalidArgument);
921 if(resources.isEmpty()) {
922 setError(QLatin1String(
"removeResources: No resource specified."), Soprano::Error::ErrorInvalidArgument);
925 foreach(
const QUrl & res, resources ) {
927 setError(QLatin1String(
"removeResources: Encountered empty resource URI."), Soprano::Error::ErrorInvalidArgument);
937 QSet<QUrl> resolvedResources = QSet<QUrl>::fromList(resolveUrls(resources, app,
false));
938 if(resolvedResources.isEmpty() || lastError()) {
945 removeAllResources(resolvedResources, flags);
954 setError(QLatin1String(
"removeDataByApplication: Empty application specified. This is not supported."), Soprano::Error::ErrorInvalidArgument);
957 foreach(
const QUrl & res, resources ) {
959 setError(QLatin1String(
"removeDataByApplication: Encountered empty resource URI."), Soprano::Error::ErrorInvalidArgument);
967 const QUrl appRes = findApplicationResource(app,
false);
968 if(appRes.isEmpty()) {
975 QString query = QString::fromLatin1(
"select distinct ?g where { ?g nao:maintainedBy %1 . }")
976 .arg( Soprano::Node::resourceToN3(appRes) );
978 Soprano::QueryResultIterator it = executeQuery(query, Soprano::Query::QueryLanguageSparqlNoInference);
981 graphs << it[0].uri();
984 if( graphs.isEmpty() )
990 QSet<QUrl> resolvedResources = QSet<QUrl>::fromList(resolveUrls(resources, app,
false));
991 if(resolvedResources.isEmpty() || lastError()) {
996 QList<QUrl> allGraphs( graphs );
997 allGraphs << d->m_nepomukGraph;
1009 QSet<QUrl> subResources;
1010 QSet<QUrl> currentResources = resolvedResources;
1013 resCount = resolvedResources.count();
1015 QString query = QString::fromLatin1(
"select distinct ?r where { graph ?g { ?r ?p ?o. }"
1016 "?parent nao:hasSubResource ?r . "
1017 "FILTER(?parent in (%1)) ."
1018 "FILTER(?g in (%2)) . "
1019 "FILTER NOT EXISTS { graph ?g2 { ?r ?p ?o. } FILTER(!(?g2 in (%3))) . }"
1025 Soprano::QueryResultIterator it = executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
1026 currentResources.clear();
1028 currentResources << it[0].uri();
1030 resolvedResources += currentResources;
1031 subResources += currentResources;
1032 }
while(resCount < resolvedResources.count());
1041 QSet<QUrl> excludedSubResources = resolvedResources;
1042 bool firstIteration =
true;
1043 while(!subResources.isEmpty() && !excludedSubResources.isEmpty()) {
1044 Soprano::QueryResultIterator it
1045 = executeQuery(QString::fromLatin1(
"select distinct ?r where { "
1049 .arg(createResourceFilter(subResources, QLatin1String(
"?r"),
false),
1050 createResourceFilter(excludedSubResources, QLatin1String(
"?r2"), firstIteration)),
1051 Soprano::Query::QueryLanguageSparqlNoInference);
1052 excludedSubResources.clear();
1054 excludedSubResources << it[0].uri();
1056 subResources -= excludedSubResources;
1057 resolvedResources -= excludedSubResources;
1061 firstIteration =
false;
1069 QString graphN3 = urlListToN3(graphs).join(QLatin1String(
","));
1070 QString resN3 = urlSetToN3(resolvedResources).join(QLatin1String(
","));
1072 query = QString::fromLatin1(
"select distinct ?r where { graph ?g { ?r ?p ?o. } FILTER(?g in (%1)) ."
1073 "FILTER(?r in (%2)) . }")
1074 .arg( graphN3, resN3 );
1076 QList<QUrl> finalResourcesList;
1077 it = executeQuery( query, Soprano::Query::QueryLanguageSparql );
1079 finalResourcesList << it[0].uri();
1081 resolvedResources = finalResourcesList.toSet();
1082 resN3 = urlListToN3(finalResourcesList).join(QLatin1String(
","));
1087 QString notInGraphs = graphN3;
1088 notInGraphs += QString::fromLatin1(
",%1").arg(Soprano::Node::resourceToN3(d->m_nepomukGraph));
1090 query = QString::fromLatin1(
"select distinct ?r where { "
1091 " graph ?g1 { ?r ?p ?o. } "
1092 " graph ?g2 { ?r ?p2 ?o2 . } "
1093 " FILTER(?g1 in (%1)) . FILTER(?r in (%2)) . "
1094 " FILTER(!(?g2 in (%3))) . }")
1095 .arg( graphN3, resN3, notInGraphs );
1097 it = executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
1098 QSet<QUrl> modifiedResources;
1099 while( it.next() ) {
1100 modifiedResources << it[0].uri();
1103 query = QString::fromLatin1(
"select distinct ?r2 where { "
1104 " graph ?g { ?r2 ?p ?r . FILTER(?r in (%1)) .}"
1105 " FILTER(?g in (%2)) }")
1106 .arg( resN3, graphN3 );
1108 it = executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
1109 while( it.next() ) {
1110 QUrl uri = it[0].uri();
1111 if( !resolvedResources.contains(uri) )
1112 modifiedResources << uri;
1114 updateModificationDate(modifiedResources);
1116 foreach(
const QUrl& graph, graphs) {
1117 QString deleteCommand = QString::fromLatin1(
"sparql delete from %1 { ?r ?p ?o. } where { "
1118 "?r ?p ?o. FILTER(?r in (%2)). }")
1119 .arg( Soprano::Node::resourceToN3(graph), resN3 );
1121 executeQuery( deleteCommand, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
1123 deleteCommand = QString::fromLatin1(
"sparql delete from %1 { ?o ?p ?r. } where { "
1124 "?o ?p ?r. FILTER(?r in (%2)). }")
1125 .arg( Soprano::Node::resourceToN3(graph), resN3 );
1127 executeQuery( deleteCommand, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
1131 resolvedResources.subtract( modifiedResources );
1133 if( resolvedResources.count() ) {
1134 QString deleteCommand = QString::fromLatin1(
"sparql delete from %1 { ?r ?p ?o. } where { "
1135 "?r ?p ?o. FILTER(?r in (%2)). }")
1136 .arg( Soprano::Node::resourceToN3(d->m_nepomukGraph),
1137 urlSetToN3(resolvedResources).join(
",") );
1138 executeQuery( deleteCommand, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
1150 setError(QLatin1String(
"removeDataByApplication: Empty application specified. This is not supported."), Soprano::Error::ErrorInvalidArgument);
1156 const QUrl appRes = findApplicationResource(app,
false);
1157 if(appRes.isEmpty()) {
1161 QString query = QString::fromLatin1(
"select ?g where { ?g nao:maintainedBy %1 . }")
1162 .arg( Soprano::Node::resourceToN3(appRes) );
1164 Soprano::QueryResultIterator it = executeQuery(query, Soprano::Query::QueryLanguageSparqlNoInference);
1166 while( it.next() ) {
1167 graphs << it[0].uri();
1171 QSet<QUrl> modifiedResources;
1173 QString graphN3 = urlListToN3(graphs).join(QLatin1String(
","));
1174 QString notInGraphs = graphN3;
1175 notInGraphs += QString::fromLatin1(
",%1").arg(Soprano::Node::resourceToN3(d->m_nepomukGraph));
1178 query = QString::fromLatin1(
"select distinct ?r where { graph ?g1 { ?r ?p ?o. } "
1179 " graph ?g2 { ?r ?p2 ?o2 . } "
1180 " FILTER(?g1 in (%1)) . "
1181 " FILTER(!(?g2 in (%2))) . }")
1182 .arg( graphN3, notInGraphs );
1184 it = executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
1185 while( it.next() ) {
1186 modifiedResources << it[0].uri();
1189 updateModificationDate( modifiedResources );
1191 QSet<QUrl> resourcesToRemove;
1192 foreach(
const QUrl& graph, graphs) {
1193 QString query = QString::fromLatin1(
"select distinct ?r where { graph %1 { ?r ?p ?o. } }")
1194 .arg( Soprano::Node::resourceToN3(graph) );
1196 Soprano::QueryResultIterator it = executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
1198 resourcesToRemove << it[0].uri();
1200 QString command = QString::fromLatin1(
"clear graph %1").arg(Soprano::Node::resourceToN3(graph));
1201 executeQuery( command, Soprano::Query::QueryLanguageSparqlNoInference );
1204 resourcesToRemove.subtract( modifiedResources );
1205 if( resourcesToRemove.count() ) {
1206 query = QString::fromLatin1(
"delete from %2 { ?r ?p ?o . } where { ?r ?p ?o. FILTER(?r in (%1)) . }")
1207 .arg( urlSetToN3(resourcesToRemove).join(
","),
1208 Soprano::Node::resourceToN3(d->m_nepomukGraph) );
1210 executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
1216 using namespace Nepomuk2;
1222 void mergeDuplicateSyncResources( QList<Sync::SyncResource>& syncResources ) {
1225 duplicateResources.clear();
1227 QList<Sync::SyncResource> finalList;
1232 if( syncRes.
uri().url().startsWith(
"_:") ) {
1236 uint hash =
qHash( syncRes );
1238 if( it != syncResHash.end() ) {
1244 if( r.QHash<KUrl,Soprano::Node>::
operator==(syncRes) ) {
1245 kDebug() <<
"Adding: " << syncRes.
uri() <<
" " << it.value()->uri();
1246 duplicateResources.insert( convertIfBlankUri( syncRes.
uri() ),
1247 convertIfBlankUri( it.value()->uri() ) );
1252 syncResHash.insert( hash, &syncRes );
1255 finalList << syncRes;
1258 if( !duplicateResources.isEmpty() ) {
1260 QMutableListIterator<Sync::SyncResource> it( finalList );
1261 while( it.hasNext() ) {
1264 QMutableHashIterator<KUrl, Soprano::Node> iter( it.value() );
1265 while( iter.hasNext() ) {
1268 const Soprano::Node node = iter.value();
1269 if( node.isLiteral() || node.isEmpty() )
1272 if( fit != duplicateResources.constEnd() ) {
1273 iter.setValue( fit.value() );
1278 syncResources = finalList;
1280 }
while( !duplicateResources.isEmpty() );
1288 Nepomuk2::StoreResourcesFlags flags,
1291 bool discardable =
false;
1296 return storeResources(resources, app, discardable, identificationMode, flags);
1303 StoreResourcesFlags flags)
1309 setError(QLatin1String(
"storeResources: Empty application specified. This is not supported."), Soprano::Error::ErrorInvalidArgument);
1323 QSet<QUrl> blankResources;
1325 QList<SimpleResource> resGraphList = resGraph.toList();
1326 QMutableListIterator<SimpleResource> iter( resGraphList );
1327 while( iter.hasNext() ) {
1331 QString error = QString::fromLatin1(
"The resource with URI %1 is invalid.")
1332 .arg( res.
uri().toString() );
1333 setError(error, Soprano::Error::ErrorInvalidArgument);
1338 if(state == NepomukUri) {
1341 else if(state == BlankUri) {
1342 blankResources << res.
uri();
1345 else if(state == NonExistingFileUrl) {
1346 setError(QString::fromLatin1(
"Cannot store information about non-existing local files. File '%1' does not exist.").arg(res.
uri().toLocalFile()), Soprano::Error::ErrorInvalidArgument);
1349 else if(state == ExistingFileUrl || state == SupportedUrl) {
1350 const QUrl nieUrl = res.
uri();
1351 QUrl newResUri = resolveUrl( nieUrl );
1355 if( newResUri.isEmpty() ) {
1359 if( state == ExistingFileUrl ) {
1360 res.
addProperty( RDF::type(), NFO::FileDataObject() );
1361 if( QFileInfo( nieUrl.toLocalFile() ).isDir() )
1368 resolvedNodes.insert( nieUrl, newResUri );
1372 else if( state == OtherUri ) {
1374 const QUrl legacyUri = resolveUrl( res.
uri() );
1378 else if( state == OntologyUri ) {
1379 setError(QLatin1String(
"It is not allowed to add classes or properties through this API."), Soprano::Error::ErrorInvalidArgument);
1383 resGraph = resGraphList;
1386 QList<Sync::SyncResource> syncResources;
1395 QHashIterator<QUrl, QVariant> hit( res.
properties() );
1396 while( hit.hasNext() ) {
1399 Soprano::Node n = d->m_classAndPropertyTree->variantToNode( hit.value(), hit.key() );
1403 if( n.isResource() )
1404 n = convertIfBlankUri( n.uri() );
1406 const Soprano::Error::Error error = d->m_classAndPropertyTree->lastError();
1411 syncRes.insert( hit.key(), n );
1415 const QUrl nieUrl = syncRes.take( NIE::url() ).
uri();
1417 QMutableHashIterator<KUrl, Soprano::Node> it( syncRes );
1418 while( it.hasNext() ) {
1421 const Soprano::Node
object = it.value();
1422 if(
object.isBlank() ) {
1426 QSet<QUrl>::const_iterator fit = blankResources.constFind( QUrl(
object.toN3()) );
1427 if( fit == blankResources.constEnd() ) {
1428 QString error = QString::fromLatin1(
"%1 does not exist in the graph. In statement (%2, %3, %4)")
1429 .arg(
object.toN3(),
1430 syncRes.
uri().url(),
1432 it.value().toN3() );
1433 setError( error, Soprano::Error::ErrorInvalidArgument );
1441 else if(
object.isResource() ) {
1442 const UriState state = uriState(
object.uri());
1443 if(state==NepomukUri || state == OntologyUri) {
1446 else if(state == NonExistingFileUrl) {
1447 setError(QString::fromLatin1(
"Cannot store information about non-existing local files. File '%1' does not exist.").arg(
object.uri().toLocalFile()),
1448 Soprano::Error::ErrorInvalidArgument);
1451 else if(state == ExistingFileUrl || state==SupportedUrl) {
1452 const QUrl nieUrl =
object.uri();
1455 if( findIter != resolvedNodes.constEnd() ) {
1456 it.setValue( convertIfBlankUri(findIter.value()) );
1462 QUrl resolvedUri = resolveUrl( nieUrl );
1463 if( resolvedUri.isEmpty() ) {
1466 newRes.insert( NIE::url(), nieUrl );
1467 if( state == ExistingFileUrl ) {
1468 newRes.insert( RDF::type(), NFO::FileDataObject() );
1469 if( QFileInfo( nieUrl.toLocalFile() ).isDir() )
1470 newRes.insert( RDF::type(), NFO::Folder() );
1473 newRes.
setUri( resolvedUri );
1474 syncResources << newRes;
1477 resolvedNodes.insert( nieUrl, resolvedUri );
1478 it.setValue( convertIfBlankUri(resolvedUri) );
1481 else if(state == OtherUri) {
1485 const QUrl legacyUri = resolveUrl(
object.uri() );
1495 if( nieUrl.scheme() == QLatin1String(
"file") && !QFile::exists(nieUrl.toLocalFile()) ) {
1496 setError(QString::fromLatin1(
"Cannot store information about non-existing local files. File '%1' does not exist.").arg(nieUrl.toLocalFile()),
1497 Soprano::Error::ErrorInvalidArgument);
1502 if( !nieUrl.isEmpty() )
1503 syncRes.insert( NIE::url(), nieUrl );
1506 syncResources << syncRes;
1509 blankResources.clear();
1512 mergeDuplicateSyncResources( syncResources );
1519 if(stList.isEmpty()) {
1520 setError(QString::fromLatin1(
"storeResources: Encountered empty sync resource (%1). This is a bug. Please report.").arg(syncRes.
uri().url()));
1525 setError(QLatin1String(
"storeResources: Contains invalid resources."), Soprano::Error::ErrorParsingFailed);
1528 resIdent.addSyncResource( syncRes );
1534 QTime identificationTimer;
1535 identificationTimer.start();
1537 resIdent.identifyAll();
1539 int identificationTime = identificationTimer.elapsed();
1541 mergingTimer.start();
1544 merger.setMappings( resIdent.mappings() );
1546 if( !merger.merge( resIdent.resourceHash() ) ) {
1547 kDebug() <<
" MERGING FAILED! ";
1548 kDebug() <<
"Setting error!" << merger.lastError();
1549 setError( merger.lastError() );
1553 kDebug() <<
"Identification:" << identificationTime <<
"Merging:" << mergingTimer.elapsed();
1554 kDebug() <<
"TIME TAKEN -------- " << timer.elapsed();
1555 return merger.mappings();
1560 Soprano::RdfSerialization serialization,
1561 const QString &userSerialization,
1563 Nepomuk2::StoreResourcesFlags flags,
1567 QString tmpFileName;
1568 if(!KIO::NetAccess::download(url, tmpFileName, 0)) {
1569 setError(QString::fromLatin1(
"Failed to download '%1'.").arg(url.toString()));
1574 if(serialization == Soprano::SerializationUnknown) {
1575 const QString extension = KUrl(url).fileName().section(
'.', -1).toLower();
1576 if(extension == QLatin1String(
"trig"))
1577 serialization = Soprano::SerializationTrig;
1578 else if(extension == QLatin1String(
"n3"))
1579 serialization = Soprano::SerializationNTriples;
1580 else if(extension == QLatin1String(
"xml"))
1581 serialization = Soprano::SerializationRdfXml;
1584 const Soprano::Parser* parser = Soprano::PluginManager::instance()->discoverParserForSerialization(serialization, userSerialization);
1586 setError(QString::fromLatin1(
"Failed to create parser for serialization '%1'").arg(Soprano::serializationMimeType(serialization, userSerialization)));
1590 Soprano::StatementIterator it = parser->parseFile(tmpFileName, QUrl(), serialization, userSerialization);
1594 if(parser->lastError()) {
1595 setError(parser->lastError());
1597 else if(it.lastError()) {
1598 setError(it.lastError());
1601 storeResources(graph, app, identificationMode, flags, additionalMetadata);
1605 KIO::NetAccess::removeTempFile(tmpFileName);
1611 setError(QLatin1String(
"mergeResources: Empty application specified. This is not supported."),
1612 Soprano::Error::ErrorInvalidArgument);
1615 QSet<QUrl> resSet = resources.toSet();
1616 if(resSet.size() <= 1) {
1617 setError(QLatin1String(
"mergeResources: Need to provide more than 1 resource to merge"),
1618 Soprano::Error::ErrorInvalidArgument);
1624 if( resources.size() > 10 ) {
1625 QList<QUrl> first10Resources = resources.mid( 0, 10 );
1626 QList<QUrl> remainingResources = resources.mid( 10 );
1636 foreach(
const QUrl& uri, resSet) {
1638 setError(QLatin1String(
"mergeResources: Encountered empty resource URI."),
1639 Soprano::Error::ErrorInvalidArgument);
1648 const QUrl resUri = resources.first();
1649 resSet.remove( resUri );
1653 QString query = QString::fromLatin1(
"select ?g ?p ?v (select count(distinct ?v2) where { %2 ?p ?v2 . }) as ?c"
1654 " where { graph ?g { ?r ?p ?v } "
1655 " FILTER(?r in (%1)) ."
1656 " FILTER NOT EXISTS { %2 ?p ?v .} }")
1658 Soprano::Node::resourceToN3(resUri) );
1660 const QList<Soprano::BindingSet> resProperties
1661 = executeQuery(query, Soprano::Query::QueryLanguageSparqlNoInference).allBindings();
1663 foreach(
const Soprano::BindingSet& binding, resProperties) {
1664 const QUrl& prop = binding[
"p"].uri();
1666 if(d->m_classAndPropertyTree->maxCardinality(prop) != 1 ||
1667 binding[
"c"].literal().toInt() == 0) {
1668 const Soprano::Node v = binding[
"v"];
1669 addStatement(resUri, prop, v, binding[
"g"]);
1670 d->m_watchManager->changeProperty( resUri, prop, QList<Soprano::Node>() << v,
1671 QList<Soprano::Node>() );
1679 const QList<Soprano::BindingSet> res2Backlinks
1680 = executeQuery(QString::fromLatin1(
"select ?g ?p ?r where { graph ?g { ?r ?p ?r2 . } . "
1681 "FILTER(?r2 in (%1)) ."
1683 "FILTER NOT EXISTS { ?r ?p %2. } }")
1685 Soprano::Node::resourceToN3(resUri)),
1686 Soprano::Query::QueryLanguageSparqlNoInference).allBindings();
1687 foreach(
const Soprano::BindingSet& binding, res2Backlinks) {
1688 addStatement(binding[
"r"], binding[
"p"], resUri, binding[
"g"]);
1701 QVariant nodeToVariant(
const Soprano::Node& node) {
1702 if(node.isResource())
1704 else if(node.isBlank())
1705 return QUrl(QLatin1String(
"_:") + node.identifier());
1707 return node.literal().variant();
1712 DescribeResourcesFlags flags,
1713 const QList<QUrl>& targetParties)
1718 foreach(
const QUrl & res, resources ) {
1720 setError(QLatin1String(
"describeResources: Encountered empty resource URI."), Soprano::Error::ErrorInvalidArgument);
1725 if(!targetParties.isEmpty()) {
1726 setError(QLatin1String(
"Permission handling has not been implemented yet."));
1737 QSet<QUrl> resolvedResources(QSet<QUrl>::fromList(resolveUrls(resources, QString(),
false )));
1738 if(resolvedResources.isEmpty()) {
1739 setError(QLatin1String(
"describeResources: No useful resource specified."), Soprano::Error::ErrorInvalidArgument);
1749 const QString discardableDataExcludeFilter
1751 ? QString::fromLatin1(
"FILTER(!bif:exists((select (1) where { ?g a %1 . })) || %2) . ")
1752 .arg(Soprano::Node::resourceToN3(NRL::DiscardableInstanceBase()),
1753 createResourceMetadataPropertyFilter(QLatin1String(
"?p"),
false))
1760 QSet<QUrl> subResources = resolvedResources;
1763 resCount = resolvedResources.count();
1766 QSet<QUrl> tmp(subResources);
1767 subResources.clear();
1768 foreach(
const QUrl& res, tmp) {
1769 Soprano::QueryResultIterator it
1770 = executeQuery(QString::fromLatin1(
"select ?r where { "
1771 "graph ?g { ?parent %2 ?r . "
1772 "FILTER(?parent in (%1)) . } . "
1775 .arg(Soprano::Node::resourceToN3(res),
1776 Soprano::Node::resourceToN3(NAO::hasSubResource()),
1777 discardableDataExcludeFilter),
1778 Soprano::Query::QueryLanguageSparqlNoInference);
1779 subResources.clear();
1781 subResources << it[0].uri();
1783 resolvedResources += subResources;
1785 }
while(resCount < resolvedResources.count());
1792 QSet<QUrl> relatedResourcesToFetch;
1795 foreach(
const QUrl& res, resolvedResources) {
1796 Soprano::QueryResultIterator it
1797 = executeQuery(QString::fromLatin1(
"select distinct ?s ?p ?o where { "
1799 "FILTER(?s in (%1)) . "
1802 .arg(Soprano::Node::resourceToN3(res),
1803 discardableDataExcludeFilter),
1804 Soprano::Query::QueryLanguageSparqlNoInference);
1806 const Soprano::Node r = it[
"s"];
1807 const Soprano::Node p = it[
"p"];
1808 const Soprano::Node o = it[
"o"];
1810 if(!o.isResource() ||
1812 d->m_classAndPropertyTree->isDefiningProperty(p.uri()) ||
1817 if(o.isResource() &&
1819 d->m_classAndPropertyTree->isDefiningProperty(p.uri())) &&
1820 !d->m_classAndPropertyTree->isChildOf(p.uri(), NAO::hasSubResource()) &&
1823 relatedResourcesToFetch << o.uri();
1826 if(it.lastError()) {
1827 setError(it.lastError());
1840 QSet<QUrl> currentRelatedResources(relatedResourcesToFetch);
1841 while(!currentRelatedResources.isEmpty()) {
1844 QSet<QUrl> tmp(currentRelatedResources);
1845 currentRelatedResources.clear();
1846 foreach(
const QUrl& res, tmp) {
1847 Soprano::QueryResultIterator it
1848 = executeQuery(QString::fromLatin1(
"select distinct ?s ?p ?o where { "
1849 "graph ?g { ?s ?p ?o . "
1850 "FILTER(?s in (%1)) . "
1851 "FILTER(!(?o in (%2))) . } . "
1852 "FILTER(!bif:exists((select (1) where { ?g a %3 }))) . "
1855 .arg(Soprano::Node::resourceToN3(res),
1857 Soprano::Node::resourceToN3(NRL::Ontology()),
1858 discardableDataExcludeFilter),
1859 Soprano::Query::QueryLanguageSparqlNoInference);
1862 const Soprano::Node r = it[
"s"];
1863 const Soprano::Node p = it[
"p"];
1864 const Soprano::Node o = it[
"o"];
1865 if(d->m_classAndPropertyTree->isDefiningProperty(p.uri())) {
1867 if(o.isResource()) {
1868 currentRelatedResources << o.uri();
1872 if(it.lastError()) {
1873 setError(it.lastError());
1884 foreach(
const QUrl& res, relatedResourcesToFetch + resolvedResources) {
1895 bool hasNonMetadataProps =
false;
1896 foreach(
const QUrl& prop, graph[res].properties().keys()) {
1897 if(!d->m_protectedProperties.contains(prop)) {
1898 hasNonMetadataProps =
true;
1902 if(!hasNonMetadataProps) {
1914 if(it == blankNodes.constEnd()) {
1915 Soprano::Node blank(QString::fromLatin1(
"b%1").arg(blankNodes.count()));
1916 blankNodes.insert(node, blank);
1926 Soprano::RdfSerialization serialization,
1927 const QString &userSerialization,
1928 Nepomuk2::DescribeResourcesFlags flags,
1929 const QList<QUrl> &targetParties)
1932 const Soprano::Serializer* serializer = Soprano::PluginManager::instance()->discoverSerializerForSerialization(serialization, userSerialization);
1934 setError(QString::fromLatin1(
"Could not find serializer plugin for serialization '%1'").arg(Soprano::serializationMimeType(serialization, userSerialization)));
1948 for(QList<Soprano::Statement>::iterator it = statements.begin();
1949 it != statements.end(); ++it) {
1950 if(it->subject().uri().scheme() == QLatin1String(
"nepomuk")) {
1951 it->setSubject(anonymizeUri(it->subject(), blankNodes));
1953 if(it->object().isResource() && it->object().uri().scheme() == QLatin1String(
"nepomuk")) {
1954 it->setObject(anonymizeUri(it->object(), blankNodes));
1960 Soprano::Util::SimpleStatementIterator it(statements);
1962 QTextStream s(&result);
1963 if(serializer->serialize(it, s, serialization, userSerialization)) {
1968 setError(serializer->lastError());
1979 bool haveGraphType =
false;
1980 bool hasNaoCreated =
false;
1983 if( it != additionalMetadata.constEnd() ) {
1985 if(!it.value().isResource()) {
1986 setError(QString::fromLatin1(
"rdf:type has resource range. '%1' does not have a resource type.").arg(it.value().toN3()), Soprano::Error::ErrorInvalidArgument);
1990 if(d->m_classAndPropertyTree->isChildOf(it.value().uri(), NRL::Graph()))
1991 haveGraphType =
true;
1995 it = additionalMetadata.constFind( NAO::created() );
1996 if( it != additionalMetadata.constEnd() ) {
1997 if(!it.value().literal().isDateTime()) {
1998 setError(QString::fromLatin1(
"nao:created has xsd:dateTime range. '%1' is not convertable to a dateTime.").arg(it.value().toN3()), Soprano::Error::ErrorInvalidArgument);
2001 hasNaoCreated =
true;
2008 if(!haveGraphType) {
2009 graphMetaData.insert(RDF::type(), NRL::InstanceBase());
2011 if(!hasNaoCreated) {
2012 graphMetaData.insert(NAO::created(), Soprano::LiteralValue(QDateTime::currentDateTime()));
2014 if(!graphMetaData.contains(NAO::maintainedBy()) && !app.isEmpty()) {
2015 graphMetaData.insert(NAO::maintainedBy(), findApplicationResource(app));
2018 const QUrl graph = createUri(GraphUri);
2019 const QUrl metadatagraph = createUri(GraphUri);
2022 const QString metaN3 = Soprano::Node::resourceToN3( metadatagraph );
2023 const QString graphN3 = Soprano::Node::resourceToN3( graph );
2025 QString query = QString::fromLatin1(
"sparql insert into %1 { %1 nrl:coreGraphMetadataFor %2 ;"
2026 " rdf:type nrl:GraphMetadata . %2 ")
2027 .arg( metaN3, graphN3 );
2031 it != graphMetaData.constEnd(); ++it) {
2033 query += QString::fromLatin1(
" %1 %2 ;")
2034 .arg( Soprano::Node::resourceToN3(it.key()), it.value().toN3() );
2036 query[ query.length() - 1 ] = QChar::fromLatin1(
'.');
2037 query.append( QLatin1Char(
'}') );
2039 executeQuery( query, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
2044 QUrl DataManagementModel::fetchGraph(
const QString& app,
bool discardable)
2046 QPair<QString, bool> cacheItem(app, discardable);
2047 QMutexLocker lock( &d->m_graphCacheMutex );
2048 QUrl* uri = d->m_graphCache.object( cacheItem );
2053 QLatin1String type(
"nrl:InstanceBase");
2055 type = QLatin1String(
"nrl:DiscardableInstanceBase");
2057 const QString query = QString::fromLatin1(
"select ?g where { ?g a %1 ; nao:maintainedBy ?agent ."
2058 " ?agent nao:identifier %2 . } LIMIT 1")
2059 .arg( type, Soprano::Node::literalToN3(app) );
2061 Soprano::QueryResultIterator it = executeQuery(query, Soprano::Query::QueryLanguageSparqlNoInference);
2063 QUrl uri = it[0].uri();
2064 d->m_graphCache.insert( cacheItem,
new QUrl(uri) );
2069 if( app == QLatin1String(
"nepomuk") )
2070 return createNepomukGraph();
2074 hash.insert( RDF::type(), NRL::DiscardableInstanceBase() );
2076 QUrl uri = createGraph(app, hash);
2077 d->m_graphCache.insert( cacheItem,
new QUrl(uri) );
2084 QUrl Nepomuk2::DataManagementModel::findApplicationResource(
const QString &app,
bool create)
2086 QMutexLocker lock( &d->m_appCacheMutex );
2087 QUrl* uri = d->m_appCache.object( app );
2092 Soprano::QueryResultIterator it =
2093 executeQuery(QString::fromLatin1(
"select ?r where { ?r a nao:Agent . ?r nao:identifier %1 . } LIMIT 1")
2094 .arg( Soprano::Node::literalToN3(app) ),
2095 Soprano::Query::QueryLanguageSparql);
2097 const QUrl newUri = it[0].uri();
2098 d->m_appCache.insert( app,
new QUrl(newUri) );
2103 const QUrl graph = d->m_nepomukGraph;
2104 const QUrl uri = createUri(ResourceUri);
2107 addStatement( uri, RDF::type(), NAO::Agent(), graph );
2108 addStatement( uri, NAO::identifier(), Soprano::LiteralValue(app), graph );
2110 KService::List services = KServiceTypeTrader::self()->query(QLatin1String(
"Application"),
2111 QString::fromLatin1(
"DesktopEntryName=='%1'").arg(app));
2112 if(services.count() == 1) {
2113 addStatement(uri, NAO::prefLabel(), Soprano::LiteralValue(services.first()->name()), graph);
2116 d->m_appCache.insert( app,
new QUrl(uri) );
2124 QUrl DataManagementModel::createNepomukGraph()
2128 const QUrl uri = createUri(ResourceUri);
2131 addStatement( uri, RDF::type(), NAO::Agent(), graph );
2132 addStatement( uri, NAO::identifier(), Soprano::LiteralValue(QLatin1String(
"nepomuk")), graph );
2135 QString query = QString::fromLatin1(
"select ?g where { ?g nrl:coreGraphMetadataFor %1 . }")
2136 .arg( Soprano::Node::resourceToN3(graph) );
2138 Soprano::QueryResultIterator it = executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
2140 addStatement( graph, NAO::maintainedBy(), uri, it[0] );
2146 QUrl Nepomuk2::DataManagementModel::createUri(Nepomuk2::DataManagementModel::UriType type)
2149 if(type == GraphUri)
2150 typeToken = QLatin1String(
"ctx");
2152 typeToken = QLatin1String(
"res");
2155 QString uuid = QUuid::createUuid().toString();
2156 uuid = uuid.mid(1, uuid.length()-2);
2158 QString uriString = QString::fromLatin1(
"nepomuk:/%1/%2").arg( typeToken, uuid );
2159 return QUrl( uriString );
2166 kDebug() << resources <<
property << nodes << app;
2167 Q_ASSERT(!resources.isEmpty());
2168 Q_ASSERT(!nodes.isEmpty());
2169 Q_ASSERT(!property.isEmpty());
2174 const int maxCardinality = d->m_classAndPropertyTree->maxCardinality(property);
2175 if( maxCardinality == 1 ) {
2176 if( nodes.size() != 1 ) {
2177 setError(QString::fromLatin1(
"%1 has cardinality of 1. Cannot set more then one value.").arg(property.toString()), Soprano::Error::ErrorInvalidArgument);
2186 if( property == NIE::url() )
2187 graph = d->m_nepomukGraph;
2189 graph = fetchGraph(app);
2193 QString insertQ = QString::fromLatin1(
"sparql insert into %1 {").arg( Soprano::Node::resourceToN3(graph) );
2194 const QString propN3 = Soprano::Node::resourceToN3(property);
2196 foreach(
const QUrl& resUri, resources) {
2197 const QString resN3 = Soprano::Node::resourceToN3(resUri);
2198 foreach(
const Soprano::Node& node, nodes) {
2199 insertQ += QString::fromLatin1(
" %1 %2 %3 . ").arg( resN3, propN3, node.toN3() );
2200 finalValuesPerResource[resUri].append(node);
2203 insertQ += QLatin1String(
"}");
2204 executeQuery( insertQ, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
2207 if(signalPropertyChanged) {
2208 for(
QHash<QUrl, QList<Soprano::Node> >::const_iterator it = finalValuesPerResource.constBegin(); it != finalValuesPerResource.constEnd(); ++it) {
2209 d->m_watchManager->changeProperty(it.key(), property, it.value(), QList<Soprano::Node>());
2211 if(!finalValuesPerResource.isEmpty()) {
2212 d->m_watchManager->changeSomething();
2218 QSet<QUrl> finalResources = finalValuesPerResource.keys().toSet();
2219 updateModificationDate( finalResources );
2221 return finalValuesPerResource;
2224 bool Nepomuk2::DataManagementModel::doesResourceExist(
const QUrl &res,
const QUrl& graph)
const
2226 if(graph.isEmpty()) {
2227 return executeQuery(QString::fromLatin1(
"ask where { %1 ?p ?v . FILTER(%2) . }")
2228 .arg(Soprano::Node::resourceToN3(res),
2229 createResourceMetadataPropertyFilter(QLatin1String(
"?p"))),
2230 Soprano::Query::QueryLanguageSparql).boolValue();
2233 return executeQuery(QString::fromLatin1(
"ask where { graph %1 { %2 ?p ?v . FILTER(%3) . } . }")
2234 .arg(Soprano::Node::resourceToN3(graph),
2235 Soprano::Node::resourceToN3(res),
2236 createResourceMetadataPropertyFilter(QLatin1String(
"?p"))),
2237 Soprano::Query::QueryLanguageSparql).boolValue();
2241 QList<QUrl> DataManagementModel::resolveUrls(
const QList<QUrl>& urls,
const QString& app,
bool statLocalFiles)
2243 QList<QUrl> nieUrls;
2244 QList<QUrl> finalUrls;
2245 finalUrls.reserve( urls.size() );
2247 Q_FOREACH(
const QUrl& url, urls) {
2248 const QUrl resolved = resolveUrl(url, statLocalFiles);
2250 return QList<QUrl>();
2252 if( resolved.isEmpty() )
2255 finalUrls << resolved;
2259 if( statLocalFiles && !app.isEmpty() ) {
2260 const QUrl graph = fetchGraph( app );
2261 finalUrls.append( createFileResources(nieUrls, graph) );
2267 QUrl Nepomuk2::DataManagementModel::resolveUrl(
const QUrl &url,
bool statLocalFiles)
2269 const UriState state = uriState( url, statLocalFiles );
2271 if( state == NepomukUri || state == OntologyUri ) {
2279 else if( executeQuery(QString::fromLatin1(
"ask where { %1 ?p ?o . }")
2280 .arg(Soprano::Node::resourceToN3(url)),
2281 Soprano::Query::QueryLanguageSparql).boolValue() ) {
2291 Soprano::QueryResultIterator it
2292 = executeQuery(QString::fromLatin1(
"select ?r where { ?r %1 %2 . } limit 1")
2293 .arg(Soprano::Node::resourceToN3(NIE::url()),
2294 Soprano::Node::resourceToN3(url)),
2295 Soprano::Query::QueryLanguageSparql);
2303 else if( state == OtherUri ) {
2304 QString error = QString::fromLatin1(
"Unknown protocol '%1' encountered in '%2'.")
2305 .arg(url.scheme(), url.toString());
2306 setError(error, Soprano::Error::ErrorInvalidArgument);
2313 if(state == NonExistingFileUrl) {
2314 setError(QString::fromLatin1(
"Cannot store information about non-existing local files. File '%1' does not exist.").arg(url.toLocalFile()),
2315 Soprano::Error::ErrorInvalidArgument);
2327 QList<Soprano::Node> DataManagementModel::resolveNodes(
const QSet< Soprano::Node >& nodes,
const QString& app)
2329 QList<QUrl> nieUrls;
2330 QList<Soprano::Node> resolvedNodes;
2331 resolvedNodes.reserve( nodes.size() );
2333 Q_FOREACH(
const Soprano::Node& node, nodes) {
2334 if(node.isResource()) {
2335 const QUrl resolved = resolveUrl(node.uri(),
true);
2336 if(resolved.isEmpty() && lastError()) {
2337 return QList<Soprano::Node>();
2340 if(resolved.isEmpty())
2341 nieUrls << node.uri();
2343 resolvedNodes << resolved;
2346 resolvedNodes << node;
2350 const QUrl graph = fetchGraph( app );
2351 QList<QUrl> fileResources = createFileResources( nieUrls, graph );
2352 foreach(
const QUrl& resUri, fileResources)
2353 resolvedNodes << resUri;
2355 return resolvedNodes;
2359 QList<QUrl> DataManagementModel::createFileResources(
const QList< QUrl >& nieUrls,
const QUrl& graph)
2361 if(nieUrls.isEmpty())
2362 return QList<QUrl>();
2364 QList<QUrl> resUriList;
2366 QString query = QString::fromLatin1(
"sparql insert into %1 { ").arg( Soprano::Node::resourceToN3(graph) );
2367 QString query2 = QString::fromLatin1(
"sparql insert into %1 { ").arg( Soprano::Node::resourceToN3(d->m_nepomukGraph) );
2369 foreach(
const QUrl& nieUrl, nieUrls ) {
2370 const QUrl resUri = createUri( ResourceUri );
2371 const QString resN3 = Soprano::Node::resourceToN3(resUri);
2375 resUriList << resUri;
2377 QFileInfo fileInfo( nieUrl.toLocalFile() );
2378 if( fileInfo.isDir() )
2379 query += QLatin1String(
" a nfo:FileDataObject, nfo:Folder . ");
2381 query += QLatin1String(
" a nfo:FileDataObject . ");
2384 query2 += QString::fromLatin1(
" nie:url %1 ; ").arg( Soprano::Node::resourceToN3(nieUrl) );
2386 Soprano::LiteralValue dtNode( QDateTime::currentDateTime() );
2387 query2 += QString::fromLatin1(
"nao:lastModified %1 ; nao:created %1 . ")
2388 .arg( Soprano::Node::literalToN3( dtNode ) );
2390 query += QLatin1Char(
'}');
2391 query2 += QLatin1Char(
'}');
2393 executeQuery( query, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
2394 executeQuery( query2, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
2399 bool Nepomuk2::DataManagementModel::updateNieUrlOnLocalFile(
const QUrl &resource,
const QUrl &nieUrl)
2401 if( !nieUrl.isLocalFile() )
2404 kDebug() << resource <<
"->" << nieUrl;
2421 QUrl resUri, oldNieUrl, oldNieUrlGraph, oldParentResource, oldParentResourceGraph, oldFileNameGraph;
2422 QString oldFileName;
2425 if(resource.scheme() == QLatin1String(
"file")) {
2426 oldNieUrl = resource;
2427 Soprano::QueryResultIterator it
2428 = executeQuery(QString::fromLatin1(
"select distinct ?gu ?gf ?gp ?r ?f ?p where { "
2429 "graph ?gu { ?r %2 %1 . } . "
2430 "OPTIONAL { graph ?gf { ?r %3 ?f . } . } . "
2431 "OPTIONAL { graph ?gp { ?r %4 ?p . } . } . "
2433 .arg(Soprano::Node::resourceToN3(resource),
2434 Soprano::Node::resourceToN3(NIE::url()),
2435 Soprano::Node::resourceToN3(NFO::fileName()),
2436 Soprano::Node::resourceToN3(NIE::isPartOf())),
2437 Soprano::Query::QueryLanguageSparql);
2439 resUri= it[
"r"].uri();
2440 oldNieUrlGraph = it[
"gu"].uri();
2441 oldParentResource = it[
"p"].uri();
2442 oldParentResourceGraph = it[
"gp"].uri();
2443 oldFileName = it[
"f"].toString();
2444 oldFileNameGraph = it[
"gf"].uri();
2449 Soprano::QueryResultIterator it
2450 = executeQuery(QString::fromLatin1(
"select distinct ?gu ?gf ?gp ?u ?f ?p where { "
2451 "graph ?gu { %1 %2 ?u . } . "
2452 "OPTIONAL { graph ?gf { %1 %3 ?f . } . } . "
2453 "OPTIONAL { graph ?gp { %1 %4 ?p . } . } . "
2455 .arg(Soprano::Node::resourceToN3(resource),
2456 Soprano::Node::resourceToN3(NIE::url()),
2457 Soprano::Node::resourceToN3(NFO::fileName()),
2458 Soprano::Node::resourceToN3(NIE::isPartOf())),
2459 Soprano::Query::QueryLanguageSparql);
2461 oldNieUrl = it[
"u"].uri();
2462 oldNieUrlGraph = it[
"gu"].uri();
2463 oldParentResource = it[
"p"].uri();
2464 oldParentResourceGraph = it[
"gp"].uri();
2465 oldFileName = it[
"f"].toString();
2466 oldFileNameGraph = it[
"gf"].uri();
2470 if (!oldNieUrlGraph.isEmpty()) {
2471 const QString oldBasePath = KUrl(oldNieUrl).path(KUrl::AddTrailingSlash);
2472 const QString newBasePath = KUrl(nieUrl).path(KUrl::AddTrailingSlash);
2474 if( oldBasePath == newBasePath )
2477 removeStatement(resUri, NIE::url(), oldNieUrl, oldNieUrlGraph);
2478 addStatement(resUri, NIE::url(), nieUrl, oldNieUrlGraph);
2480 d->m_watchManager->changeProperty( resource, NIE::url(),
2481 QList<Soprano::Node>() << nieUrl,
2482 QList<Soprano::Node>() << oldNieUrl );
2484 if (!oldFileNameGraph.isEmpty()) {
2486 if(KUrl(oldNieUrl).fileName() != KUrl(nieUrl).fileName()) {
2487 Soprano::Node oldN = Soprano::LiteralValue(oldFileName);
2488 Soprano::Node newN = Soprano::LiteralValue(KUrl(nieUrl).fileName());
2490 removeStatement(resUri, NFO::fileName(), oldN, oldFileNameGraph);
2491 addStatement(resUri, NFO::fileName(), newN, oldFileNameGraph);
2493 d->m_watchManager->changeProperty( resource, NIE::url(),
2494 QList<Soprano::Node>() << newN,
2495 QList<Soprano::Node>() << oldN );
2499 if (!oldParentResourceGraph.isEmpty()) {
2501 const KUrl nieUrlParent = KUrl(nieUrl).directory(KUrl::IgnoreTrailingSlash);
2502 const KUrl oldUrlParent = KUrl(oldNieUrl).directory(KUrl::IgnoreTrailingSlash);
2503 if(nieUrlParent != oldUrlParent) {
2504 removeStatement(resUri, NIE::isPartOf(), oldParentResource, oldParentResourceGraph);
2505 const QUrl newParentRes = resolveUrl(nieUrlParent);
2506 if (!newParentRes.isEmpty()) {
2507 addStatement(resUri, NIE::isPartOf(), newParentRes, oldParentResourceGraph);
2520 const QString query = QString::fromLatin1(
"select distinct ?r ?u where { "
2522 "FILTER(REGEX(STR(?u),'^%2')) . "
2524 .arg(Soprano::Node::resourceToN3(NIE::url()),
2525 KUrl(oldNieUrl).url(KUrl::AddTrailingSlash));
2533 const QList<Soprano::BindingSet> urls = executeQuery(query + QLatin1String(
" LIMIT 500" ),
2534 Soprano::Query::QueryLanguageSparql)
2539 for (
int i = 0; i < urls.count(); ++i) {
2540 const KUrl u = urls[i][
"u"].uri();
2541 const QUrl r = urls[i][
"r"].
uri();
2544 const QString oldRelativePath = u.path().mid(oldBasePath.length());
2545 const KUrl newUrl(newBasePath + oldRelativePath);
2547 QString cmd = QString::fromLatin1(
"sparql with %1 delete { %2 nie:url %3 }"
2548 "insert { %2 nie:url %4 . }")
2549 .arg( Soprano::Node::resourceToN3(d->m_nepomukGraph),
2550 Soprano::Node::resourceToN3(r),
2551 Soprano::Node::resourceToN3(u),
2552 Soprano::Node::resourceToN3(newUrl) );
2554 executeQuery( cmd, Soprano::Query::QueryLanguageUser, QLatin1String(
"sql") );
2590 return d->m_classAndPropertyTree;
2593 bool Nepomuk2::DataManagementModel::isProtectedProperty(
const QUrl &prop)
const
2595 return d->m_protectedProperties.contains(prop);
2600 return d->m_watchManager;
2605 return d->m_typeCache;
2610 return d->m_nepomukGraph;
2614 void Nepomuk2::DataManagementModel::removeAllResources(
const QSet< QUrl >& resourceUris, RemovalFlags flags)
2616 if( resourceUris.isEmpty() )
2619 QSet<QUrl> resolvedResources(resourceUris);
2630 QSet<QUrl> subResources = resolvedResources;
2633 resCount = resolvedResources.count();
2635 QString q = QString::fromLatin1(
"select ?r where { ?r ?p ?o . "
2636 "?parent nao:hasSubResource ?r . "
2637 "FILTER(?parent in (%1)) . "
2638 "FILTER NOT EXISTS { ?r2 ?p3 ?r . FILTER(%2) . "
2639 " FILTER NOT EXISTS { ?x nao:hasSubResource ?r2 . FILTER(?x in (%1)) . } "
2642 createResourceFilter(resolvedResources, QLatin1String(
"?r2")));
2644 Soprano::QueryResultIterator it = executeQuery( q, Soprano::Query::QueryLanguageSparqlNoInference );
2645 subResources.clear();
2647 subResources << it[0].uri();
2649 resolvedResources += subResources;
2650 }
while(resCount < resolvedResources.count());
2655 QSet<QUrl> actuallyRemovedResources;
2656 Soprano::QueryResultIterator it
2657 = executeQuery(QString::fromLatin1(
"select distinct ?r where { ?r ?p ?o . FILTER(?r in (%1)) . }")
2658 .arg(
resourcesToN3(resolvedResources).join(QLatin1String(
","))),
2659 Soprano::Query::QueryLanguageSparqlNoInference);
2661 actuallyRemovedResources << it[0].uri();
2665 QSet<QUrl> modifiedResources;
2666 QList<Soprano::Statement> removedStatements;
2667 foreach(
const QUrl& resUri, resolvedResources) {
2668 it = executeQuery(QString::fromLatin1(
"select distinct ?o ?p where { ?o ?p %1 . }")
2669 .arg(Soprano::Node::resourceToN3(resUri)),
2670 Soprano::Query::QueryLanguageSparqlNoInference);
2672 modifiedResources << it[0].uri();
2673 removedStatements << Soprano::Statement(it[0].uri(), it[1].uri(), resUri);
2676 modifiedResources -= actuallyRemovedResources;
2679 foreach(
const Soprano::Node& res, actuallyRemovedResources) {
2681 d->m_watchManager->removeResource(res.uri(), QList<QUrl>());
2683 removeAllStatements(res, Soprano::Node(), Soprano::Node());
2684 removeAllStatements(Soprano::Node(), Soprano::Node(), res);
2686 updateModificationDate(modifiedResources);
2688 foreach(
const Soprano::Statement& st, removedStatements) {
2689 d->m_watchManager->changeProperty( st.subject().uri(), st.predicate().uri(),
2690 QList<Soprano::Node>(),
2691 QList<Soprano::Node>() << st.object() );
2694 if(!actuallyRemovedResources.isEmpty()) {
2695 d->m_watchManager->changeSomething();
2699 #include "datamanagementmodel.moc"
StoreIdentificationMode
The identification mode used by storeResources().
void addStatement(const Soprano::Statement &statement)
When this is enabled each SimpleResource will be checked to make sure a duplicate of it does not alre...
Exclude related resources, only include literal properties.
KJob * addProperty(const QList< QUrl > &resources, const QUrl &property, const QVariantList &values, const KComponentData &component=KGlobal::mainComponent())
Add one or more property values to one or more resources.
QHash< QUrl, QUrl > storeResources(const SimpleResourceGraph &resources, const QString &app, Nepomuk2::StoreIdentificationMode identificationMode=Nepomuk2::IdentifyNew, Nepomuk2::StoreResourcesFlags flags=Nepomuk2::NoStoreResourcesFlags, const QHash< QUrl, QVariant > &additionalMetadata=(QHash< QUrl, QVariant >()))
Exclude discardable data, ie. data which can be re-generated.
void removeResources(const QList< QUrl > &resources, Nepomuk2::RemovalFlags flags, const QString &app)
Remove resources from the database.
Soprano::Graph toStatementGraph() const
Represents a snapshot of one Nepomuk resource.
void mergeResources(const QList< QUrl > &resources, const QString &app)
Merges all the resources into one.
PropertyHash properties() const
KJob * mergeResources(const QUrl &resource1, const QUrl &resource2, const KComponentData &component=KGlobal::mainComponent())
Merge two resources into one.
void removeProperty(const QList< QUrl > &resources, const QUrl &property, const QVariantList &values, const QString &app)
Remove the property property with values from each resource in resources.
void setProperty(const QList< QUrl > &resources, const QUrl &property, const QVariantList &values, const QString &app)
Set, ie.
QString exportResources(const QList< QUrl > &resources, Soprano::RdfSerialization serialization, const QString &userSerialization=QString(), DescribeResourcesFlags flags=NoDescribeResourcesFlags, const QList< QUrl > &targetParties=QList< QUrl >())
Export a set of resources, i.e.
bool contains(const QUrl &uri) const
Returns true if the uri is a Class or a Property.
void addProperty(const QUrl &property, const QVariant &value)
Add a property.
DescribeResourcesJob * describeResources(const QList< QUrl > &resources, DescribeResourcesFlags flags=NoDescribeResourcesFlags, const QList< QUrl > &targetParties=QList< QUrl >())
Retrieve all information about a set of resources.
QUrl createResource(const QList< QUrl > &types, const QString &label, const QString &description, const QString &app)
Create a new resource with several types.
void remove(const QUrl &uri)
Replaces the resouce URIs which are specific to this instance of Nepomuk with blank nodes...
SimpleResourceGraph describeResources(const QList< QUrl > &resources, DescribeResourcesFlags flags=NoDescribeResourcesFlags, const QList< QUrl > &targetParties=QList< QUrl >())
Describe a set of resources, i.e.
QList< Soprano::Statement > toStatementList() const
void addProperty(const QList< QUrl > &resources, const QUrl &property, const QVariantList &values, const QString &app)
Add property with values to each resource from resources.
static ClassAndPropertyTree * self()
void removeAll(const QUrl &uri, const QUrl &property, const QVariant &value=QVariant())
Remove all properties matching the provided parameters.
void importResources(const QUrl &url, const QString &app, Soprano::RdfSerialization serialization, const QString &userSerialization=QString(), Nepomuk2::StoreIdentificationMode identificationMode=Nepomuk2::IdentifyNew, Nepomuk2::StoreResourcesFlags flags=Nepomuk2::NoStoreResourcesFlags, const QHash< QUrl, QVariant > &additionalMetadata=(QHash< QUrl, QVariant >()))
Import an RDF graph from a URL.
DataManagementModel(ClassAndPropertyTree *tree, Soprano::Model *model, QObject *parent=0)
StoreResourcesJob * storeResources(const Nepomuk2::SimpleResourceGraph &resources, Nepomuk2::StoreIdentificationMode identificationMode=Nepomuk2::IdentifyNew, Nepomuk2::StoreResourcesFlags flags=Nepomuk2::NoStoreResourcesFlags, const QHash< QUrl, QVariant > &additionalMetadata=QHash< QUrl, QVariant >(), const KComponentData &component=KGlobal::mainComponent())
Store many resources at once.
void removeDataByApplication(const QList< QUrl > &resources, RemovalFlags flags, const QString &app)
Remove all information about resources from the database which have been created by a specific applic...
void clearCache()
Clear the internal cache present in the model.
ResourceWatcherManager * resourceWatcherManager() const
used by the unit tests
KJob * removeProperties(const QList< QUrl > &resources, const QList< QUrl > &properties, const KComponentData &component=KGlobal::mainComponent())
Remove one or more properties from one or more resources.
QList< QUrl > allResourceUris() const
Get a list of the URIs of all resources in this graph.
uint qHash(const SimpleResource &res)
void setUri(const Soprano::Node &node)
If node is resource node the uri is set to the node's uri Otherwise if node is a blank node then the ...
KJob * removeResources(const QList< QUrl > &resources, Nepomuk2::RemovalFlags flags=Nepomuk2::NoRemovalFlags, const KComponentData &component=KGlobal::mainComponent())
Completely remove resources from the database.
QStringList resourcesToN3(const T &urls)
Convert a list or set or QUrls into a list of N3 formatted strings.
bool contains(const SimpleResource &res) const
void removeProperties(const QList< QUrl > &resources, const QList< QUrl > &properties, const QString &app)
Remove all statements involving any proerty from properties from all resources in resources...
Remove sub resources of the resources specified in the parameters.
A SyncResource is a convenient way of storing a set of properties and objects for a common subject...
No flags - default behaviour.
void setUri(const QUrl &uri)
Setting an invalid/empty uri will create a new random ID.