• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Nepomuk-Core

  • sources
  • kde-4.12
  • kdelibs
  • nepomuk-core
  • services
  • storage
resourcemerger.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the Nepomuk KDE project.
3  Copyright (C) 2011-13 Vishesh Handa <handa.vish@gmail.com>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 
20 
21 #include "resourcemerger.h"
22 #include "datamanagementmodel.h"
23 #include "classandpropertytree.h"
24 #include "nepomuktools.h"
25 
26 #include <Soprano/Vocabulary/NRL>
27 #include <Soprano/Vocabulary/RDF>
28 #include <Soprano/Vocabulary/RDFS>
29 #include <Soprano/Vocabulary/NAO>
30 #include <Soprano/Vocabulary/XMLSchema>
31 
32 #include <Soprano/StatementIterator>
33 #include <Soprano/QueryResultIterator>
34 #include <Soprano/FilterModel>
35 #include <Soprano/NodeIterator>
36 #include <Soprano/LiteralValue>
37 #include <Soprano/Node>
38 
39 #include "nie.h"
40 
41 #include <KDebug>
42 #include <Soprano/Graph>
43 #include "resourcewatchermanager.h"
44 #include "typecache.h"
45 
46 using namespace Soprano::Vocabulary;
47 using namespace Nepomuk2::Vocabulary;
48 
49 
50 namespace {
51  QUrl getBlankOrResourceUri( const Soprano::Node & n ) {
52  if( n.isResource() ) {
53  return n.uri();
54  }
55  else if( n.isBlank() ) {
56  return QString( QLatin1String("_:") + n.identifier() );
57  }
58  return QUrl();
59  }
60 
61  QUrl xsdDuration() {
62  return QUrl( Soprano::Vocabulary::XMLSchema::xsdNamespace().toString() + QLatin1String("duration") );
63  }
64 
65  template<typename T> QStringList nodesToN3( const T &nodes ) {
66  QStringList list;
67  foreach( const Soprano::Node& node, nodes ) {
68  list << node.toN3();
69  }
70  return list;
71  }
72 
73  template<typename T> QStringList urlsToN3( const T &urls ) {
74  QStringList list;
75  foreach( const QUrl& uri, urls ) {
76  list << Soprano::Node::resourceToN3(uri);
77  }
78  return list;
79  }
80 
81  QList<QUrl> nodeListToUriList( const QList<Soprano::Node>& nodeList ) {
82  QList<QUrl> urls;
83  urls.reserve( nodeList.size() );
84  foreach( const Soprano::Node& node, nodeList )
85  urls << node.uri();
86  return urls;
87  }
88 }
89 
90 Nepomuk2::ResourceMerger::ResourceMerger(Nepomuk2::DataManagementModel* model, const QString& app,
91  const Nepomuk2::StoreResourcesFlags& flags, bool discardable )
92 {
93  m_app = app;
94  m_discardbale = discardable;
95  m_model = model;
96  m_flags = flags;
97  m_rvm = model->resourceWatcherManager();
98 
99  //setModel( m_model );
100  // Resource Metadata
101  metadataProperties.reserve( 4 );
102  metadataProperties.insert( NAO::lastModified() );
103  metadataProperties.insert( NAO::userVisible() );
104  metadataProperties.insert( NAO::created() );
105  metadataProperties.insert( NAO::creator() );
106 }
107 
108 
109 Nepomuk2::ResourceMerger::~ResourceMerger()
110 {
111 }
112 
113 void Nepomuk2::ResourceMerger::setMappings(const QHash< QUrl, QUrl >& mappings)
114 {
115  m_mappings = mappings;
116 }
117 
118 QHash< QUrl, QUrl > Nepomuk2::ResourceMerger::mappings() const
119 {
120  return m_mappings;
121 }
122 
123 
124 bool Nepomuk2::ResourceMerger::push(const QUrl& graph, const Nepomuk2::Sync::ResourceHash& resHash)
125 {
126  if( resHash.isEmpty() || graph.isEmpty() )
127  return true; /* Silently fail, nothing bad has happened */
128 
129  ClassAndPropertyTree *tree = ClassAndPropertyTree::self();
130 
131  const bool lazy = (m_flags & LazyCardinalities);
132  const bool overwrite = (m_flags & OverwriteProperties);
133  const bool overwriteAll = (m_flags & OverwriteAllProperties);
134 
135  const QString preQuery = QString::fromLatin1("sparql insert into %1 { ")
136  .arg( Soprano::Node::resourceToN3( graph ) );
137 
138  QString query;
139  QHashIterator<KUrl, Sync::SyncResource> it( resHash );
140  while( it.hasNext() ) {
141  const Sync::SyncResource& res = it.next().value();
142 
143  const QString resN3 = Soprano::Node::resourceToN3( res.uri() );
144  query += resN3;
145 
146  QList<QUrl> propertiesToRemove;
147  QList<KUrl> properties = res.uniqueKeys();
148  foreach( const QUrl& prop, properties ) {
149  QList<Soprano::Node> values = res.values( prop );
150  const QString propN3 = Soprano::Node::resourceToN3( prop );
151 
152  if( lazy || overwrite || overwriteAll ) {
153  if( tree->maxCardinality( prop ) == 1 || overwriteAll ) {
154  QString query = QString::fromLatin1("select ?o where { %1 %2 ?o . }")
155  .arg( resN3, propN3 );
156 
157  Soprano::QueryResultIterator it = m_model->executeQuery(query, Soprano::Query::QueryLanguageSparqlNoInference);
158  while (it.next()) {
159  m_resRemoveHash[ res.uri() ].insert( prop, it[0] );
160  }
161  propertiesToRemove << prop;
162 
163  // In LazyCardinalities we don't care about the cardinality
164  if( lazy )
165  values = QList<Soprano::Node>() << values.first();
166  }
167  }
168 
169  query += QString::fromLatin1(" %1 %2 ;").arg( propN3, nodesToN3(values).join(QString(", ")) );
170  }
171 
172  query[ query.length() - 1 ] = '.';
173 
174  // Remove the properties
175  if( propertiesToRemove.count() ) {
176  QString query = QString::fromLatin1("sparql delete { graph ?g { %1 ?p ?o.} } where { "
177  " graph ?g { %1 ?p ?o. } FILTER(?p in(%2)) . }")
178  .arg( resN3, urlsToN3(propertiesToRemove).join(",") );
179 
180  m_model->executeQuery( query, Soprano::Query::QueryLanguageUser, QLatin1String("sql") );
181  }
182 
183  // Virtuoso does not like commands that are too long. So we use an arbitary limit of 500 characters.
184  if( query.size() >= 500 ) {
185  QString command = QString::fromLatin1("%1 %2 }").arg( preQuery, query );
186  m_model->executeQuery( command, Soprano::Query::QueryLanguageUser, QLatin1String("sql") );
187  if( m_model->lastError() ) {
188  setError( m_model->lastError() );
189  return false;
190  }
191  query.clear();
192  }
193  }
194 
195  if( !query.isEmpty() ) {
196  QString command = QString::fromLatin1("%1 %2 }").arg( preQuery, query );
197 
198  // We use sql instead of sparql so that we can avoid any changes done by any of the other models
199  m_model->executeQuery( command, Soprano::Query::QueryLanguageUser, QLatin1String("sql") );
200  if( m_model->lastError() ) {
201  setError( m_model->lastError() );
202  return false;
203  }
204  }
205 
206  return true;
207 }
208 
209 
210 
211 bool Nepomuk2::ResourceMerger::isOfType(const Soprano::Node & node, const QUrl& type, const QList<QUrl> & newTypes) const
212 {
213  //kDebug() << "Checking " << node << " for type " << type;
214  ClassAndPropertyTree * tree = m_model->classAndPropertyTree();
215 
216  QList<QUrl> types( newTypes );
217  if( !node.isBlank() ) {
218  types << m_model->typeCache()->types( node.uri() );
219  }
220  types += newTypes;
221 
222  if( types.isEmpty() ) {
223  kDebug() << node << " does not have a type!!";
224  return false;
225  }
226 
227  foreach( const QUrl & uri, types ) {
228  if( uri == type || tree->isChildOf( uri, type ) ) {
229  return true;
230  }
231  }
232 
233  return false;
234 }
235 
236 Soprano::Node Nepomuk2::ResourceMerger::resolveMappedNode(const Soprano::Node& node)
237 {
238  // Find in mappings
239  const QUrl uri = node.isBlank() ? node.toN3() : node.uri();
240  QHash< QUrl, QUrl >::const_iterator it = m_mappings.constFind( uri );
241  if( it != m_mappings.constEnd() ) {
242  return it.value();
243  }
244 
245  // Do not resolve the blank nodes which need to be created
246  if( node.isBlank() )
247  return node;
248 
249  if( uri.scheme() == QLatin1String("nepomuk") &&
250  !m_model->containsAnyStatement( uri, Soprano::Node(), Soprano::Node() ) ) {
251  QString error = QString::fromLatin1("Could not resolve %1. "
252  "You cannot create nepomuk uris using this method")
253  .arg( Soprano::Node::resourceToN3( uri ) );
254  setError( error, Soprano::Error::ErrorInvalidArgument );
255  return Soprano::Node();
256  }
257 
258  return node;
259 }
260 
261 Soprano::Node Nepomuk2::ResourceMerger::resolveBlankNode(const Soprano::Node& node)
262 {
263  if( !node.isBlank() )
264  return node;
265 
266  const QUrl nodeN3( node.toN3() );
267  QHash< QUrl, QUrl >::const_iterator it = m_mappings.constFind( nodeN3 );
268  if( it != m_mappings.constEnd() ) {
269  return it.value();
270  }
271 
272  const QUrl newUri = m_model->createUri( DataManagementModel::ResourceUri );
273  m_mappings.insert( nodeN3, newUri );
274  m_newUris.insert( newUri );
275 
276  return newUri;
277 }
278 
279 
280 Nepomuk2::Sync::ResourceHash Nepomuk2::ResourceMerger::resolveBlankNodes(const Nepomuk2::Sync::ResourceHash& resHash_)
281 {
282  Sync::ResourceHash resHash;
283 
284  QHashIterator<KUrl, Sync::SyncResource> it( resHash_ );
285  while( it.hasNext() ) {
286  Sync::SyncResource res = it.next().value();
287 
288  res.setUri( resolveBlankNode( res.uriNode() ) );
289 
290  QMutableHashIterator<KUrl, Soprano::Node> it( res );
291  while( it.hasNext() ) {
292  it.next();
293  it.setValue( resolveBlankNode(it.value()) );
294  }
295 
296  resHash.insert( res.uri(), res );
297  }
298 
299  return resHash;
300 }
301 
302 
303 bool Nepomuk2::ResourceMerger::merge(const Nepomuk2::Sync::ResourceHash& resHash_)
304 {
305  //
306  // 1. Resolve all the mapped statements
307  //
308  Sync::ResourceHash resHash;
309  QHashIterator<KUrl, Sync::SyncResource> it_( resHash_ );
310  while( it_.hasNext() ) {
311  Sync::SyncResource res = it_.next().value();
312  res.setUri( resolveMappedNode(res.uri()) );
313  if( lastError() )
314  return false;
315 
316  QMutableHashIterator<KUrl, Soprano::Node> iter( res );
317  while( iter.hasNext() ) {
318  Soprano::Node& object = iter.next().value();
319  if( ( object.isResource() && object.uri().scheme() == QLatin1String("nepomuk") ) || object.isBlank() )
320  object = resolveMappedNode( object );
321 
322  if( lastError() )
323  return false;
324  }
325 
326  resHash.insert( res.uri(), res );
327  }
328 
329  Soprano::LiteralValue currentDateTime( QDateTime::currentDateTime() );
330 
331  //
332  // 2. Move the metadata from resHash to the metadataHash
333  //
334  Sync::ResourceHash resMetadataHash;
335  QStringList resN3List;
336 
337  QMutableHashIterator<KUrl, Sync::SyncResource> it( resHash );
338  while( it.hasNext() ) {
339  Sync::SyncResource& res = it.next().value();
340 
341  Sync::SyncResource metadataRes( res.uri() );
342 
343  // Remove the metadata properties - nao:lastModified and nao:created
344  QHash<KUrl, Soprano::Node>::iterator fit = res.find( NAO::lastModified() );
345  if( fit != res.end() ) {
346  metadataRes.insert( NAO::lastModified(), fit.value() );
347  res.erase( fit );
348  }
349  else {
350  metadataRes.insert( NAO::lastModified(), currentDateTime );
351  }
352 
353  if( !res.isBlank() )
354  resN3List << Soprano::Node::resourceToN3(res.uri());
355 
356  fit = res.find( NAO::created() );
357  if( fit != res.end() ) {
358  // We do not allow the nao:created to be changed
359  if( res.isBlank() )
360  metadataRes.insert( NAO::created(), fit.value() );
361 
362  res.erase( fit );
363  }
364  else {
365  if( res.isBlank() )
366  metadataRes.insert( NAO::created(), currentDateTime );
367  }
368 
369  // Also move the nie:url
370  fit = res.find( NIE::url() );
371  if( fit != res.end() ) {
372  metadataRes.insert( NIE::url(), fit.value() );
373  res.erase( fit );
374  }
375 
376  resMetadataHash.insert( metadataRes.uri(), metadataRes );
377 
378  if( !hasValidData( resHash, res ) )
379  return false;
380 
381  }
382 
383  // nao:lastModified
384  if( resN3List.count() ) {
385  QString removeCommand = QString::fromLatin1("sparql delete from %1 { ?r nao:lastModified ?m . } where"
386  "{ graph %1 { ?r nao:lastModified ?m . FILTER(?r in (%2)) .} }")
387  .arg( Soprano::Node::resourceToN3(m_model->nepomukGraph()),
388  resN3List.join(",") );
389  m_model->executeQuery( removeCommand, Soprano::Query::QueryLanguageUser, QLatin1String("sql") );
390  }
391  resN3List.clear();
392 
393  // Create the main graph, if they are any statements to merge
394  if( !resHash.isEmpty() ) {
395  m_graph = m_model->fetchGraph(m_app, m_discardbale);
396  if( m_graph.isEmpty() || m_model->lastError() )
397  return false;
398  }
399 
400 
401  // 6. Create all the blank nodes
402  resHash = resolveBlankNodes( resHash );
403  resMetadataHash = resolveBlankNodes( resMetadataHash );
404 
405  //
406  // Actual statement pushing
407  //
408 
409  // Push the data in one go
410  if( !push( m_graph, resHash ) )
411  return false;
412 
413  if( !push( m_model->nepomukGraph(), resMetadataHash ) )
414  return false;
415 
416  //
417  // Resource Watcher
418  //
419 
420  // Inform the ResourceWatcherManager of the new resources
421  QSetIterator<QUrl> newUriIt( m_newUris );
422  while( newUriIt.hasNext() ) {
423  const QUrl newUri = newUriIt.next();
424 
425  QList<Soprano::Node> types = resHash[ newUri ].values( RDF::type() );
426  QSet<QUrl> allTypes = ClassAndPropertyTree::self()->allParents( nodeListToUriList(types) );
427  m_rvm->createResource( newUri, allTypes );
428  }
429 
430  // Inform the ResourceWatcherManager of the changed properties
431  QHashIterator<KUrl, Sync::SyncResource> iter( resHash );
432  while( iter.hasNext() ) {
433  const Sync::SyncResource& res = iter.next().value();
434  const Sync::SyncResource& removedRes = m_resRemoveHash.value( res.uri() );
435 
436  // FIXME: More efficient way of traversing the multi hash?
437  const QList<KUrl> properties = res.uniqueKeys();
438  foreach( const KUrl& propUri, properties ) {
439  if( metadataProperties.contains( propUri ) )
440  continue;
441 
442  const QList<Soprano::Node> added = res.values( propUri );
443  const QList<Soprano::Node> removed = removedRes.values( propUri );
444 
445  m_rvm->changeProperty( res.uri(), propUri, added, removed );
446  }
447  }
448 
449  return true;
450 }
451 
452 bool Nepomuk2::ResourceMerger::hasValidData(const QHash<KUrl, Nepomuk2::Sync::SyncResource>& resHash,
453  Nepomuk2::Sync::SyncResource& res)
454 {
455  // Remove the types for now, will add again later
456  // There is no point in checking the domain and range of rdf:type
457  QList<Soprano::Node> resNodeTypes = res.values( RDF::type() );
458  QList<QUrl> resTypes = nodeListToUriList( resNodeTypes );
459  res.remove( RDF::type() );
460 
461  // FIXME: Optimize iteration over a multi hash
462  QList<KUrl> properties = res.uniqueKeys();
463  foreach( const KUrl& propUri, properties ) {
464  QList<Soprano::Node> objectValues = res.values( propUri );
465 
466  //
467  // 3.a Check the max cardinality
468  //
469  bool overwriteProperties = (m_flags & OverwriteProperties) | (m_flags & OverwriteAllProperties);
470  bool lazyCardinalities = (m_flags & LazyCardinalities);
471 
472  if( !lazyCardinalities ) {
473  int maxCardinality = ClassAndPropertyTree::self()->maxCardinality( propUri );
474  if( maxCardinality > 0 ) {
475 
476  QStringList filterStringList;
477  QStringList objectN3 = nodesToN3( objectValues );
478  foreach( const QString &n3, objectN3 )
479  filterStringList << QString::fromLatin1("?v!=%1").arg( n3 );
480 
481  int existingCardinality = 0;
482 
483  if( !res.isBlank() && !overwriteProperties ) {
484  if( maxCardinality > 1 ) {
485  const QString query = QString::fromLatin1("select count(distinct ?v) where {"
486  " %1 %2 ?v . FILTER( %3 ) . }")
487  .arg( Soprano::Node::resourceToN3( res.uri() ),
488  Soprano::Node::resourceToN3( propUri ),
489  filterStringList.join( QLatin1String(" && ") ) );
490 
491  Soprano::QueryResultIterator exCarIt =
492  m_model->executeQuery( query, Soprano::Query::QueryLanguageSparql );
493  if( exCarIt.next() ) {
494  existingCardinality = exCarIt[0].literal().toInt();
495  }
496  }
497  else {
498  QString query = QString::fromLatin1("ask where { %1 %2 ?v . FILTER(%3) .}")
499  .arg( Soprano::Node::resourceToN3( res.uri() ),
500  Soprano::Node::resourceToN3( propUri ),
501  filterStringList.first() );
502 
503  bool e = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference ).boolValue();
504  if( e )
505  existingCardinality = 1;
506  }
507  }
508 
509  const int newCardinality = objectValues.size() + existingCardinality;
510  if( newCardinality > maxCardinality ) {
511  //
512  // Display a very informative error message
513  //
514  QString query = QString::fromLatin1("select distinct ?v where {" " %1 %2 ?v ."
515  "FILTER( %3 ) . }")
516  .arg( Soprano::Node::resourceToN3( res.uri() ),
517  Soprano::Node::resourceToN3( propUri ),
518  filterStringList.join( QLatin1String(" && ") ) );
519  QList< Soprano::Node > existingValues = m_model->executeQuery( query,
520  Soprano::Query::QueryLanguageSparql ).iterateBindings(0).allNodes();
521 
522  QString error = QString::fromLatin1("%1 has a max cardinality of %2. Provided "
523  "%3 values - %4. Existing - %5")
524  .arg( propUri.url(),
525  QString::number(maxCardinality),
526  QString::number(objectN3.size()),
527  objectN3.join(QLatin1String(", ")),
528  nodesToN3(existingValues).join(QLatin1String(", ")) );
529  setError( error, Soprano::Error::ErrorInvalidStatement );
530  return false;
531  }
532  } // if ( maxCardinality > 0 )
533  }
534 
535  //
536  // 3.b Check the domain and range
537  //
538  ClassAndPropertyTree* tree = ClassAndPropertyTree::self();
539  QUrl domain = tree->propertyDomain( propUri );
540  QUrl range = tree->propertyRange( propUri );
541 
542  // kDebug() << "Domain : " << domain;
543  // kDebug() << "Range : " << range;
544 
545  // domain
546  if( !domain.isEmpty() && !isOfType( res.uriNode(), domain, resTypes ) ) {
547  // Error
548  QList<QUrl> allTypes = ( resTypes + m_model->typeCache()->types(res.uri()) );
549 
550  QString error = QString::fromLatin1("%1 has a rdfs:domain of %2. "
551  "%3 only has the following types %4" )
552  .arg( Soprano::Node::resourceToN3( propUri ),
553  Soprano::Node::resourceToN3( domain ),
554  Soprano::Node::resourceToN3( res.uri() ),
555  Nepomuk2::resourcesToN3( allTypes ).join(", ") );
556  setError( error, Soprano::Error::ErrorInvalidArgument);
557  return false;
558  }
559 
560  // range
561  if( range.isEmpty() )
562  continue;
563 
564  foreach( const Soprano::Node& object, objectValues ) {
565  if( object.isResource() || object.isBlank() ) {
566  const QUrl objUri = getBlankOrResourceUri( object );
567  QList<QUrl> objectNewTypes = nodeListToUriList( resHash[ objUri ].values( RDF::type() ) );
568 
569  if( !isOfType( object, range, objectNewTypes ) ) {
570  // Error
571  QList<QUrl> allTypes = ( objectNewTypes + m_model->typeCache()->types(objUri) );
572 
573  QString error = QString::fromLatin1("%1 has a rdfs:range of %2. "
574  "%3 only has the following types %4" )
575  .arg( Soprano::Node::resourceToN3( propUri ),
576  Soprano::Node::resourceToN3( range ),
577  Soprano::Node::resourceToN3( objUri ),
578  resourcesToN3( allTypes ).join(", ") );
579  setError( error, Soprano::Error::ErrorInvalidArgument );
580  return false;
581  }
582  }
583  else if( object.isLiteral() ) {
584  const Soprano::LiteralValue lv = object.literal();
585  // Special handling for xsd:duration
586  if( lv.isUnsignedInt() && range == xsdDuration() ) {
587  continue;
588  }
589  if( (!lv.isPlain() && lv.dataTypeUri() != range) || (lv.isPlain() && range != RDFS::Literal()) ) {
590  // Error
591  QString error = QString::fromLatin1("%1 has a rdfs:range of %2. Provided %3")
592  .arg( Soprano::Node::resourceToN3( propUri ),
593  Soprano::Node::resourceToN3( range ),
594  Soprano::Node::literalToN3(lv) );
595  setError( error, Soprano::Error::ErrorInvalidArgument);
596  return false;
597  }
598  }
599  } // range
600 
601  } // SyncResource contents iteration
602 
603  // Insert the removed types
604  foreach( const Soprano::Node& node, resNodeTypes )
605  res.insert( RDF::type(), node );
606 
607  return true;
608 }
609 
610 void Nepomuk2::ResourceMerger::clearError()
611 {
612  m_error = Soprano::Error::Error();
613 }
614 
615 Soprano::Error::Error Nepomuk2::ResourceMerger::lastError()
616 {
617  return m_error;
618 }
619 
620 void Nepomuk2::ResourceMerger::setError(const Soprano::Error::Error& error)
621 {
622  m_error = error;
623 }
624 
625 void Nepomuk2::ResourceMerger::setError(const QString& errorMessage, int code)
626 {
627  m_error = Soprano::Error::Error( errorMessage, code );
628 }
629 
630 
Nepomuk2::ResourceMerger::ResourceMerger
ResourceMerger(Nepomuk2::DataManagementModel *model, const QString &app, const StoreResourcesFlags &flags, bool discardable)
Definition: resourcemerger.cpp:90
Nepomuk2::OverwriteProperties
By default storeResources() will only append data and fail if properties with cardinality 1 already h...
Definition: datamanagement.h:369
Nepomuk2::LazyCardinalities
When lazy cardinalities are enabled any value that would violate a cardinality restriction is simply ...
Definition: datamanagement.h:373
QHash
resourcewatchermanager.h
Nepomuk2::ClassAndPropertyTree
Definition: classandpropertytree.h:45
Nepomuk2::ResourceMerger::~ResourceMerger
~ResourceMerger()
Definition: resourcemerger.cpp:109
Nepomuk2::ResourceMerger::mappings
QHash< QUrl, QUrl > mappings() const
Definition: resourcemerger.cpp:118
Nepomuk2::OverwriteAllProperties
By default storeResources will only append data and fail if properties with cardinality 1 already hav...
Definition: datamanagement.h:380
classandpropertytree.h
typecache.h
Nepomuk2::Sync::SyncResource::uri
KUrl uri() const
Definition: syncresource.cpp:127
resourcemerger.h
Nepomuk2::ResourceMerger::setError
void setError(const Soprano::Error::Error &error)
Definition: resourcemerger.cpp:620
Nepomuk2::DataManagementModel::resourceWatcherManager
ResourceWatcherManager * resourceWatcherManager() const
used by the unit tests
Definition: datamanagementmodel.cpp:2598
Soprano::Vocabulary::XMLSchema::xsdDuration
QUrl xsdDuration()
Definition: classandpropertytree.cpp:345
Nepomuk2::ResourceMerger::setMappings
void setMappings(const QHash< QUrl, QUrl > &mappings)
Definition: resourcemerger.cpp:113
Nepomuk2::ResourceMerger::lastError
Soprano::Error::Error lastError()
Definition: resourcemerger.cpp:615
Nepomuk2::ResourceMerger::clearError
void clearError()
Definition: resourcemerger.cpp:610
Nepomuk2::Sync::SyncResource::setUri
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 ...
Definition: syncresource.cpp:117
Nepomuk2::ResourceMerger::merge
bool merge(const Sync::ResourceHash &resHash)
Definition: resourcemerger.cpp:303
Nepomuk2::Sync::SyncResource::isBlank
bool isBlank() const
Definition: syncresource.cpp:244
Nepomuk2::resourcesToN3
QStringList resourcesToN3(const T &urls)
Convert a list or set or QUrls into a list of N3 formatted strings.
Definition: nepomuktools.h:35
datamanagementmodel.h
nepomuktools.h
Nepomuk2::ClassAndPropertyTree::maxCardinality
int maxCardinality(const QUrl &type) const
Definition: classandpropertytree.cpp:155
Nepomuk2::Sync::SyncResource
A SyncResource is a convenient way of storing a set of properties and objects for a common subject...
Definition: syncresource.h:53
Nepomuk2::DataManagementModel
Definition: datamanagementmodel.h:39
Nepomuk2::Sync::SyncResource::uriNode
Soprano::Node uriNode() const
Definition: syncresource.cpp:132
Nepomuk2::Sync::ResourceHash
A SyncResource is a convenient way of representing a list of Soprano::Statements or a Soprano::Graph...
Definition: syncresource.h:109
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:08 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Nepomuk-Core

Skip menu "Nepomuk-Core"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal