Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F16569240
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
60 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/nepomuk/core/resource.cpp b/nepomuk/core/resource.cpp
index a4ab756d32..75a41a98bc 100644
--- a/nepomuk/core/resource.cpp
+++ b/nepomuk/core/resource.cpp
@@ -1,964 +1,963 @@
/*
* This file is part of the Nepomuk KDE project.
* Copyright (C) 2006-2010 Sebastian Trueg <trueg@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "resource.h"
#include "resourcedata.h"
#include "resourcemanager.h"
#include "resourcemanager_p.h"
#include "tools.h"
#include "tag.h"
#include "pimo.h"
#include "thing.h"
#include "file.h"
#include "property.h"
#include "nfo.h"
#include "nie.h"
#include "nco.h"
#include "nuao.h"
#include "klocale.h"
#include "kdebug.h"
#include "kurl.h"
#include "kmimetype.h"
#include <Soprano/Vocabulary/NAO>
#include <Soprano/Vocabulary/Xesam>
#include <Soprano/Vocabulary/RDFS>
#include <Soprano/Model>
#include <Soprano/QueryResultIterator>
Nepomuk::Resource::Resource()
{
QMutexLocker lock( &ResourceManager::instance()->d->mutex );
m_data = ResourceManager::instance()->d->data( QUrl(), QUrl() );
if ( m_data )
m_data->ref( this );
}
Nepomuk::Resource::Resource( ResourceManager* manager )
{
if(!manager)
manager = ResourceManager::instance();
QMutexLocker lock( &manager->d->mutex );
m_data = manager->d->data( QUrl(), QUrl() );
if ( m_data )
m_data->ref( this );
}
Nepomuk::Resource::Resource( const Nepomuk::Resource& res )
{
QMutexLocker lock( &res.m_data->rm()->mutex );
m_data = res.m_data;
if ( m_data )
m_data->ref( this );
}
Nepomuk::Resource::Resource( const QString& uri, const QUrl& type )
{
QMutexLocker lock( &ResourceManager::instance()->d->mutex );
m_data = ResourceManager::instance()->d->data( uri, type );
if ( m_data )
m_data->ref( this );
}
Nepomuk::Resource::Resource( const QString& uri, const QUrl& type, ResourceManager* manager )
{
if(!manager)
manager = ResourceManager::instance();
QMutexLocker lock( &manager->d->mutex );
m_data = manager->d->data( uri, type );
if ( m_data )
m_data->ref( this );
}
#ifndef KDE_NO_DEPRECATED
Nepomuk::Resource::Resource( const QString& uri, const QString& type )
{
QMutexLocker lock( &ResourceManager::instance()->d->mutex );
m_data = ResourceManager::instance()->d->data( uri, type );
if ( m_data )
m_data->ref( this );
}
#endif
Nepomuk::Resource::Resource( const QUrl& uri, const QUrl& type )
{
QMutexLocker lock( &ResourceManager::instance()->d->mutex );
m_data = ResourceManager::instance()->d->data( uri, type );
if ( m_data )
m_data->ref( this );
}
Nepomuk::Resource::Resource( const QUrl& uri, const QUrl& type, ResourceManager* manager )
{
if(!manager)
manager = ResourceManager::instance();
QMutexLocker lock( &manager->d->mutex );
m_data = manager->d->data( uri, type );
if ( m_data )
m_data->ref( this );
}
Nepomuk::Resource::Resource( Nepomuk::ResourceData* data )
{
QMutexLocker lock( &data->rm()->mutex );
m_data = data;
if ( m_data )
m_data->ref( this );
}
Nepomuk::Resource::~Resource()
{
if ( m_data ) {
QMutexLocker lock(&m_data->rm()->mutex);
m_data->deref( this );
if ( m_data->rm()->shouldBeDeleted( m_data ) )
delete m_data;
}
}
Nepomuk::Resource& Nepomuk::Resource::operator=( const Resource& res )
{
if( m_data != res.m_data ) {
QMutexLocker lock(&m_data->rm()->mutex);
if ( m_data && !m_data->deref( this ) && m_data->rm()->shouldBeDeleted( m_data ) ) {
delete m_data;
}
m_data = res.m_data;
if ( m_data )
m_data->ref( this );
}
return *this;
}
Nepomuk::Resource& Nepomuk::Resource::operator=( const QUrl& res )
{
return operator=( Resource( res ) );
}
Nepomuk::ResourceManager* Nepomuk::Resource::manager() const
{
return m_data->rm()->m_manager;
}
#ifndef KDE_NO_DEPRECATED
QString Nepomuk::Resource::uri() const
{
return resourceUri().toString();
}
#endif
QUrl Nepomuk::Resource::resourceUri() const
{
if ( m_data ) {
determineFinalResourceData();
return m_data->uri();
}
else {
return QUrl();
}
}
#ifndef KDE_NO_DEPRECATED
QString Nepomuk::Resource::type() const
{
return resourceType().toString();
}
#endif
QUrl Nepomuk::Resource::resourceType() const
{
determineFinalResourceData();
return m_data->type();
}
QList<QUrl> Nepomuk::Resource::types() const
{
determineFinalResourceData();
return m_data->allTypes();
}
void Nepomuk::Resource::setTypes( const QList<QUrl>& types )
{
determineFinalResourceData();
m_data->setTypes( types );
}
void Nepomuk::Resource::addType( const QUrl& type )
{
QList<QUrl> tl = types();
if( !tl.contains( type ) )
setTypes( tl << type );
}
bool Nepomuk::Resource::hasType( const QUrl& typeUri ) const
{
determineFinalResourceData();
return m_data->hasType( typeUri );
}
QString Nepomuk::Resource::className() const
{
return resourceType().toString().section( QRegExp( "[#:]" ), -1 );
}
QHash<QUrl, Nepomuk::Variant> Nepomuk::Resource::properties() const
{
determineFinalResourceData();
return m_data->allProperties();
}
#ifndef KDE_NO_DEPRECATED
QHash<QString, Nepomuk::Variant> Nepomuk::Resource::allProperties() const
{
QHash<QString, Nepomuk::Variant> pl;
QHash<QUrl, Nepomuk::Variant> p = properties();
QHash<QUrl, Nepomuk::Variant>::const_iterator end = p.constEnd();
for ( QHash<QUrl, Nepomuk::Variant>::const_iterator it = p.constBegin();
it != end; ++it ) {
pl.insert( it.key().toString(), it.value() );
}
return pl;
}
#endif
bool Nepomuk::Resource::hasProperty( const QUrl& uri ) const
{
determineFinalResourceData();
return m_data->hasProperty( uri );
}
bool Nepomuk::Resource::hasProperty( const Types::Property& p, const Variant& v ) const
{
determineFinalResourceData();
return m_data->hasProperty( p.uri(), v );
}
#ifndef KDE_NO_DEPRECATED
bool Nepomuk::Resource::hasProperty( const QString& uri ) const
{
return hasProperty( QUrl( uri ) );
}
#endif
#ifndef KDE_NO_DEPRECATED
Nepomuk::Variant Nepomuk::Resource::property( const QString& uri ) const
{
return property( QUrl( uri ) );
}
#endif
Nepomuk::Variant Nepomuk::Resource::property( const QUrl& uri ) const
{
determineFinalResourceData();
return m_data->property( uri );
}
#ifndef KDE_NO_DEPRECATED
void Nepomuk::Resource::setProperty( const QString& uri, const Nepomuk::Variant& value )
{
setProperty( QUrl( uri ), value );
}
#endif
void Nepomuk::Resource::addProperty( const QUrl& uri, const Variant& value )
{
- Variant v = property( uri );
- v.append( value );
- setProperty( uri, v );
+ determineFinalResourceData();
+ m_data->addProperty( uri, value );
}
void Nepomuk::Resource::setProperty( const QUrl& uri, const Nepomuk::Variant& value )
{
determineFinalResourceData();
m_data->setProperty( uri, value );
}
#ifndef KDE_NO_DEPRECATED
void Nepomuk::Resource::removeProperty( const QString& uri )
{
removeProperty( QUrl( uri ) );
}
#endif
void Nepomuk::Resource::removeProperty( const QUrl& uri )
{
determineFinalResourceData();
m_data->removeProperty( uri );
}
void Nepomuk::Resource::removeProperty( const QUrl& uri, const Variant& value )
{
QList<Variant> vl = property( uri ).toVariantList();
foreach( const Variant& v, value.toVariantList() ) {
vl.removeAll( v );
}
setProperty( uri, Variant( vl ) );
}
void Nepomuk::Resource::remove()
{
determineFinalResourceData();
m_data->remove();
}
bool Nepomuk::Resource::exists() const
{
determineFinalResourceData();
if ( m_data ) {
return m_data->exists();
}
else {
return false;
}
}
bool Nepomuk::Resource::isValid() const
{
return m_data ? m_data->isValid() : false;
}
// TODO: cache this one in ResourceData
QString Nepomuk::Resource::genericLabel() const
{
QString label = this->label();
if(!label.isEmpty())
return label;
label = property( Soprano::Vocabulary::RDFS::label() ).toString();
if(!label.isEmpty())
return label;
label = property( Nepomuk::Vocabulary::NIE::title() ).toString();
if(!label.isEmpty())
return label;
label = property( Nepomuk::Vocabulary::NCO::fullname() ).toString();
if(!label.isEmpty())
return label;
label = property( Soprano::Vocabulary::NAO::identifier() ).toString();
if(!label.isEmpty())
return label;
label = m_data->pimoThing().label();
if(!label.isEmpty())
return label;
label = property( Nepomuk::Vocabulary::NFO::fileName() ).toString();
if(!label.isEmpty())
return label;
const KUrl nieUrl = property( Nepomuk::Vocabulary::NIE::url() ).toUrl();
if(!nieUrl.isEmpty()) {
if(nieUrl.isLocalFile())
return nieUrl.fileName();
else
return nieUrl.prettyUrl();
}
QList<Resource> go = property( Vocabulary::PIMO::groundingOccurrence() ).toResourceList();
if( !go.isEmpty() ) {
label = go.first().genericLabel();
if( label != KUrl(go.first().resourceUri()).pathOrUrl() ) {
return label;
}
}
QString hashValue = property( Vocabulary::NFO::hashValue() ).toString();
if( !hashValue.isEmpty() )
return hashValue;
// ugly fallback
return KUrl(resourceUri()).pathOrUrl();
}
QString Nepomuk::Resource::genericDescription() const
{
QString s = property( Soprano::Vocabulary::NAO::description() ).toString();
if ( !s.isEmpty() ) {
return s;
}
s = property( Soprano::Vocabulary::Xesam::summary() ).toString();
if ( !s.isEmpty() ) {
return s;
}
s = property( Soprano::Vocabulary::Xesam::description() ).toString();
if ( !s.isEmpty() ) {
return s;
}
s = property( Soprano::Vocabulary::Xesam::asText() ).toString();
if ( !s.isEmpty() ) {
return s;
}
s = property( Soprano::Vocabulary::RDFS::comment() ).toString();
return s;
}
QString Nepomuk::Resource::genericIcon() const
{
// FIXME: support resource symbols
Variant symbol = property( Soprano::Vocabulary::NAO::hasSymbol() );
if ( symbol.isString() ) {
return symbol.toString();
} else if ( symbol.isStringList() ) {
const QStringList l = symbol.toStringList();
if ( l.isEmpty() )
return QString();
return l.first();
}
// strigi mimetypes are sadly not very reliable, I keep the code here for future use
// QString mimeType = property( Soprano::Vocabulary::Xesam::mimeType() ).toString();
// if ( !mimeType.isEmpty() ) {
// if ( KMimeType::Ptr m = KMimeType::mimeType( mimeType ) ) {
// return m->iconName();
// }
// }
if ( hasType( Soprano::Vocabulary::Xesam::File() ) ||
resourceUri().scheme() == "file" ) {
return KMimeType::iconNameForUrl( resourceUri() );
}
return QString();
}
Nepomuk::Thing Nepomuk::Resource::pimoThing()
{
determineFinalResourceData();
return m_data->pimoThing();
}
bool Nepomuk::Resource::operator==( const Resource& other ) const
{
if( this == &other )
return true;
if( this->m_data == other.m_data )
return true;
if ( !m_data || !other.m_data ) {
return false;
}
// get the resource URIs since two different ResourceData instances
// can still represent the same Resource
determineFinalResourceData();
other.determineFinalResourceData();
if( m_data->uri().isEmpty() )
return *m_data == *other.m_data;
else
return resourceUri() == other.resourceUri();
}
bool Nepomuk::Resource::operator!=( const Resource& other ) const
{
return !operator==( other );
}
QString Nepomuk::errorString( ErrorCode code )
{
switch( code ) {
case NoError:
return i18n("Success");
case CommunicationError:
return i18n("Communication error");
case InvalidType:
return i18n("Invalid type in Database");
default:
return i18n("Unknown error");
}
}
QString Nepomuk::Resource::description() const
{
return ( property( Soprano::Vocabulary::NAO::description() ).toStringList() << QString() ).first();
}
void Nepomuk::Resource::setDescription( const QString& value )
{
setProperty( Soprano::Vocabulary::NAO::description(), Variant( value ) );
}
QString Nepomuk::Resource::descriptionUri()
{
return Soprano::Vocabulary::NAO::description().toString();
}
QStringList Nepomuk::Resource::identifiers() const
{
return property( Soprano::Vocabulary::NAO::identifier() ).toStringList();
}
void Nepomuk::Resource::setIdentifiers( const QStringList& value )
{
setProperty( Soprano::Vocabulary::NAO::identifier(), Variant( value ) );
}
void Nepomuk::Resource::addIdentifier( const QString& value )
{
Variant v = property( Soprano::Vocabulary::NAO::identifier() );
v.append( value );
setProperty( Soprano::Vocabulary::NAO::identifier(), v );
}
QString Nepomuk::Resource::identifierUri()
{
return Soprano::Vocabulary::NAO::identifier().toString();
}
QStringList Nepomuk::Resource::altLabels() const
{
return property( Soprano::Vocabulary::NAO::altLabel() ).toStringList();
}
void Nepomuk::Resource::setAltLabels( const QStringList& value )
{
setProperty( Soprano::Vocabulary::NAO::altLabel(), Variant( value ) );
}
void Nepomuk::Resource::addAltLabel( const QString& value )
{
Variant v = property( Soprano::Vocabulary::NAO::altLabel() );
v.append( value );
setProperty( Soprano::Vocabulary::NAO::altLabel(), v );
}
QString Nepomuk::Resource::altLabelUri()
{
return Soprano::Vocabulary::NAO::altLabel().toString();
}
QList<Nepomuk::Resource> Nepomuk::Resource::annotations() const
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
return convertResourceList<Resource>( property( Soprano::Vocabulary::NAO::annotation() ).toResourceList() );
}
void Nepomuk::Resource::setAnnotations( const QList<Nepomuk::Resource>& value )
{
setProperty( Soprano::Vocabulary::NAO::annotation(), Variant( value ) );
}
void Nepomuk::Resource::addAnnotation( const Nepomuk::Resource& value )
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
Variant v = property( Soprano::Vocabulary::NAO::annotation() );
v.append( Resource( value ) );
setProperty( Soprano::Vocabulary::NAO::annotation(), v );
}
QString Nepomuk::Resource::annotationUri()
{
return Soprano::Vocabulary::NAO::annotation().toString();
}
QList<Nepomuk::Tag> Nepomuk::Resource::tags() const
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
return convertResourceList<Tag>( property( Soprano::Vocabulary::NAO::hasTag() ).toResourceList() );
}
void Nepomuk::Resource::setTags( const QList<Nepomuk::Tag>& value )
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
QList<Resource> l;
for( QList<Tag>::const_iterator it = value.constBegin();
it != value.constEnd(); ++it ) {
l.append( Resource( (*it) ) );
}
setProperty( Soprano::Vocabulary::NAO::hasTag(), Variant( l ) );
}
void Nepomuk::Resource::addTag( const Nepomuk::Tag& value )
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
Variant v = property( Soprano::Vocabulary::NAO::hasTag() );
v.append( Resource( value ) );
setProperty( Soprano::Vocabulary::NAO::hasTag(), v );
}
QString Nepomuk::Resource::tagUri()
{
return Soprano::Vocabulary::NAO::hasTag().toString();
}
QList<Nepomuk::Resource> Nepomuk::Resource::topics() const
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
return convertResourceList<Resource>( property( Soprano::Vocabulary::NAO::hasTopic() ).toResourceList() );
}
void Nepomuk::Resource::setTopics( const QList<Nepomuk::Resource>& value )
{
setProperty( Soprano::Vocabulary::NAO::hasTopic(), Variant( value ) );
}
void Nepomuk::Resource::addTopic( const Nepomuk::Resource& value )
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
Variant v = property( Soprano::Vocabulary::NAO::hasTopic() );
v.append( Resource( value ) );
setProperty( Soprano::Vocabulary::NAO::hasTopic(), v );
}
QString Nepomuk::Resource::topicUri()
{
return Soprano::Vocabulary::NAO::hasTopic().toString();
}
QList<Nepomuk::Resource> Nepomuk::Resource::isTopicOfs() const
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
return convertResourceList<Resource>( property( Soprano::Vocabulary::NAO::isTopicOf() ).toResourceList() );
}
void Nepomuk::Resource::setIsTopicOfs( const QList<Nepomuk::Resource>& value )
{
setProperty( Soprano::Vocabulary::NAO::isTopicOf(), Variant( value ) );
}
void Nepomuk::Resource::addIsTopicOf( const Nepomuk::Resource& value )
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
Variant v = property( Soprano::Vocabulary::NAO::isTopicOf() );
v.append( Resource( value ) );
setProperty( Soprano::Vocabulary::NAO::isTopicOf(), v );
}
QString Nepomuk::Resource::isTopicOfUri()
{
return Soprano::Vocabulary::NAO::isTopicOf().toString();
}
QList<Nepomuk::Resource> Nepomuk::Resource::isRelateds() const
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
return convertResourceList<Resource>( property( Soprano::Vocabulary::NAO::isRelated() ).toResourceList() );
}
void Nepomuk::Resource::setIsRelateds( const QList<Nepomuk::Resource>& value )
{
setProperty( Soprano::Vocabulary::NAO::isRelated(), Variant( value ) );
}
void Nepomuk::Resource::addIsRelated( const Nepomuk::Resource& value )
{
// We always store all Resource types as plain Resource objects.
// It does not introduce any overhead (due to the implicit sharing of
// the data and has the advantage that we can mix setProperty calls
// with the special Resource subclass methods.
// More importantly Resource loads the data as Resource objects anyway.
Variant v = property( Soprano::Vocabulary::NAO::isRelated() );
v.append( Resource( value ) );
setProperty( Soprano::Vocabulary::NAO::isRelated(), v );
}
QString Nepomuk::Resource::isRelatedUri()
{
return Soprano::Vocabulary::NAO::isRelated().toString();
}
QString Nepomuk::Resource::label() const
{
return ( property( Soprano::Vocabulary::NAO::prefLabel() ).toStringList() << QString() ).first();
}
void Nepomuk::Resource::setLabel( const QString& value )
{
setProperty( Soprano::Vocabulary::NAO::prefLabel(), Variant( value ) );
}
QString Nepomuk::Resource::labelUri()
{
return Soprano::Vocabulary::NAO::prefLabel().toString();
}
quint32 Nepomuk::Resource::rating() const
{
return ( property( Soprano::Vocabulary::NAO::numericRating() ).toUnsignedIntList() << 0 ).first();
}
void Nepomuk::Resource::setRating( const quint32& value )
{
setProperty( Soprano::Vocabulary::NAO::numericRating(), Variant( value ) );
}
QString Nepomuk::Resource::ratingUri()
{
return Soprano::Vocabulary::NAO::numericRating().toString();
}
QStringList Nepomuk::Resource::symbols() const
{
return property( Soprano::Vocabulary::NAO::hasSymbol() ).toStringList();
}
void Nepomuk::Resource::setSymbols( const QStringList& value )
{
setProperty( Soprano::Vocabulary::NAO::hasSymbol(), Variant( value ) );
}
void Nepomuk::Resource::addSymbol( const QString& value )
{
Variant v = property( Soprano::Vocabulary::NAO::hasSymbol() );
v.append( value );
setProperty( Soprano::Vocabulary::NAO::hasSymbol(), v );
}
QString Nepomuk::Resource::symbolUri()
{
return Soprano::Vocabulary::NAO::hasSymbol().toString();
}
QList<Nepomuk::Resource> Nepomuk::Resource::annotationOf() const
{
return convertResourceList<Resource>( manager()->allResourcesWithProperty( Soprano::Vocabulary::NAO::annotation(), *this ) );
}
QList<Nepomuk::Resource> Nepomuk::Resource::isRelatedOf() const
{
return convertResourceList<Resource>( manager()->allResourcesWithProperty( Soprano::Vocabulary::NAO::isRelated(), *this ) );
}
// static
QList<Nepomuk::Resource> Nepomuk::Resource::allResources()
{
return Nepomuk::convertResourceList<Resource>( ResourceManager::instance()->allResourcesOfType( Soprano::Vocabulary::RDFS::Resource() ) );
}
int Nepomuk::Resource::usageCount() const
{
return property( Vocabulary::NUAO::usageCount() ).toInt();
}
void Nepomuk::Resource::increaseUsageCount()
{
int cnt = 0;
const QDateTime now = QDateTime::currentDateTime();
if( hasProperty( Vocabulary::NUAO::usageCount() ) )
cnt = property( Vocabulary::NUAO::usageCount() ).toInt();
else
setProperty( Vocabulary::NUAO::firstUsage(), now );
++cnt;
setProperty( Vocabulary::NUAO::usageCount(), cnt );
setProperty( Vocabulary::NUAO::lastUsage(), now );
}
bool Nepomuk::Resource::isFile() const
{
if( m_data ) {
determineFinalResourceData();
m_data->load();
return m_data->isFile();
}
else {
return false;
}
}
Nepomuk::File Nepomuk::Resource::toFile() const
{
return File( *this );
}
// static
Nepomuk::Resource Nepomuk::Resource::fromResourceUri( const KUrl& uri, const Nepomuk::Types::Class& type, ResourceManager* manager )
{
if( !manager )
manager = ResourceManager::instance();
QMutexLocker lock( &manager->d->mutex );
return Resource( manager->d->dataForResourceUri( uri, type.uri() ) );
}
void Nepomuk::Resource::determineFinalResourceData() const
{
QMutexLocker lock( &m_data->rm()->mutex );
// Get an initialized ResourceData instance
ResourceData* oldData = m_data;
ResourceData* newData = m_data->determineUri();
Q_ASSERT(oldData);
Q_ASSERT(newData);
// in case we get an already existing one we update all instances
// using the old ResourceData to avoid the overhead of calling
// determineUri over and over
if( newData != oldData ) {
Q_FOREACH( Resource* res, m_data->m_resources) {
res->m_data = newData;
oldData->deref( res );
newData->ref( res );
}
}
if ( !oldData->cnt() )
delete oldData;
}
uint Nepomuk::qHash( const Resource& res )
{
return qHash(res.resourceUri());
}
diff --git a/nepomuk/core/resourcedata.cpp b/nepomuk/core/resourcedata.cpp
index 06c4d7e7ef..c9816bf2ed 100644
--- a/nepomuk/core/resourcedata.cpp
+++ b/nepomuk/core/resourcedata.cpp
@@ -1,750 +1,799 @@
/*
* This file is part of the Nepomuk KDE project.
* Copyright (C) 2006-2010 Sebastian Trueg <trueg@kde.org>
* Copyright (C) 2010 Vishesh Handa <handa.vish@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "resourcedata.h"
#include "resourcemanager.h"
#include "resourcemanager_p.h"
#include "resource.h"
#include "tools.h"
#include "nie.h"
#include "nfo.h"
#include "pimo.h"
#include "nepomukmainmodel.h"
#include "dbusconnectionpool.h"
#include "class.h"
#include "dbustypes.h"
#include <Soprano/Statement>
#include <Soprano/StatementIterator>
#include <Soprano/QueryResultIterator>
#include <Soprano/Model>
#include <Soprano/Vocabulary/RDFS>
#include <Soprano/Vocabulary/RDF>
#include <Soprano/Vocabulary/Xesam>
#include <Soprano/Vocabulary/NAO>
#include <QtCore/QFile>
#include <QtCore/QDateTime>
#include <QtCore/QMutexLocker>
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusReply>
#include <kdebug.h>
#include <kurl.h>
#include <kcomponentdata.h>
using namespace Soprano;
#define MAINMODEL (m_rm->m_manager->mainModel())
Nepomuk::ResourceData::ResourceData( const QUrl& uri, const QUrl& kickOffUri, const QUrl& type, ResourceManagerPrivate* rm )
: m_uri(uri),
m_mainType( type ),
m_modificationMutex(QMutex::Recursive),
m_cacheDirty(true),
m_pimoThing(0),
m_groundingOccurence(0),
m_rm(rm)
{
if( m_mainType.isEmpty() ) {
m_mainType = Soprano::Vocabulary::RDFS::Resource();
}
m_types << m_mainType;
if( m_rm->dataCacheFull() )
m_rm->cleanupCache();
m_rm->dataCnt.ref();
if( !uri.isEmpty() ) {
m_kickoffUris.insert( uri );
}
if( !kickOffUri.isEmpty() ) {
m_kickoffUris.insert( kickOffUri );
}
m_rm->addToKickOffList( this, m_kickoffUris );
}
Nepomuk::ResourceData::~ResourceData()
{
resetAll(true);
m_rm->dataCnt.deref();
}
bool Nepomuk::ResourceData::isFile()
{
return( m_uri.scheme() == QLatin1String("file") ||
m_nieUrl.scheme() == QLatin1String("file") ||
(!m_kickoffUris.isEmpty() && (*m_kickoffUris.begin()).scheme() == QLatin1String("file")) ||
constHasType( Soprano::Vocabulary::Xesam::File() ) ||
constHasType( Nepomuk::Vocabulary::NFO::FileDataObject() ) );
}
QUrl Nepomuk::ResourceData::uri() const
{
return m_uri;
}
QUrl Nepomuk::ResourceData::type()
{
load();
return m_mainType;
}
QList<QUrl> Nepomuk::ResourceData::allTypes()
{
load();
return m_types;
}
void Nepomuk::ResourceData::setTypes( const QList<QUrl>& types )
{
store();
QMutexLocker lock(&m_modificationMutex);
// reset types
m_types.clear();
m_mainType = Soprano::Vocabulary::RDFS::Resource();
QList<Node> nodes;
// load types (and set maintype)
foreach( const QUrl& url, types ) {
loadType( url );
nodes << Node( url );
}
// update the data store
setProperty(Soprano::Vocabulary::RDF::type(), Nepomuk::Variant(types) );
}
void Nepomuk::ResourceData::resetAll( bool isDelete )
{
// remove us from all caches (store() will re-insert us later if necessary)
m_rm->mutex.lock();
if( !m_uri.isEmpty() )
m_rm->m_initializedData.remove( m_uri );
Q_FOREACH( const KUrl& uri, m_kickoffUris )
m_rm->m_uriKickoffData.remove( uri );
m_rm->mutex.unlock();
// reset all variables
m_uri = QUrl();
m_nieUrl = KUrl();
m_kickoffUris.clear();
m_cache.clear();
m_cacheDirty = false;
m_types.clear();
delete m_pimoThing;
m_pimoThing = 0;
m_groundingOccurence = 0;
// when we are being deleted the value of m_mainType is not important
// anymore. Also since ResourceManager is a global static it might be
// deleted after the global static behind Soprano::Vocabulary::RDFS
// which results in a crash.
if( !isDelete )
m_mainType = Soprano::Vocabulary::RDFS::Resource();
}
QHash<QUrl, Nepomuk::Variant> Nepomuk::ResourceData::allProperties()
{
load();
return m_cache;
}
bool Nepomuk::ResourceData::hasProperty( const QUrl& uri )
{
load();
QHash<QUrl, Variant>::const_iterator it = m_cache.constFind( uri );
if( it == m_cache.constEnd() )
return false;
return true;
}
bool Nepomuk::ResourceData::hasProperty( const QUrl& p, const Variant& v )
{
QHash<QUrl, Variant>::const_iterator it = m_cache.constFind( p );
if( it == m_cache.constEnd() )
return false;
QList<Variant> thisVals = it.value().toVariantList();
QList<Variant> vals = v.toVariantList();
Q_FOREACH( const Variant& val, vals ) {
if( !thisVals.contains(val) )
return false;
}
return true;
}
bool Nepomuk::ResourceData::hasType( const QUrl& uri )
{
load();
return constHasType( uri );
}
bool Nepomuk::ResourceData::constHasType( const QUrl& uri ) const
{
// we need to protect the reading, too. setTypes may be triggered from another thread
QMutexLocker lock(&m_modificationMutex);
Types::Class requestedType( uri );
for ( QList<QUrl>::const_iterator it = m_types.constBegin();
it != m_types.constEnd(); ++it ) {
Types::Class availType( *it );
if ( availType == requestedType ||
availType.isSubClassOf( requestedType ) ) {
return true;
}
}
return false;
}
Nepomuk::Variant Nepomuk::ResourceData::property( const QUrl& uri )
{
load();
// we need to protect the reading, too. load my be triggered from another thread's
// connection to a Soprano statement signal
QMutexLocker lock(&m_modificationMutex);
QHash<QUrl, Variant>::const_iterator it = m_cache.constFind( uri );
if ( it == m_cache.constEnd() ) {
return Variant();
}
else {
return *it;
}
}
bool Nepomuk::ResourceData::store()
{
QMutexLocker lock(&m_modificationMutex);
if ( m_uri.isEmpty() ) {
QMutexLocker rmlock(&m_rm->mutex);
if ( m_nieUrl.isValid() &&
m_nieUrl.isLocalFile() &&
m_mainType == Soprano::Vocabulary::RDFS::Resource() ) {
m_mainType = Nepomuk::Vocabulary::NFO::FileDataObject();
m_types << m_mainType;
}
QDBusConnection bus = QDBusConnection::sessionBus();
QDBusMessage msg = QDBusMessage::createMethodCall( QLatin1String("org.kde.nepomuk.DataManagement"),
QLatin1String("/datamanagement"),
QLatin1String("org.kde.nepomuk.DataManagement"),
QLatin1String("createResource") );
QString app = KGlobal::mainComponent().componentName();
QVariantList arguments;
//FIXME: Maybe we should be setting the 'label' over here.
arguments << DBus::convertUriList(m_types) << QString() << QString() << app;
msg.setArguments( arguments );
QDBusMessage reply = bus.call( msg );
if( reply.type() == QDBusMessage::ErrorMessage ) {
//TODO: Set the error somehow
kWarning() << reply.errorMessage();
return false;
}
else if( reply.type() == QDBusMessage::ReplyMessage ) {
m_uri = reply.arguments().at(0).toUrl();
}
// Add us to the initialized data, i.e. make us "valid"
m_rm->m_initializedData.insert( m_uri, this );
// each initialized resource has to be in a kickoff list
// thus, we make sure that is the case.
if( m_kickoffUris.isEmpty() ) {
m_kickoffUris.insert( m_uri );
m_rm->addToKickOffList( this, m_kickoffUris );
}
// store our grounding occurrence in case we are a thing created by the pimoThing() method
if( m_groundingOccurence ) {
if( m_groundingOccurence != this )
m_groundingOccurence->store();
setProperty(Vocabulary::PIMO::groundingOccurrence(), Variant(m_groundingOccurence->uri()) );
}
foreach( const KUrl& url, m_kickoffUris ) {
if( url.scheme().isEmpty() )
setProperty( Soprano::Vocabulary::NAO::identifier(), Variant(url.url()) );
else
setProperty( Nepomuk::Vocabulary::NIE::url(), Variant(url.url()) );
}
}
return true;
}
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()
{
QMutexLocker lock(&m_modificationMutex);
if ( m_cacheDirty ) {
m_cache.clear();
if ( m_uri.isValid() ) {
//
// We exclude properties that are part of the inference graph
// It would only pollute the user interface
//
Soprano::QueryResultIterator it = MAINMODEL->executeQuery(QString("select distinct ?p ?o where { "
"graph ?g { %1 ?p ?o . } . FILTER(?g!=<urn:crappyinference2:inferredtriples>) . "
"}").arg(Soprano::Node::resourceToN3(m_uri)),
Soprano::Query::QueryLanguageSparql);
while ( it.next() ) {
QUrl p = it["p"].uri();
Soprano::Node o = it["o"];
if ( p == Soprano::Vocabulary::RDF::type() ) {
if ( o.isResource() ) {
loadType( o.uri() );
}
}
else {
Nepomuk::Variant var = Variant::fromNode( o );
updateKickOffLists( p, var );
m_cache[p].append( var );
}
}
m_cacheDirty = false;
delete m_pimoThing;
m_pimoThing = 0;
if( hasType( Vocabulary::PIMO::Thing() ) ) {
m_pimoThing = new Thing( m_uri );
}
else {
// TODO: somehow handle pimo:referencingOccurrence and pimo:occurrence
QueryResultIterator pimoIt = MAINMODEL->executeQuery( QString( "select ?r where { ?r <%1> <%2> . }")
.arg( Vocabulary::PIMO::groundingOccurrence().toString() )
.arg( QString::fromAscii( m_uri.toEncoded() ) ),
Soprano::Query::QueryLanguageSparql );
if( pimoIt.next() ) {
m_pimoThing = new Thing( pimoIt.binding("r").uri() );
}
}
return true;
}
else {
return false;
}
}
else {
return true;
}
}
void Nepomuk::ResourceData::setProperty( const QUrl& uri, const Nepomuk::Variant& value )
{
Q_ASSERT( uri.isValid() );
if( store() ) {
// step 0: make sure this resource is in the store
QMutexLocker lock(&m_modificationMutex);
// update the store
QDBusConnection bus = QDBusConnection::sessionBus();
QDBusMessage msg = QDBusMessage::createMethodCall( QLatin1String("org.kde.nepomuk.DataManagement"),
QLatin1String("/datamanagement"),
QLatin1String("org.kde.nepomuk.DataManagement"),
QLatin1String("setProperty") );
QString app = KGlobal::mainComponent().componentName();
QVariantList arguments;
QVariantList varList;
foreach( const Nepomuk::Variant var, value.toVariantList() ) {
// make sure resource values are in the store
if( var.simpleType() == qMetaTypeId<Resource>() ) {
var.toResource().m_data->store();
varList << var.toUrl();
}
else {
varList << var.variant();
}
}
arguments << DBus::convertUriList(QList<QUrl>() << m_uri) << DBus::convertUri(uri)
<< QVariant(DBus::normalizeVariantList(varList)) << app;
msg.setArguments( arguments );
QDBusMessage reply = bus.call( msg );
if( reply.type() == QDBusMessage::ErrorMessage ) {
//TODO: Set the error somehow
kWarning() << reply.errorMessage();
return;
}
// update the cache for now
if( value.isValid() )
m_cache[uri] = value;
else
m_cache.remove(uri);
// update the kickofflists
updateKickOffLists( uri, value );
}
}
+void Nepomuk::ResourceData::addProperty( const QUrl& uri, const Nepomuk::Variant& value )
+{
+ Q_ASSERT( uri.isValid() );
+
+ if( value.isValid() && store() ) {
+ // step 0: make sure this resource is in the store
+ QMutexLocker lock(&m_modificationMutex);
+
+ // update the store
+ QDBusConnection bus = QDBusConnection::sessionBus();
+ QDBusMessage msg = QDBusMessage::createMethodCall( QLatin1String("org.kde.nepomuk.DataManagement"),
+ QLatin1String("/datamanagement"),
+ QLatin1String("org.kde.nepomuk.DataManagement"),
+ QLatin1String("addProperty") );
+ QString app = KGlobal::mainComponent().componentName();
+ QVariantList arguments;
+ QVariantList varList;
+ foreach( const Nepomuk::Variant var, value.toVariantList() ) {
+ // make sure resource values are in the store
+ if( var.simpleType() == qMetaTypeId<Resource>() ) {
+ var.toResource().m_data->store();
+ varList << var.toUrl();
+ }
+ else {
+ varList << var.variant();
+ }
+ }
+
+ arguments << DBus::convertUriList(QList<QUrl>() << m_uri) << DBus::convertUri(uri)
+ << QVariant(DBus::normalizeVariantList(varList)) << app;
+ msg.setArguments( arguments );
+
+ QDBusMessage reply = bus.call( msg );
+ if( reply.type() == QDBusMessage::ErrorMessage ) {
+ //TODO: Set the error somehow
+ kWarning() << reply.errorMessage();
+ return;
+ }
+
+ // update the cache for now
+ if( value.isValid() )
+ m_cache[uri].append(value);
+
+ // update the kickofflists
+ updateKickOffLists( uri, value );
+ }
+}
+
+
void Nepomuk::ResourceData::removeProperty( const QUrl& uri )
{
Q_ASSERT( uri.isValid() );
if( !m_uri.isEmpty() ) {
QMutexLocker lock(&m_modificationMutex);
QDBusConnection bus = QDBusConnection::sessionBus();
QDBusMessage msg = QDBusMessage::createMethodCall( QLatin1String("org.kde.nepomuk.DataManagement"),
QLatin1String("/datamanagement"),
QLatin1String("org.kde.nepomuk.DataManagement"),
QLatin1String("removeProperties") );
QString app = KGlobal::mainComponent().componentName();
QVariantList arguments;
arguments << DBus::convertUri(m_uri) << DBus::convertUri(uri) << app;
msg.setArguments( arguments );
QDBusMessage reply = bus.call( msg );
if( reply.type() == QDBusMessage::ErrorMessage ) {
//TODO: Set the error somehow
kWarning() << reply.errorMessage();
return;
}
// Update the cache
m_cache.remove( uri );
// update the kickofflists
updateKickOffLists( uri, Variant() );
}
}
void Nepomuk::ResourceData::remove( bool recursive )
{
Q_UNUSED(recursive)
QMutexLocker lock(&m_modificationMutex);
if( !m_uri.isEmpty() ) {
QDBusConnection bus = QDBusConnection::sessionBus();
QDBusMessage msg = QDBusMessage::createMethodCall( QLatin1String("org.kde.nepomuk.DataManagement"),
QLatin1String("/datamanagement"),
QLatin1String("org.kde.nepomuk.DataManagement"),
QLatin1String("removeResources") );
QString app = KGlobal::mainComponent().componentName();
QVariantList arguments;
// TODO: Set the flag over here
arguments << DBus::convertUri(m_uri) << 0 << app;
msg.setArguments( arguments );
QDBusMessage reply = bus.call( msg );
if( reply.type() == QDBusMessage::ErrorMessage ) {
//TODO: Set the error somehow
kWarning() << reply.errorMessage();
return;
}
}
resetAll();
}
bool Nepomuk::ResourceData::exists()
{
if( m_uri.isValid() ) {
const QString query = QString::fromLatin1("ask { %1 ?p ?o . }")
.arg( Soprano::Node::resourceToN3(m_uri) );
return MAINMODEL->executeQuery( query, Soprano::Query::QueryLanguageSparql ).boolValue();
}
else {
return false;
}
}
bool Nepomuk::ResourceData::isValid() const
{
return( !m_mainType.isEmpty() && ( !m_uri.isEmpty() || !m_kickoffUris.isEmpty() ) );
}
Nepomuk::ResourceData* Nepomuk::ResourceData::determineUri()
{
// We have the following possible situations:
// 1. m_uri is already valid
// -> simple, nothing to do
//
// 2. m_uri is not valid
// -> we need to determine the URI
//
// 2.1. m_kickoffUri is valid
// 2.1.1. it is a file URL
// 2.1.1.1. it is nie:url for r
// -> use r as m_uri
// 2.1.1.2. it points to a file on a removable device for which we have a filex:/ URL
// -> use the r in r nie:url filex:/...
// 2.1.1.3. it is a file which is not an object in some nie:url relation
// -> create new random m_uri and use kickoffUriOrId() as m_nieUrl
// 2.1.2. it is a resource URI
// -> use it as m_uri
//
// 2.2. m_kickOffUri is not valid
// 2.2.1. m_kickOffUri is a nao:identifier for r
// -> use r as m_uri
//
if( m_uri.isEmpty() ) {
Soprano::Model* model = MAINMODEL;
if( !m_kickoffUris.isEmpty() ) {
KUrl kickOffUri = *m_kickoffUris.begin();
if( kickOffUri.scheme().isEmpty() ) {
//
// Not valid. Checking for nao:identifier
//
QString query = QString::fromLatin1("select distinct ?r where { ?r %1 %2. } LIMIT 1")
.arg( Soprano::Node::resourceToN3(Soprano::Vocabulary::NAO::identifier()) )
.arg( Soprano::Node::literalToN3( kickOffUri.url() ) );
Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparql );
if( it.next() ) {
m_uri = it["r"].uri();
it.close();
}
}
else {
//
// In one query determine if the URI is already used as resource URI or as
// nie:url
//
QString query = QString::fromLatin1("select distinct ?r ?o where { "
"{ ?r %1 %2 . FILTER(?r!=%2) . } "
"UNION "
"{ %2 ?p ?o . } "
"} LIMIT 1")
.arg( Soprano::Node::resourceToN3( Nepomuk::Vocabulary::NIE::url() ) )
.arg( Soprano::Node::resourceToN3( kickOffUri ) );
Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparql );
if( it.next() ) {
QUrl uri = it["r"].uri();
if( uri.isEmpty() ) {
m_uri = kickOffUri;
}
else {
m_uri = uri;
m_nieUrl = kickOffUri;
}
it.close();
}
else if( kickOffUri.scheme() == QLatin1String("nepomuk") ) {
// for nepomuk URIs we simply use the kickoff URI as resource URI
m_uri = kickOffUri;
}
else {
// for everything else we use m_kickoffUri as nie:url with a new random m_uri
m_nieUrl = kickOffUri;
}
}
}
}
//
// Move us to the final data hash now that the URI is known
//
if( !m_uri.isEmpty() ) {
//vHanda: Is there some way to avoid this hash lookup every time?
// It sure would speed things up.
ResourceDataHash::iterator it = m_rm->m_initializedData.find(m_uri);
if( it == m_rm->m_initializedData.end() ) {
m_rm->m_initializedData.insert( m_uri, this );
}
else {
return it.value();
}
}
return this;
}
void Nepomuk::ResourceData::invalidateCache()
{
m_cacheDirty = true;
}
Nepomuk::Thing Nepomuk::ResourceData::pimoThing()
{
load();
if( !m_pimoThing ) {
//
// We only create a new thing if we are a nie:InformationElement.
// All other resources will simply be converted into a pimo:Thing
//
// Files, however, are a special case in every aspect. this includes pimo things.
// Files are their own grounding occurrence. This makes a lot of things
// much simpler.
//
if( hasType( Vocabulary::PIMO::Thing() ) ||
isFile() ||
!hasType( Vocabulary::NIE::InformationElement() ) ) {
m_pimoThing = new Thing(this);
}
else {
m_pimoThing = new Thing();
}
m_pimoThing->m_data->m_groundingOccurence = this;
}
return *m_pimoThing;
}
bool Nepomuk::ResourceData::operator==( const ResourceData& other ) const
{
if( this == &other )
return true;
return( m_uri == other.m_uri &&
m_mainType == other.m_mainType &&
m_kickoffUris == other.m_kickoffUris );
}
QDebug Nepomuk::ResourceData::operator<<( QDebug dbg ) const
{
KUrl::List list = m_kickoffUris.toList();
dbg << QString::fromLatin1("[kickoffuri: %1; uri: %2; type: %3; ref: %4]")
.arg( list.toStringList().join(QLatin1String(",")),
m_uri.url(),
m_mainType.toString() )
.arg( m_ref );
return dbg;
}
QDebug operator<<( QDebug dbg, const Nepomuk::ResourceData& data )
{
return data.operator<<( dbg );
}
void Nepomuk::ResourceData::updateKickOffLists(const QUrl& prop, const Nepomuk::Variant& v)
{
KUrl oldUrl;
KUrl newUrl;
if( prop == Nepomuk::Vocabulary::NIE::url() ) {
oldUrl = m_nieUrl;
newUrl = v.toUrl();
m_nieUrl = newUrl;
}
else if( prop == Soprano::Vocabulary::NAO::identifier() ) {
Q_FOREACH( const KUrl& url, m_kickoffUris ) {
if( url.scheme().isEmpty() ) {
oldUrl = url;
break;
}
}
newUrl = KUrl( v.toString() );
}
else {
return;
}
if( oldUrl != newUrl ) {
QMutexLocker rmlock(&m_rm->mutex);
m_kickoffUris.remove( oldUrl );
m_rm->m_uriKickoffData.remove( oldUrl );
if( !newUrl.isEmpty() ) {
m_kickoffUris.insert( newUrl );
m_rm->m_uriKickoffData.insert( newUrl, this );
}
}
}
diff --git a/nepomuk/core/resourcedata.h b/nepomuk/core/resourcedata.h
index 461b225a56..be4f0a5bc7 100644
--- a/nepomuk/core/resourcedata.h
+++ b/nepomuk/core/resourcedata.h
@@ -1,217 +1,219 @@
/*
* This file is part of the Nepomuk KDE project.
* Copyright (C) 2006-2010 Sebastian Trueg <trueg@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef _NEPOMUK_RESOURCE_DATA_H_
#define _NEPOMUK_RESOURCE_DATA_H_
#include <QtCore/QString>
#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QMutex>
#include <QtCore/QAtomicInt>
#include <QtCore/QSet>
#include "variant.h"
#include "thing.h"
#include <kurl.h>
#include <soprano/statement.h>
namespace Nepomuk {
class Resource;
class ResourceManagerPrivate;
class ResourceData
{
public:
explicit ResourceData( const QUrl& uri, const QUrl& kickOffUri, const QUrl& type_, ResourceManagerPrivate* rm );
~ResourceData();
inline bool ref(Nepomuk::Resource* res) {
m_resources.push_back( res );
return m_ref.ref();
}
inline bool deref(Nepomuk::Resource* res) {
m_resources.removeAll( res );
return m_ref.deref();
}
inline int cnt() const {
return m_ref;
}
/**
* Tries to determine if this resource represents a file by examining the type and the uri.
*/
bool isFile();
/**
* The URI of the resource. This might be empty if the resource was not synced yet.
*/
QUrl uri() const;
/**
* \return The main type of the resource. ResourceData tries hard to make this the
* most important type, i.e. that which is furthest down the hierachy.
*/
QUrl type();
QList<QUrl> allTypes();
void setTypes( const QList<QUrl>& types );
QHash<QUrl, Variant> allProperties();
bool hasProperty( const QUrl& uri );
bool hasProperty( const QUrl& p, const Variant& v );
/**
* Does also check for subClass relations.
*/
bool hasType( const QUrl& uri );
/**
* Check the type without loading data from the store.
*/
bool constHasType( const QUrl& type ) const;
Variant property( const QUrl& uri );
/**
* Set a property. The property will directly be saved to the RDF store.
* Calls store to make sure this resource and property resources are properly
* stored.
*/
void setProperty( const QUrl& uri, const Variant& value );
+ void addProperty( const QUrl& uri, const Variant& value );
+
void removeProperty( const QUrl& uri );
/**
* Makes sure the resource is present in the RDF store. This means that if it does
* not exist the type and the identifier (if one has been used to create the instance)
* are stored.
*
* This is also the only place where a new URI is generated via ResourceManager::generateUniqueUri()
* in case m_uri is empty.
*
* \sa exists, setProperty
*/
bool store();
bool load();
/**
* Remove this resource data from the store completely.
* \param recursive If true all statements that contain this
* resource as an object will be removed, too.
*/
void remove( bool recursive = true );
/**
* This method only works with a proper URI, i.e. it does
* not work on non-initialized resources that only know
* their kickoffUriOrId
*/
bool exists();
bool isValid() const;
/**
* Searches for the resource in the Nepomuk store using m_kickoffId and m_kickoffUri.
*
* This will either get the actual resource URI from the database
* and add m_data into ResourceManagerPrivate::m_initializedData
* or it will find another ResourceData instance in m_initializedData
* which represents the same resource. The ResourceData that should be
* used is returned.
*
* \returns The initialized ResourceData object representing the actual resource.
*
* m_determineUriMutex needs to be locked before calling this method
*/
ResourceData* determineUri();
void invalidateCache();
Thing pimoThing();
/**
* Compares the properties of two ResourceData objects taking into account the Deleted flag
*/
bool operator==( const ResourceData& other ) const;
QDebug operator<<( QDebug dbg ) const;
ResourceManagerPrivate* rm() const { return m_rm; }
/// Contains a list of resources which use this ResourceData
QList<Resource*> m_resources;
/// the URI that was used to construct the resource. Will be used by determineUri
/// to find the actual resource URI which is either m_kickoffUri itself or
/// a resource URI which relates to m_kickoffUri by nie:url
/// This is a set since Resource::determineFinalResourceData may add additional uris
QSet<KUrl> m_kickoffUris;
private:
void loadType( const QUrl& type );
/// Will reset this instance to 0 as if constructed without parameters
/// Used by remove() and deleteData()
void resetAll( bool isDelete = false );
/// Updates both m_kickoffUris and ResourceMangerPrivate's list
void updateKickOffLists( const QUrl & prop, const Variant & v );
/// final resource URI created by determineUri
KUrl m_uri;
/// the URL of file resources
KUrl m_nieUrl;
QUrl m_mainType;
QList<QUrl> m_types;
QAtomicInt m_ref;
mutable QMutex m_modificationMutex;
QHash<QUrl, Variant> m_cache;
bool m_cacheDirty;
// using a pointer to avoid infinite creation loop
Thing* m_pimoThing;
// only used for delayed storage of the pimo thing relation
ResourceData* m_groundingOccurence;
ResourceManagerPrivate* m_rm;
};
}
QDebug operator<<( QDebug dbg, const Nepomuk::ResourceData& );
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Nov 1, 8:18 AM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10074888
Default Alt Text
(60 KB)
Attached To
Mode
rKL kdelibs
Attached
Detach File
Event Timeline
Log In to Comment