diff --git a/nepomuk/core/ontology/nepomukontologyloader.cpp b/nepomuk/core/ontology/nepomukontologyloader.cpp index 6702c9759f..b68ac43c86 100644 --- a/nepomuk/core/ontology/nepomukontologyloader.cpp +++ b/nepomuk/core/ontology/nepomukontologyloader.cpp @@ -1,70 +1,70 @@ /* This file is part of the Nepomuk-KDE libraries Copyright (c) 2007 Sebastian Trueg 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 "nepomukontologyloader.h" #include "global.h" -#include -#include -#include -#include +#include +#include +#include +#include #include class Nepomuk::NepomukOntologyLoader::Private { public: Soprano::Client::DBusClient client; }; Nepomuk::NepomukOntologyLoader::NepomukOntologyLoader() : OntologyLoader(), d( new Private() ) { } Nepomuk::NepomukOntologyLoader::~NepomukOntologyLoader() { delete d; } QList Nepomuk::NepomukOntologyLoader::loadOntology( const QUrl& uri ) { QList sl; if ( Soprano::Model* model = d->client.createModel( "main" ) ) { // get the complete named graph describing the ontology Soprano::QueryResultIterator it = model->executeQuery( QString( "construct {?s ?p ?o} " "where GRAPH <%1> { ?s ?p ?o. }" ) .arg( uri.toString() ), Soprano::Query::QUERY_LANGUAGE_SPARQL ); while ( it.next() ) { sl.append( it.currentStatement() ); } } else { qDebug() << "(NepomukOntologyLoader) could not find ontology statements for " << uri; } return sl; } diff --git a/nepomuk/core/ontology/test/desktopontologyloadertest.cpp b/nepomuk/core/ontology/test/desktopontologyloadertest.cpp index f36975a816..d73e62fd9b 100644 --- a/nepomuk/core/ontology/test/desktopontologyloadertest.cpp +++ b/nepomuk/core/ontology/test/desktopontologyloadertest.cpp @@ -1,102 +1,102 @@ /* This file is part of the Nepomuk-KDE libraries Copyright (c) 2007 Sebastian Trueg 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 "desktopontologyloadertest.h" #include "desktopontologyloader.h" #include #include #include #include #include #include #include #include #include #include #include -#include +#include void DesktopOntologyLoaderTest::initTestCase() { // create our test folder QDir tmpDir( "/tmp" ); tmpDir.mkpath( "konto_desktopontologyloader_test/knepomuk/ontologies" ); KGlobal::dirs()->addResourceDir( "data", "/tmp/konto_desktopontologyloader_test" ); // create our little test ontology QFile ontoFile( "/tmp/konto_desktopontologyloader_test/knepomuk/ontologies/test.nrl" ); ontoFile.open( QIODevice::WriteOnly ); QTextStream ontoStream( &ontoFile ); // the header ontoStream << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "]>" << endl << "" << endl; // one class ontoStream << "" << endl << "test" << endl << "" << endl << "" << endl; // the footer ontoStream << "" << endl; KDesktopFile desktopFile( "/tmp/konto_desktopontologyloader_test/knepomuk/ontologies/test.desktop" ); KConfigGroup desktopGroup( desktopFile.desktopGroup() ); desktopGroup.writeEntry( "Type", "Link" ); desktopGroup.writeEntry( "Name", "Test Ontology" ); desktopGroup.writeEntry( "MimeType", "text/rdf" ); desktopGroup.writeEntry( "Path", "test.nrl" ); desktopGroup.writeEntry( "URL", "http://test.org/test" ); } void DesktopOntologyLoaderTest::testLoading() { Nepomuk::DesktopOntologyLoader loader; QList sl = loader.loadOntology( QUrl( "http://test.org/test" ) ); QVERIFY( !sl.isEmpty() ); QCOMPARE( sl.count(), 2 ); } void DesktopOntologyLoaderTest::cleanupTestCase() { QFile::remove( "/tmp/konto_desktopontologyloader_test/knepomuk/ontologies/test.desktop" ); QFile::remove( "/tmp/konto_desktopontologyloader_test/knepomuk/ontologies/test.nrl" ); QDir( "/tmp/konto_desktopontologyloader_test/knepomuk/" ).rmdir( "ontologies" ); QDir( "/tmp/konto_desktopontologyloader_test" ).rmdir( "knepomuk" ); QDir( "/tmp/" ).rmdir( "konto_desktopontologyloader_test" ); } QTEST_KDEMAIN( DesktopOntologyLoaderTest, NoGUI ) #include "desktopontologyloadertest.moc" diff --git a/nepomuk/core/ontology/test/kontotest.cpp b/nepomuk/core/ontology/test/kontotest.cpp index 7ae8ccbe0c..ff656fc218 100644 --- a/nepomuk/core/ontology/test/kontotest.cpp +++ b/nepomuk/core/ontology/test/kontotest.cpp @@ -1,177 +1,177 @@ /* This file is part of the Nepomuk-KDE libraries Copyright (c) 2007 Sebastian Trueg 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 "kontotest.h" #include "../ontologyloader.h" #include "../ontologymanager.h" #include "../ontology.h" #include "../class.h" #include "../global.h" #include "../property.h" -#include +#include #include #include using namespace Nepomuk; using namespace Soprano; class DummyOntologyLoader : public OntologyLoader { public: QList loadOntology( const QUrl& uri ) { // create some dummy onto stuff QList sl; QString ns = uri.toString(); if ( !ns.endsWith( "#" ) ) { ns += '#'; } // one dummy class sl.append( Statement( Node( QUrl( ns + "DummyClass" ) ), Node( QUrl( RDF::type() ) ), Node( QUrl( RDF::NS() + "Class" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "DummyClass" ) ), Node( QUrl( RDFS::label() ) ), Node( LiteralValue( "A dummy class" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "DummySubClass" ) ), Node( QUrl( RDF::type() ) ), Node( QUrl( RDFS::NS() + "Class" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "DummySubClass" ) ), Node( QUrl( RDFS::NS() + "subClassOf" ) ), Node( QUrl( ns + "DummyClass" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "DummySubSubClass" ) ), Node( QUrl( RDF::type() ) ), Node( QUrl( RDFS::NS() + "Class" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "DummySubSubClass" ) ), Node( QUrl( RDFS::NS() + "subClassOf" ) ), Node( QUrl( ns + "DummySubClass" ) ) ) ); // one dummy property sl.append( Statement( Node( QUrl( ns + "hasBrother" ) ), Node( QUrl( RDF::type() ) ), Node( QUrl( RDFS::NS() + "Property" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "hasBrother" ) ), Node( QUrl( RDFS::NS() + "domain" ) ), Node( QUrl( ns + "DummyClass" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "hasBrother" ) ), Node( QUrl( RDFS::NS() + "range" ) ), Node( QUrl( ns + "DummyClass" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "hasBrother" ) ), Node( QUrl( NRL::NS() + "inverseProperty" ) ), Node( QUrl( ns + "isBrotherOf" ) ) ) ); // and its reverse property sl.append( Statement( Node( QUrl( ns + "isBrotherOf" ) ), Node( QUrl( RDF::type() ) ), Node( QUrl( RDFS::NS() + "Property" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "isBrotherOf" ) ), Node( QUrl( RDFS::NS() + "domain" ) ), Node( QUrl( ns + "DummyClass" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "isBrotherOf" ) ), Node( QUrl( RDFS::NS() + "range" ) ), Node( QUrl( ns + "DummyClass" ) ) ) ); sl.append( Statement( Node( QUrl( ns + "isBrotherOf" ) ), Node( QUrl( NRL::NS() + "inverseProperty" ) ), Node( QUrl( ns + "hasBrother" ) ) ) ); return sl; } }; void KontoTest::initTestCase() { OntologyManager::instance()->setOntologyLoader( new DummyOntologyLoader() ); } void KontoTest::testOntology() { const Ontology* onto = Ontology::load( QUrl( "test" ) ); QVERIFY( onto != 0 ); QCOMPARE( onto->uri(), QUrl( "test" ) ); } void KontoTest::testClass() { const Ontology* onto = Ontology::load( QUrl( "test" ) ); QCOMPARE( onto->allClasses().count(), 3 ); QVERIFY( onto->findClassByName( "DummyClass" ) != 0 ); QVERIFY( onto->findClassByUri( QUrl( "test#DummyClass" ) ) != 0 ); const Class* dummyClass = Class::load( QUrl( "test#DummyClass" ) ); QVERIFY( dummyClass != 0 ); QCOMPARE( dummyClass->name(), QString( "DummyClass" ) ); QCOMPARE( dummyClass->label(), QString( "A dummy class" ) ); const Class* dummySubClass = onto->findClassByName( "DummySubClass" ); const Class* dummySubSubClass = onto->findClassByName( "DummySubSubClass" ); QVERIFY( dummySubClass != 0 ); QVERIFY( dummySubSubClass != 0 ); QVERIFY( dummyClass->subClasses().contains( dummySubClass ) ); QVERIFY( dummySubClass->subClasses().contains( dummySubSubClass ) ); QVERIFY( dummySubClass->parentClasses().contains( dummyClass ) ); QVERIFY( dummySubSubClass->parentClasses().contains( dummySubClass ) ); QVERIFY( dummyClass->isParentOf( dummySubClass ) ); QVERIFY( dummyClass->isParentOf( dummySubSubClass ) ); QVERIFY( dummySubClass->isParentOf( dummySubSubClass ) ); QVERIFY( !dummySubClass->isParentOf( dummyClass ) ); QVERIFY( dummySubSubClass->isSubClassOf( dummyClass ) ); QVERIFY( dummySubSubClass->isSubClassOf( dummySubClass ) ); QVERIFY( dummySubClass->isSubClassOf( dummyClass ) ); QVERIFY( !dummySubClass->isSubClassOf( dummySubSubClass ) ); } void KontoTest::testProperty() { const Property* hasBrother = Property::load( QUrl( "test#hasBrother" ) ); const Property* isBrotherOf = Property::load( QUrl( "test#isBrotherOf" ) ); QVERIFY( hasBrother != 0 ); QVERIFY( isBrotherOf != 0 ); QCOMPARE( hasBrother->inverseProperty(), isBrotherOf ); QCOMPARE( isBrotherOf->inverseProperty(), hasBrother ); const Class* dummyClass = Class::load( QUrl( "test#DummyClass" ) ); QCOMPARE( hasBrother->range(), dummyClass ); QCOMPARE( hasBrother->domain(), dummyClass ); QCOMPARE( isBrotherOf->range(), dummyClass ); QCOMPARE( isBrotherOf->domain(), dummyClass ); } QTEST_MAIN( KontoTest ) #include "kontotest.moc" diff --git a/nepomuk/core/resourcedata.cpp b/nepomuk/core/resourcedata.cpp index 8329379774..e62eb4e138 100644 --- a/nepomuk/core/resourcedata.cpp +++ b/nepomuk/core/resourcedata.cpp @@ -1,581 +1,581 @@ /* * * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $ * * This file is part of the Nepomuk KDE project. * Copyright (C) 2006-2007 Sebastian Trueg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 "tools.h" #include "generated/resource.h" -#include -#include -#include +#include +#include +#include #include "ontology/class.h" #include using namespace Soprano; typedef QMap ResourceDataHash; Q_GLOBAL_STATIC( ResourceDataHash, initializedData ) Q_GLOBAL_STATIC( ResourceDataHash, kickoffData ) // FIXME: use Soprano::Vocabulary::RDFS::RESOURCE() static const char* s_defaultType = "http://www.w3.org/2000/01/rdf-schema#Resource"; static Nepomuk::Variant nodeToVariant( const Soprano::Node& node ) { if ( node.isResource() ) { return Nepomuk::Variant( Nepomuk::Resource( node.toString() ) ); } else if ( node.isLiteral() ) { return Nepomuk::Variant( node.literal().variant() ); } else { return Nepomuk::Variant(); } } Nepomuk::ResourceData::ResourceData( const QString& uriOrId, const QString& type_ ) : m_kickoffUriOrId( uriOrId ), m_type( type_ ), m_ref(0), m_proxyData(0) { if( m_type.isEmpty() && !uriOrId.isEmpty() ) m_type = s_defaultType; } Nepomuk::ResourceData::~ResourceData() { if( m_proxyData ) m_proxyData->deref(); } QString Nepomuk::ResourceData::kickoffUriOrId() const { if( m_proxyData ) return m_proxyData->kickoffUriOrId(); return m_kickoffUriOrId; } QString Nepomuk::ResourceData::uri() const { if( m_proxyData ) return m_proxyData->uri(); return m_uri; } QString Nepomuk::ResourceData::type() const { if( m_proxyData ) return m_proxyData->type(); return m_type; } void Nepomuk::ResourceData::deleteData() { if( m_proxyData ) if( m_proxyData->deref() ) m_proxyData->deleteData(); m_proxyData = 0; if( !m_uri.isEmpty() ) initializedData()->remove( m_uri ); if( !m_kickoffUriOrId.isEmpty() ) kickoffData()->remove( m_kickoffUriOrId ); // FIXME: crashes // delete this; } QHash Nepomuk::ResourceData::allProperties() { if( m_proxyData ) return m_proxyData->allProperties(); Soprano::Model* model = ResourceManager::instance()->mainModel(); QHash props; if ( determineUri() ) { Soprano::StatementIterator it = model->listStatements( Soprano::Statement( QUrl(m_uri), Soprano::Node(), Soprano::Node() ) ); while ( it.next() ) { Statement statement = *it; if ( props.contains( statement.predicate().toString() ) ) { props[statement.predicate().toString()].append( nodeToVariant( statement.object() ) ); } else { props.insert( statement.predicate().toString(), nodeToVariant( statement.object() ) ); } } it.close(); } return props; } bool Nepomuk::ResourceData::hasProperty( const QString& uri ) { if( m_proxyData ) return m_proxyData->hasProperty( uri ); if ( determineUri() ) { return ResourceManager::instance()->mainModel()->containsAnyStatement( Soprano::Statement( QUrl( m_uri ), QUrl( uri ), Soprano::Node() ) ); } else { return false; } } Nepomuk::Variant Nepomuk::ResourceData::property( const QString& uri ) { if( m_proxyData ) return m_proxyData->property( uri ); Variant v; if ( determineUri() ) { Soprano::Model* model = ResourceManager::instance()->mainModel(); Soprano::StatementIterator it = model->listStatements( Soprano::Statement( QUrl(m_uri), QUrl(uri), Soprano::Node() ) ); while ( it.next() ) { Statement statement = *it; if ( !v.isValid() ) { v = nodeToVariant( statement.object() ); } else { v.append( nodeToVariant( statement.object() ) ); } } it.close(); } return v; } bool Nepomuk::ResourceData::store() { if ( determineUri() ) { if ( !exists() ) { QList statements; // save type // FIXME: handle multiple types statements.append( Statement( QUrl(m_uri), QUrl(Nepomuk::typePredicate()), QUrl(m_type) ) ); // save the kickoff identifier (other identifiers are stored via setProperty) if ( !m_kickoffIdentifier.isEmpty() ) { statements.append( Statement( QUrl(m_uri), QUrl(Resource::identifierUri()), LiteralValue(m_kickoffIdentifier) ) ); } return ResourceManager::instance()->mainModel()->addStatements( statements ) == Soprano::Error::ErrorNone; } else { return true; } } else { return false; } } void Nepomuk::ResourceData::setProperty( const QString& uri, const Nepomuk::Variant& value ) { if( m_proxyData ) return m_proxyData->setProperty( uri, value ); // step 0: make sure this resource is in the store if ( store() ) { Soprano::Model* model = ResourceManager::instance()->mainModel(); // step 1: remove all the existing stuff model->removeAllStatements( Statement( QUrl(m_uri), QUrl(uri), Node() ) ); // step 2: make sure resource values are in the store if ( value.simpleType() == qMetaTypeId() ) { QList l = value.toResourceList(); for( QList::iterator resIt = l.begin(); resIt != l.end(); ++resIt ) { (*resIt).m_data->store(); } } // step 3: add the actual property statements // one-to-one Resource if( value.isResource() ) { model->addStatement( Statement( QUrl(m_uri), QUrl(uri), QUrl( value.toResource().uri() ) ) ); } // one-to-many Resource else if( value.isResourceList() ) { const QList& l = value.toResourceList(); for( QList::const_iterator resIt = l.constBegin(); resIt != l.constEnd(); ++resIt ) { model->addStatement( Statement( QUrl(m_uri), QUrl(uri), QUrl( (*resIt).uri() ) ) ); } } // one-to-many literals else if( value.isList() ) { QList nl = Nepomuk::valuesToRDFNodes( value ); for( QList::const_iterator nIt = nl.constBegin(); nIt != nl.constEnd(); ++nIt ) { model->addStatement( Statement( QUrl(m_uri), QUrl(uri), *nIt ) ); } } // one-to-one literal else { model->addStatement( Statement( QUrl(m_uri), QUrl(uri), Nepomuk::valueToRDFNode( value ) ) ); } } } void Nepomuk::ResourceData::removeProperty( const QString& uri ) { if( m_proxyData ) return m_proxyData->removeProperty( uri ); if ( determineUri() ) { ResourceManager::instance()->mainModel()->removeAllStatements( Statement( QUrl(m_uri), QUrl(uri), Node() ) ); } } void Nepomuk::ResourceData::remove( bool recursive ) { if( m_proxyData ) return m_proxyData->remove(); if ( determineUri() ) { Soprano::Model* model = ResourceManager::instance()->mainModel(); model->removeAllStatements( Statement( QUrl(m_uri), Node(), Node() ) ); if ( recursive ) { model->removeAllStatements( Statement( Node(), Node(), QUrl(m_uri) ) ); } } } bool Nepomuk::ResourceData::exists() { if( m_proxyData ) return m_proxyData->exists(); if( determineUri() ) { return ResourceManager::instance()->mainModel()->containsAnyStatement( Statement( QUrl( m_uri ), Node(), Node() ) ); } else return false; } bool Nepomuk::ResourceData::isValid() const { if( m_proxyData ) return m_proxyData->isValid(); // FIXME: check namespaces and stuff return( !m_type.isEmpty() ); } bool Nepomuk::ResourceData::determineUri() { if( m_proxyData ) return m_proxyData->determineUri(); if( m_uri.isEmpty() ) { Q_ASSERT( !m_kickoffUriOrId.isEmpty() ); m_modificationMutex.lock(); Soprano::Model* model = ResourceManager::instance()->mainModel(); if( model->containsAnyStatement( Statement( QUrl( kickoffUriOrId() ), Node(), Node() ) ) ) { // // The kickoffUriOrId is actually a URI // m_uri = kickoffUriOrId(); kDebug(300004) << " kickoff identifier " << kickoffUriOrId() << " exists as a URI " << uri(); updateType(); } else { // // Check if the kickoffUriOrId is a resource identifier // StatementIterator it = model->listStatements( Statement( Node(), Node(QUrl( Resource::identifierUri() )), LiteralValue( kickoffUriOrId() ) ) ); // // The kickoffUriOrId is an identifier // // Identifiers are not unique! // Thus, we do the following: // - If we have Ontology support, i.e. we know the classes: // We reuse a resource if its type is derived from the // current type of the other way around (example: an ImageFile // is a File and if we open an ImageFile as File we do want it to // keep its ImageFile type) // - If we do not have Ontology support: // Fallback to the default behaviour of always reusing existing // data. // // TODO: basically it is perfectly valid to store both types in the first case // Q_ASSERT( !m_type.isEmpty() ); const Nepomuk::Class* wantedType = Nepomuk::Class::load( m_type ); if ( wantedType && m_type != s_defaultType ) { while ( it.next() ) { // get the type of the stored resource StatementIterator resourceSl = model->listStatements( Statement( it.current().subject(), QUrl( typePredicate() ), Node() ) ); if ( resourceSl.next() ) { const Nepomuk::Class* storedType = Nepomuk::Class::load( resourceSl.current().object().uri() ); if ( storedType ) { if ( storedType == wantedType ) { // great. :) m_uri = it.current().subject().toString(); } else if ( wantedType->isSubClassOf( storedType ) ) { // Keep the type that is further down the hierarchy m_type = wantedType->uri().toString(); m_uri = it.current().subject().toString(); break; } else if ( storedType->isSubClassOf( wantedType ) ) { // just use the existing data with the finer grained type m_uri = it.current().subject().toString(); break; } } } } } else if ( it.next() ) { m_uri = it.current().subject().toString(); kDebug(300004) << k_funcinfo << " kickoff identifier " << kickoffUriOrId() << " already exists with URI " << uri(); updateType(); } it.close(); if ( m_uri.isEmpty() ) { // // The resource does not exist, create a new one // m_kickoffIdentifier = kickoffUriOrId(); m_uri = ResourceManager::instance()->generateUniqueUri(); kDebug(300004) << " kickoff identifier " << kickoffUriOrId() << " seems fresh. Generated new URI " << uri(); } } // // Move us to the final data hash now that the URI is known // if( !uri().isEmpty() && uri() != kickoffUriOrId() ) { if( !initializedData()->contains( uri() ) ) initializedData()->insert( uri(), this ); else { m_proxyData = initializedData()->value( uri() ); m_proxyData->ref(); } } m_modificationMutex.unlock(); return !uri().isEmpty(); } else return true; } void Nepomuk::ResourceData::updateType() { Soprano::Model* model = ResourceManager::instance()->mainModel(); // get the type of the stored resource StatementIterator typeStatements = model->listStatements( Statement( QUrl( m_uri ), QUrl( typePredicate() ), Node() ) ); if ( typeStatements.next() ) { // FIXME: handle multple types, maybe select the one type that fits best QString storedType = typeStatements.current().object().toString(); if ( m_type == s_defaultType ) { m_type = storedType; } else { const Nepomuk::Class* wantedTypeClass = Nepomuk::Class::load( m_type ); const Nepomuk::Class* storedTypeClass = Nepomuk::Class::load( storedType ); if ( wantedTypeClass && storedTypeClass ) { // Keep the type that is further down the hierarchy if ( wantedTypeClass->isSubClassOf( storedTypeClass ) ) { m_type = wantedTypeClass->uri().toString(); } } } } } bool Nepomuk::ResourceData::operator==( const ResourceData& other ) const { const ResourceData* that = this; if( m_proxyData ) that = m_proxyData; if( that == &other ) return true; if( that->m_uri != other.m_uri || that->m_type != other.m_type ) { kDebug(300004) << "different uri or type"; return false; } return true; } Nepomuk::ResourceData* Nepomuk::ResourceData::data( const QString& uriOrId, const QString& type ) { Q_ASSERT( !uriOrId.isEmpty() ); ResourceDataHash::iterator it = initializedData()->find( uriOrId ); bool resFound = ( it != initializedData()->end() ); // // The uriOrId is not a known local URI. Might be a kickoff value though // if( it == initializedData()->end() ) { it = kickoffData()->find( uriOrId ); // check if the type matches (see determineUri for details) if ( !type.isEmpty() && type != s_defaultType ) { const Nepomuk::Class* wantedType = Nepomuk::Class::load( type ); if ( wantedType ) { while ( it != kickoffData()->end() && it.key() == uriOrId ) { const Nepomuk::Class* storedType = Nepomuk::Class::load( it.value()->type() ); if ( storedType ) { if ( storedType->isSubClassOf( wantedType ) ) { break; } else if ( wantedType->isSubClassOf( storedType ) ) { it.value()->m_type = type; break; } } ++it; } } } resFound = ( it != kickoffData()->end() && it.key() == uriOrId ); } // // The uriOrId has no local representation yet -> create one // if( !resFound ) { kDebug(300004) << "No existing ResourceData instance found for uriOrId " << uriOrId; // // Every new ResourceData object ends up in the kickoffdata since its actual URI is not known yet // ResourceData* d = new ResourceData( uriOrId, type ); kickoffData()->insert( uriOrId, d ); return d; } else { // // Reuse the already existing ResourceData object // return it.value(); } } QList Nepomuk::ResourceData::allResourceDataOfType( const QString& type ) { QList l; if( !type.isEmpty() ) { for( ResourceDataHash::iterator rdIt = kickoffData()->begin(); rdIt != kickoffData()->end(); ++rdIt ) { if( rdIt.value()->type() == type ) { l.append( rdIt.value() ); } } } return l; } QList Nepomuk::ResourceData::allResourceDataWithProperty( const QString& _uri, const Variant& v ) { QList l; for( ResourceDataHash::iterator rdIt = kickoffData()->begin(); rdIt != kickoffData()->end(); ++rdIt ) { if( rdIt.value()->hasProperty( _uri ) && rdIt.value()->property( _uri ) == v ) { l.append( rdIt.value() ); } } return l; } QList Nepomuk::ResourceData::allResourceData() { QList l; for( ResourceDataHash::iterator rdIt = kickoffData()->begin(); rdIt != kickoffData()->end(); ++rdIt ) { l.append( rdIt.value() ); } return l; } diff --git a/nepomuk/core/resourcemanager.cpp b/nepomuk/core/resourcemanager.cpp index 8ed49c66f9..cbbff8f25f 100644 --- a/nepomuk/core/resourcemanager.cpp +++ b/nepomuk/core/resourcemanager.cpp @@ -1,229 +1,229 @@ /* * * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $ * * This file is part of the Nepomuk KDE project. * Copyright (C) 2006-2007 Sebastian Trueg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "resourcemanager.h" #include "resourcedata.h" #include "tools.h" #include "resource.h" #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include using namespace Soprano; static const char* NEPOMUK_NAMESPACE = "http://nepomuk.kde.org/resources#"; class Nepomuk::ResourceManager::Private { public: Private( ResourceManager* manager ) : client( "org.kde.nepomuk.DataRepository" ), mainModel( 0 ), dummyModel( 0 ), m_parent(manager) { } Soprano::Client::DBusClient client; Soprano::Model* mainModel; Soprano::DummyModel* dummyModel; private: ResourceManager* m_parent; }; Nepomuk::ResourceManager::ResourceManager() : QObject(), d( new Private( this ) ) { } Nepomuk::ResourceManager::~ResourceManager() { delete d->dummyModel; delete d; } class Nepomuk::ResourceManagerHelper { public: Nepomuk::ResourceManager q; }; K_GLOBAL_STATIC(Nepomuk::ResourceManagerHelper, instanceHelper) // FIXME: make the singleton deletion thread-safe so autosyncing will be forced when shutting // down the application // Maybe connect to QCoreApplication::aboutToQuit? Nepomuk::ResourceManager* Nepomuk::ResourceManager::instance() { return &instanceHelper->q; } int Nepomuk::ResourceManager::init() { return ( initialized() ? 0 : -1 ); } bool Nepomuk::ResourceManager::initialized() const { return d->client.isValid(); } Nepomuk::Resource Nepomuk::ResourceManager::createResourceFromUri( const QString& uri ) { return Resource( uri, QString() ); } void Nepomuk::ResourceManager::notifyError( const QString& uri, int errorCode ) { kDebug(300004) << "(Nepomuk::ResourceManager) error: " << uri << " " << errorCode; emit error( uri, errorCode ); } QList Nepomuk::ResourceManager::allResourcesOfType( const QString& type ) { QList l; if( !type.isEmpty() ) { // check local data QList localData = ResourceData::allResourceDataOfType( type ); for( QList::iterator rdIt = localData.begin(); rdIt != localData.end(); ++rdIt ) { l.append( Resource( *rdIt ) ); } kDebug(300004) << " added local resources: " << l.count(); Soprano::Model* model = mainModel(); Soprano::StatementIterator it = model->listStatements( Soprano::Statement( Soprano::Node(), Soprano::Vocabulary::RDF::type(), QUrl(type) ) ); while( it.next() ) { Statement s = *it; Resource res( s.subject().toString() ); if( !l.contains( res ) ) l.append( res ); } kDebug(300004) << " added remote resources: " << l.count(); } return l; } QList Nepomuk::ResourceManager::allResourcesWithProperty( const QString& uri, const Variant& v ) { QList l; if( v.isList() ) { kDebug(300004) << "(ResourceManager::allResourcesWithProperty) list values not supported."; } else { // check local data QList localData = ResourceData::allResourceDataWithProperty( uri, v ); for( QList::iterator rdIt = localData.begin(); rdIt != localData.end(); ++rdIt ) { l.append( Resource( *rdIt ) ); } // check remote data Soprano::Node n; if( v.isResource() ) { n = QUrl( v.toResource().uri() ); } else { n = valueToRDFNode(v); } Soprano::Model* model = mainModel(); Soprano::StatementIterator it = model->listStatements( Soprano::Statement( Soprano::Node(), QUrl(uri), n ) ); while( it.next() ) { Statement s = *it; Resource res( s.subject().toString() ); if( !l.contains( res ) ) l.append( res ); } } return l; } QString Nepomuk::ResourceManager::generateUniqueUri() { Soprano::Model* model = mainModel(); QUrl s; while( 1 ) { // Should we use the Nepomuk localhost whatever namespace here? s = NEPOMUK_NAMESPACE + KRandom::randomString( 20 ); if( !model->containsContext( s ) && !model->containsAnyStatement( Soprano::Statement( s, Soprano::Node(), Soprano::Node() ) ) && !model->containsAnyStatement( Soprano::Statement( Soprano::Node(), s, Soprano::Node() ) ) && !model->containsAnyStatement( Soprano::Statement( Soprano::Node(), Soprano::Node(), s ) ) ) return s.toString(); } } Soprano::Model* Nepomuk::ResourceManager::mainModel() { // make sure we are initialized if ( !initialized() ) { delete d->mainModel; d->mainModel = 0; init(); } if ( !d->mainModel ) { d->mainModel = d->client.createModel( "main" ); } if ( !d->mainModel ) { if ( !d->dummyModel ) { d->dummyModel = new Soprano::DummyModel(); } return d->dummyModel; } return d->mainModel; } #include "resourcemanager.moc"