Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > d9b360ee2bb591aec74456d859429422 > files > 7

kdelibs4-4.1.2-5mdv2009.0.src.rpm

Index: nepomuk/core/resourcedata.cpp
===================================================================
--- nepomuk/core/resourcedata.cpp	(revision 842405)
+++ nepomuk/core/resourcedata.cpp	(revision 842406)
@@ -87,6 +87,9 @@
 
     m_types << m_mainType;
 
+    // there is no need to store the trivial type
+    m_initialTypeSaved = ( m_mainType == Soprano::Vocabulary::RDFS::Resource() );
+
     // TODO: handle the caching in a decent Cache class and not this ugly.
     if ( s_dataCnt >= 1000 ) {
         for( ResourceDataHash::iterator rdIt = initializedData()->begin();
@@ -143,6 +146,31 @@
 }
 
 
+void Nepomuk::ResourceData::setTypes( const QList<QUrl>& types )
+{
+    if( m_proxyData ) {
+        m_proxyData->setTypes( types );
+    }
+    else if ( store() ) {
+        // reset types
+        m_types.clear();
+        m_mainType = Soprano::Vocabulary::RDFS::Resource();
+
+        // load types (and set maintype)
+        QList<Node> nodes;
+        foreach( const QUrl& url, types ) {
+            loadType( url );
+            nodes << Node( url );
+        }
+
+        // update the data store
+        ResourceFilterModel fm( ResourceManager::instance()->mainModel() );
+        fm.updateProperty( m_uri, Soprano::Vocabulary::RDF::type(), nodes );
+    }
+}
+
+
+
 void Nepomuk::ResourceData::deleteData()
 {
     if( m_proxyData ) {
@@ -257,13 +285,17 @@
         m_modificationMutex.unlock();
     }
 
-    if ( !exists() ) {
-        QList<Statement> statements;
+    QList<Statement> statements;
 
-        // save type (There should be no need to save all the types since there is only one way
-        // that m_types contains more than one element: if we loaded them)
+    // save type (There should be no need to save all the types since there is only one way
+    // that m_types contains more than one element: if we loaded them)
+    // The first type, however, can be set at creation time to any value
+    if ( !m_initialTypeSaved &&
+         !ResourceManager::instance()->mainModel()->containsAnyStatement( m_uri, Soprano::Vocabulary::RDF::type(), m_types.first() ) ) {
         statements.append( Statement( m_uri, Soprano::Vocabulary::RDF::type(), m_types.first() ) );
+    }
 
+    if ( !exists() ) {
         // save the creation date
         statements.append( Statement( m_uri, Soprano::Vocabulary::NAO::created(), Soprano::LiteralValue( QDateTime::currentDateTime() ) ) );
 
@@ -274,13 +306,17 @@
 
         // HACK: make sure that files have proper fileUrl properties so long as we do not have a File class for
         // Dolphin and co.
-        if ( constHasType( Soprano::Vocabulary::Xesam::File() ) &&
+        if ( ( m_uri.scheme() == "file" ||
+               constHasType( Soprano::Vocabulary::Xesam::File() ) ) &&
              QFile::exists( m_uri.toLocalFile()) ) {
             statements.append( Statement( m_uri,
                                           Soprano::Vocabulary::Xesam::url(),
                                           LiteralValue( m_uri.toLocalFile() ) ) );
         }
+    }
 
+    if ( !statements.isEmpty() ) {
+        m_initialTypeSaved = true;
         ResourceFilterModel fm( ResourceManager::instance()->mainModel() );
         return fm.addStatements( statements ) == Soprano::Error::ErrorNone;
     }
@@ -290,6 +326,48 @@
 }
 
 
+void Nepomuk::ResourceData::loadType( const QUrl& storedType )
+{
+    if ( !m_types.contains( storedType ) ) {
+        m_types << storedType;
+    }
+    if ( m_mainType == Soprano::Vocabulary::RDFS::Resource() ) {
+        Q_ASSERT( !storedType.isEmpty() );
+        m_mainType = storedType;
+    }
+    else {
+        Types::Class currentTypeClass = m_mainType;
+        Types::Class storedTypeClass = storedType;
+
+        // Keep the type that is further down the hierarchy
+        if ( storedTypeClass.isSubClassOf( currentTypeClass ) ) {
+            m_mainType = storedTypeClass.uri();
+        }
+        else {
+            // This is a little convenience hack since the user is most likely
+            // more interested in the file content than the actual file
+            Types::Class xesamContentClass( Soprano::Vocabulary::Xesam::Content() );
+            if ( m_mainType == Soprano::Vocabulary::Xesam::File() &&
+                 ( storedTypeClass == xesamContentClass ||
+                   storedTypeClass.isSubClassOf( xesamContentClass ) ) ) {
+                m_mainType = storedTypeClass.uri();
+            }
+            else {
+                // the same is true for nie:DataObject vs. nie:InformationElement
+                Types::Class nieInformationElementClass( Vocabulary::NIE::InformationElement() );
+                Types::Class nieDataObjectClass( Vocabulary::NIE::DataObject() );
+                if( ( currentTypeClass == nieDataObjectClass ||
+                      currentTypeClass.isSubClassOf( nieDataObjectClass ) ) &&
+                    ( storedTypeClass == nieInformationElementClass ||
+                      storedTypeClass.isSubClassOf( nieInformationElementClass ) ) ) {
+                    m_mainType = storedTypeClass.uri();
+                }
+            }
+        }
+    }
+}
+
+
 bool Nepomuk::ResourceData::load()
 {
     if ( m_cacheDirty ) {
@@ -304,43 +382,7 @@
                 if ( statement.predicate().uri() == Soprano::Vocabulary::RDF::type() ) {
                     if ( statement.object().isResource() ) {
                         QUrl storedType = statement.object().uri();
-                        if ( !m_types.contains( storedType ) ) {
-                            m_types << storedType;
-                        }
-                        if ( m_mainType == Soprano::Vocabulary::RDFS::Resource() ) {
-                            Q_ASSERT( !storedType.isEmpty() );
-                            m_mainType = storedType;
-                        }
-                        else {
-                            Types::Class currentTypeClass = m_mainType;
-                            Types::Class storedTypeClass = storedType;
-
-                            // Keep the type that is further down the hierarchy
-                            if ( storedTypeClass.isSubClassOf( currentTypeClass ) ) {
-                                m_mainType = storedTypeClass.uri();
-                            }
-                            else {
-                                // This is a little convenience hack since the user is most likely
-                                // more interested in the file content than the actual file
-                                Types::Class xesamContentClass( Soprano::Vocabulary::Xesam::Content() );
-                                if ( m_mainType == Soprano::Vocabulary::Xesam::File() &&
-                                     ( storedTypeClass == xesamContentClass ||
-                                       storedTypeClass.isSubClassOf( xesamContentClass ) ) ) {
-                                    m_mainType = storedTypeClass.uri();
-                                }
-                                else {
-                                    // the same is true for nie:DataObject vs. nie:InformationElement
-                                    Types::Class nieInformationElementClass( Vocabulary::NIE::InformationElement() );
-                                    Types::Class nieDataObjectClass( Vocabulary::NIE::DataObject() );
-                                    if( ( currentTypeClass == nieDataObjectClass ||
-                                          currentTypeClass.isSubClassOf( nieDataObjectClass ) ) &&
-                                        ( storedTypeClass == nieInformationElementClass ||
-                                          storedTypeClass.isSubClassOf( nieInformationElementClass ) ) ) {
-                                        m_mainType = storedTypeClass.uri();
-                                    }
-                                }
-                            }
-                        }
+                        loadType( storedType );
                     }
                 }
                 else {
@@ -374,8 +416,7 @@
         if ( value.simpleType() == qMetaTypeId<Resource>() ) {
             QList<Resource> l = value.toResourceList();
             for( QList<Resource>::iterator resIt = l.begin(); resIt != l.end(); ++resIt ) {
-                if ( resIt->isValid() )
-                    resIt->m_data->store();
+                resIt->m_data->store();
             }
         }
 
@@ -396,7 +437,7 @@
 
         // one-to-many literals
         else if( value.isList() ) {
-            valueNodes += Nepomuk::valuesToRDFNodes( value );
+            valueNodes = Nepomuk::valuesToRDFNodes( value );
         }
 
         // one-to-one literal
@@ -480,7 +521,9 @@
 
         Soprano::Model* model = ResourceManager::instance()->mainModel();
 
-        if( model->containsAnyStatement( Statement( QUrl( kickoffUriOrId() ), Node(), Node() ) ) ) {
+        // kickoffUriOrId() cannot be a URI without a slash (ugly hack for a tiny speed gain)
+        if( kickoffUriOrId().contains('/') &&
+            model->containsAnyStatement( Statement( QUrl( kickoffUriOrId() ), Node(), Node() ) ) ) {
             //
             // The kickoffUriOrId is actually a URI
             //
@@ -549,13 +592,15 @@
                 //
                 // The resource does not exist, create a new one:
                 // If the kickoffUriOrId is a valid URI we use it as such, otherwise we create a new URI
-                // Special case: files: paths are always converted to URIs
+                // Special case: files: paths are always converted to URIs (but we only allow absolute paths,
+                // otherwise there can be false positives when for example a tag has the same name as a folder)
                 //
                 QUrl uri( kickoffUriOrId() );
                 if ( uri.isValid() && !uri.scheme().isEmpty() ) {
                     m_uri = uri;
                 }
-                else if ( QFile::exists( kickoffUriOrId() ) ) {
+                else if ( kickoffUriOrId()[0] == '/' &&
+                          QFile::exists( kickoffUriOrId() ) ) {
                     // KURL defaults to schema "file:"
                     m_uri = KUrl::fromPath( kickoffUriOrId() );
                 }
Index: nepomuk/core/resourcedata.h
===================================================================
--- nepomuk/core/resourcedata.h	(revision 842405)
+++ nepomuk/core/resourcedata.h	(revision 842406)
@@ -84,6 +84,8 @@
 
         QList<QUrl> allTypes();
 
+        void setTypes( const QList<QUrl>& types );
+
         QHash<QUrl, Variant> allProperties();
 
         bool hasProperty( const QUrl& uri );
@@ -183,6 +185,7 @@
 
     private:
         bool constHasType( const QUrl& type ) const;
+        void loadType( const QUrl& type );
 
         /**
          * The kickoff URI or ID is used as long as the resource has not been synced yet
@@ -216,6 +219,9 @@
         QHash<QUrl, Variant> m_cache;
         bool m_cacheDirty;
 
+        // used to prevent countless model operations in store()
+        bool m_initialTypeSaved;
+
         friend class ResourceManager;
     };
 }
Index: nepomuk/core/resource.cpp
===================================================================
--- nepomuk/core/resource.cpp	(revision 842405)
+++ nepomuk/core/resource.cpp	(revision 842406)
@@ -83,6 +83,7 @@
 
 Nepomuk::Resource::~Resource()
 {
+    // FIXME: ResourceData instances having a proxy also need to be deleted, maybe extend deref
     if( m_data && m_data->deref() == 0 && !m_data->isValid() ) {
         m_data->deleteData();
     }
@@ -150,6 +151,20 @@
 }
 
 
+void Nepomuk::Resource::setTypes( const QList<QUrl>& types )
+{
+    if ( m_data )
+        m_data->setTypes( types );
+}
+
+
+void Nepomuk::Resource::addType( const QUrl& type )
+{
+    if ( m_data )
+        setTypes( types() << type );
+}
+
+
 bool Nepomuk::Resource::hasType( const QUrl& typeUri ) const
 {
     return m_data ? m_data->hasType( typeUri ) : false;
@@ -321,6 +336,7 @@
 
 QString Nepomuk::Resource::genericIcon() const
 {
+    // FIXME: support resource symbols
     Variant symbol = property( Soprano::Vocabulary::NAO::hasSymbol() );
     if ( symbol.isString() ) {
         return symbol.toString();
Index: nepomuk/core/resource.h
===================================================================
--- nepomuk/core/resource.h	(revision 842405)
+++ nepomuk/core/resource.h	(revision 842406)
@@ -222,6 +222,20 @@
         QList<QUrl> types() const;
 
         /**
+         * Set the types of the resource. Previous types will be overwritten.
+         *
+         * \since 4.2
+         */
+        void setTypes( const QList<QUrl>& types );
+
+        /**
+         * Add a type to the list of types.
+         *
+         * \since 4.2
+         */
+        void addType( const QUrl& type );
+
+        /**
          * Check if the resource is of a certain type. The type hierarchy
          * is checked including subclass relations.
          */
Index: nepomuk/Mainpage.dox
===================================================================
--- nepomuk/Mainpage.dox	(revision 842405)
+++ nepomuk/Mainpage.dox	(revision 842406)
@@ -25,14 +25,7 @@
 
 This is the KDE Meta Data library (not to confuse with KFileMetaData).
 
-@warning The Nepomuk API may be subject to change before the release of
-KDE 4.1. Using these classes in applications that are part of the KDE core
-packages is no problem at all; API changes will be merged in quickly.
-However, if you intend to use this API in external applications please
-be aware that your application might stop working with KDE 4.1. Changes to
-the API will be announced on the kde-core mailing list.
 
-
 \section overview The General Idea
 
 Three types of meta data can be identified:
@@ -82,8 +75,8 @@
 - \ref hacking
 - \ref examples
 - \ref nepomuk-rcgen
+- <a href="http://techbase.kde.org/Development/Tutorials#Nepomuk">The Nepomuk techbase tutorials</a>
 
-
 \authors
 Sebastian Trueg \<trueg@kde.org\>
 
@@ -241,7 +234,8 @@
             << it.next().genericLabel();
 \endcode
 
-Reading the information using the convenience classes:
+Reading the information using the convenience classes (be aware that these classes need to be generated
+from an ontology using the \ref nepomuk-rcgen "Resource Generator"):
 
 \code
 Nepomuk::File f( "/home/foo/bar.txt" );