Difference between revisions of "Development/Tutorials/Metadata/Nepomuk/Resources"

Jump to: navigation, search
(Nepomuk::File does not exist. Changed to Nepomuk::Resource)
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Template:I18n/Language Navigation Bar|Development/Tutorials/Metadata/Nepomuk/Resources}}
+
 
  
 
{{TutorialBrowser|
 
{{TutorialBrowser|
Line 32: Line 32:
 
To use Nepomuk in your application simply make cmake search for it using the Nepomuk macro that comes with kdelibs:
 
To use Nepomuk in your application simply make cmake search for it using the Nepomuk macro that comes with kdelibs:
  
<code>
+
<syntaxhighlight lang="text">
 
find_package(Nepomuk REQUIRED)
 
find_package(Nepomuk REQUIRED)
 
include_directories(${NEPOMUK_INCLUDES})
 
include_directories(${NEPOMUK_INCLUDES})
 
target_link_libraries( [...] ${NEPOMUK_LIBRARIES})
 
target_link_libraries( [...] ${NEPOMUK_LIBRARIES})
</code>
+
</syntaxhighlight>
  
  
Line 49: Line 49:
 
Setting and getting metadata is done via two methods:
 
Setting and getting metadata is done via two methods:
  
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
void Nepomuk::Resource::setProperty( const QUrl& key, const Nepomuk::Variant& value );
 
void Nepomuk::Resource::setProperty( const QUrl& key, const Nepomuk::Variant& value );
 
Variant Nepomuk::Resource::property( const QUrl& key );
 
Variant Nepomuk::Resource::property( const QUrl& key );
</code>
+
</syntaxhighlight>
  
 
{{note|Why don't we use {{qt|QVariant}} instead of Nepomuk::Variant? Actually Nepomuk::Variant has been derived from {{qt|QVariant}} and extended with some nice list-handling features that will come in handy later on.}}
 
{{note|Why don't we use {{qt|QVariant}} instead of Nepomuk::Variant? Actually Nepomuk::Variant has been derived from {{qt|QVariant}} and extended with some nice list-handling features that will come in handy later on.}}
Line 60: Line 60:
 
[http://api.kde.org/kdesupport-api/kdesupport-apidocs/soprano/html/namespaceSoprano_1_1Vocabulary.html Soprano::Vocabulary] provides static instances of the most often used URIs as we see below (Soprano also comes with a code generation tool which can create these kind of namespaces from ontology files).  
 
[http://api.kde.org/kdesupport-api/kdesupport-apidocs/soprano/html/namespaceSoprano_1_1Vocabulary.html Soprano::Vocabulary] provides static instances of the most often used URIs as we see below (Soprano also comes with a code generation tool which can create these kind of namespaces from ontology files).  
  
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
Nepomuk::Resource tag( "TestTag", Soprano::Vocabulary::NAO::Tag() );
 
Nepomuk::Resource tag( "TestTag", Soprano::Vocabulary::NAO::Tag() );
 
tag.setProperty( Soprano::Vocabulary::RDFS::label(), QString("Important stuff") );
 
tag.setProperty( Soprano::Vocabulary::RDFS::label(), QString("Important stuff") );
Line 66: Line 66:
 
Nepomuk::Resource aFile( "/tmp/testfile.txt", Soprano::Vocabulary::Xesam::File() );
 
Nepomuk::Resource aFile( "/tmp/testfile.txt", Soprano::Vocabulary::Xesam::File() );
 
aFile.setProperty( Soprano::Vocabulary::NAO::hasTag(), tag );
 
aFile.setProperty( Soprano::Vocabulary::NAO::hasTag(), tag );
</code>
+
</syntaxhighlight>
  
 
Now what does this do then?
 
Now what does this do then?
Line 77: Line 77:
 
The second way of using Nepomuk is to rely on its class generator which, as mentioned in the introduction, generates C++ classes from ontologies. Suddenly the above code looks much simpler:
 
The second way of using Nepomuk is to rely on its class generator which, as mentioned in the introduction, generates C++ classes from ontologies. Suddenly the above code looks much simpler:
  
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
Nepomuk::Tag tag( "TestTag" );
 
Nepomuk::Tag tag( "TestTag" );
 
tag.setLabel( "Important Stuff" );
 
tag.setLabel( "Important Stuff" );
  
Nepomuk::Resource aFile( "/tmp/testfile.txt" );
+
Nepomuk::File aFile( "/tmp/testfile.txt" );
 
aFile.addTag( tag );
 
aFile.addTag( tag );
</code>
+
</syntaxhighlight>
  
 
Isn't this much more readable and much easier to remember and debug? The nice thing is that both Tag and File are subclasses of Nepomuk::Resource and internally methods like addLabel are only based on setProperty and some magic use of Nepomuk::Variant.
 
Isn't this much more readable and much easier to remember and debug? The nice thing is that both Tag and File are subclasses of Nepomuk::Resource and internally methods like addLabel are only based on setProperty and some magic use of Nepomuk::Variant.
Line 99: Line 99:
 
In Nepomuk each resource has only one instance at all times. Thus, the following code will actually result in only one new tag with two labels since the second one is simply a local copy:
 
In Nepomuk each resource has only one instance at all times. Thus, the following code will actually result in only one new tag with two labels since the second one is simply a local copy:
  
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
Nepomuk::Tag tagA( "test" );
 
Nepomuk::Tag tagA( "test" );
 
Nepomuk::Tag tagB( "test" );
 
Nepomuk::Tag tagB( "test" );
Line 105: Line 105:
 
tagA.setLabel( "testtagA" );
 
tagA.setLabel( "testtagA" );
 
tagB.setLabel( "testtagB" );
 
tagB.setLabel( "testtagB" );
</code>
+
</syntaxhighlight>
  
 
The actual data is cached and synced back regularly by the framework.
 
The actual data is cached and synced back regularly by the framework.

Latest revision as of 11:47, 15 July 2012


Resource Metadata Handling with Nepomuk

Contents

[edit] Introduction

Three types of meta data can be identified:

  1. Meta data that is stored with the data itself and is available at all times. This includes id3 tags, the number of pages in a PDF document, or even the size of a file or the subject of an email.
  2. Meta data that is created by the user manually like annotations or tags that are assigned to files, emails, or whatever resources.
  3. Meta data that can be gathered automatically by applications such as the source of a downloaded file or the email an attachment was saved from or the original when copying a file locally.

Type 1 is already handled in many implementations. KDE itself uses Strigi which allows the extraction of this kind of meta information from files.

Nepomuk is intended for meta data of type 2 and 3. It provides an easy way to create and read meta data for arbitrary resources (this includes for example files or emails, but also contacts or maybe even a paragraph in a pdf file).

The simplest type of meta data that can be handled with Nepomuk is a comment. It is a simple string associated with a resource (a file for example). This comment is created by the user using an application that is based on Nepomuk. Nepomuk's core is designed to allow arbitrary types of meta data, i.e. any resource can be related with any other resource or value by simply naming the relation and providing the value. The power of Nepomuk from a developer's point of view, however, lies in that it can provide a C++ class for each type of resource. Such a C++ class then provides convenience methods to allow a simple handling of the metadata.

Nepomuk is resource based. Thus, working with Nepomuk is always done with instances representing a certain resource. This resource has a list of properties. Properties are named and have a certain type. The type can either be another resource (compare a file that was an attachment from an email) or a literal (this means for example a string, or an integer; the comment mentioned earlier would be a string literal). Each property can either have a cardinality of 1 (again a file can only be saved from one email) or greater than 1 (i.e. infinite, like one file can have many associated comments).


[edit] Getting started

Nepomuk is already part of kdelibs. To use it make sure you have installed Soprano from the kdesupport module.

To use Nepomuk in your application simply make cmake search for it using the Nepomuk macro that comes with kdelibs:

find_package(Nepomuk REQUIRED)
include_directories(${NEPOMUK_INCLUDES})
target_link_libraries( [...] ${NEPOMUK_LIBRARIES})


[edit] Developing with Nepomuk

Now let's dive into the good stuff and do some coding. There are basicly two ways to use Nepomuk: 1. by setting properties manually and 2. by generating convenience classes that provide proper method calls for each property.

[edit] The manual way of doing things

In Nepomuk metadata is represented as key/value pairs belonging to a certain resource which is represented by the Nepomuk::Resource class.

Setting and getting metadata is done via two methods:

void Nepomuk::Resource::setProperty( const QUrl& key, const Nepomuk::Variant& value );
Variant Nepomuk::Resource::property( const QUrl& key );
noframe
 
Note
Why don't we use QVariant instead of Nepomuk::Variant? Actually Nepomuk::Variant has been derived from QVariant and extended with some nice list-handling features that will come in handy later on.

Since in Nepomuk all metadata is stored as RDF all keys are actually URIs which are defined in specific ontologies (see Introduction to RDF and Ontologies for details) and look something like this: http://semanticdesktop.org/ontologies/2007/08/15/nao#Tag

Soprano::Vocabulary provides static instances of the most often used URIs as we see below (Soprano also comes with a code generation tool which can create these kind of namespaces from ontology files).

Nepomuk::Resource tag( "TestTag", Soprano::Vocabulary::NAO::Tag() );
tag.setProperty( Soprano::Vocabulary::RDFS::label(), QString("Important stuff") );
 
Nepomuk::Resource aFile( "/tmp/testfile.txt", Soprano::Vocabulary::Xesam::File() );
aFile.setProperty( Soprano::Vocabulary::NAO::hasTag(), tag );

Now what does this do then?

We first create a resource with an identifier "TestTag" and type "http://www.semanticdesktop.org/ontologies/2007/08/15/nao/#Tag" and then set a property (rdfs:label) to a string value "Important Stuff". Then we create a second resource and assign it the newly created tag.

[edit] Do it the smooth way

The second way of using Nepomuk is to rely on its class generator which, as mentioned in the introduction, generates C++ classes from ontologies. Suddenly the above code looks much simpler:

Nepomuk::Tag tag( "TestTag" );
tag.setLabel( "Important Stuff" );
 
Nepomuk::File aFile( "/tmp/testfile.txt" );
aFile.addTag( tag );

Isn't this much more readable and much easier to remember and debug? The nice thing is that both Tag and File are subclasses of Nepomuk::Resource and internally methods like addLabel are only based on setProperty and some magic use of Nepomuk::Variant.

Let us continue with the tagging example. The Tag class provides some more nice methods:

  • QList<Resource> Tag::TagOf() provides a list of all resources that have been tagged with this tag.
  • static QList<Tag> Tag::allTags() provide all existing tags

Using these methods it is already possible to provide basic tagging in your application.

[edit] Tips

[edit] Only one instance of each resource

In Nepomuk each resource has only one instance at all times. Thus, the following code will actually result in only one new tag with two labels since the second one is simply a local copy:

Nepomuk::Tag tagA( "test" );
Nepomuk::Tag tagB( "test" );
 
tagA.setLabel( "testtagA" );
tagB.setLabel( "testtagB" );

The actual data is cached and synced back regularly by the framework.

[edit] Two ways of accessing existing data

The constructor of Nepomuk::Resource (and with it the constructors of all subclasses) allows to use an identifier or an actual resource URI for creation. The framework will then look if the passed string already exists as an URI or an identifier and load the data appropriately. If neither identifier or URi exist the passed string is used as a new identifier and a new random resource URI is generated. To understand what this means it is important to know that each resource in Nepomuk is uniquely identified by its URI (which is also used for storage in RDF) but can also have an arbitrary number of alternative identifiers which are more convenient for certain applications to find a resource. A typical example is the path of a file or the name of a tag.


This page was last modified on 15 July 2012, at 11:47. This page has been accessed 13,532 times. Content is available under Creative Commons License SA 3.0 as well as the GNU Free Documentation License 1.2.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal