diff --git a/nepomuk/rcgen/ontologyparser.cpp b/nepomuk/rcgen/ontologyparser.cpp index de1b4ba7fa..6bf4badc96 100644 --- a/nepomuk/rcgen/ontologyparser.cpp +++ b/nepomuk/rcgen/ontologyparser.cpp @@ -1,263 +1,272 @@ /* * * $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. * See the file "COPYING.LIB" for the exact licensing terms. */ #include "ontologyparser.h" #include "resourceclass.h" #include "resourcetemplate.h" #include #include #include #include #include #include #include +extern bool quiet; + class OntologyParser::Private { public: Private() { // default parent class resources.insert( "http://www.w3.org/2000/01/rdf-schema#Resource", ResourceClass( "http://www.w3.org/2000/01/rdf-schema#Resource" ) ); } QMap resources; QMap properties; QMap comments; const Soprano::Parser* rdfParser; QHash namespaceAbbr; QString ensureNS( const QString& uri ) { // check if we have a NS abbrev QString ns = uri.left( uri.indexOf( ":" ) ); if( namespaceAbbr.contains( ns ) ) return namespaceAbbr[ns] + uri.mid( ns.length()+1 ); else return uri; } ResourceClass& getResource( const QString& uri ) { ResourceClass& r = resources[ensureNS(uri)]; r.uri = ensureNS(uri); if ( !r.parent ) { r.parent = &resources["http://www.w3.org/2000/01/rdf-schema#Resource"]; } return r; } Property& getProperty( const QString& uri ) { Property& p = properties[ensureNS(uri)]; p.uri = ensureNS(uri); return p; } }; OntologyParser::OntologyParser() { d = new Private; d->rdfParser = 0; } OntologyParser::~OntologyParser() { delete d; } bool OntologyParser::assignTemplates( const QStringList& templates ) { // FIXME: do an actual class name mapping by parsing the class foreach( QString tf, templates ) { QString filename = QFileInfo( tf ).fileName(); for( QMap::iterator it = d->resources.begin(); it != d->resources.end(); ++it ) { // we use startsWith() for a hackish handling of such suffixes as ".in" if( filename.startsWith( it.value().headerName() ) ) { - qDebug() << "Using header template file " << tf << " for class " << it.value().name(); + if ( !quiet ) + qDebug() << "Using header template file " << tf << " for class " << it.value().name(); it.value().headerTemplateFilePath = tf; } else if( filename.startsWith( it.value().sourceName() ) ) { - qDebug() << "Using source template file " << tf << " for class " << it.value().name(); + if ( !quiet ) + qDebug() << "Using source template file " << tf << " for class " << it.value().name(); it.value().sourceTemplateFilePath = tf; } } } return true; } bool OntologyParser::parse( const QString& filename ) { Soprano::RdfSerialization serialization; if ( filename.endsWith( "trig" ) ) { serialization = Soprano::SerializationTrig; } else { serialization = Soprano::SerializationRdfXml; } if ( !( d->rdfParser = Soprano::PluginManager::instance()->discoverParserForSerialization( serialization ) ) ) { return false; } - qDebug() << "(OntologyParser) Parsing " << filename << endl; + if ( !quiet ) + qDebug() << "(OntologyParser) Parsing " << filename << endl; // get the namespaces the hacky way QFile f( filename ); if( f.open( QIODevice::ReadOnly | QIODevice::Text ) ) { QString s = QTextStream( &f ).readAll(); QRegExp nsr( "xmlns:(\\S*)=\"(\\S*\\#)\"" ); int pos = 0; while( ( pos = s.indexOf( nsr, pos+1 ) ) > 0 ) { - qDebug() << "Found namespace abbrevation: " << nsr.cap(1) << "->" << nsr.cap(2) << endl; + if ( !quiet ) + qDebug() << "Found namespace abbrevation: " << nsr.cap(1) << "->" << nsr.cap(2) << endl; d->namespaceAbbr.insert( nsr.cap(1), nsr.cap(2) ); } } // FIXME: the serialization should be somehow specified Soprano::StatementIterator it = d->rdfParser->parseFile( filename, QUrl("http://org.kde.nepomuk/dummybaseuri"), serialization ); bool success = true; while( it.next() ) { const Soprano::Statement& s = *it; if( s.predicate().uri().toString().endsWith( "#subClassOf" ) ) { ResourceClass& rc = d->getResource( s.subject().uri().toString() ); rc.parent = &d->getResource( s.object().uri().toString() ); rc.allParents.append( &d->getResource( s.object().uri().toString() ) ); rc.generate = true; } else if( s.predicate().uri().toString().endsWith( "#type" ) ) { if( s.object().uri().toString().endsWith( "#Class" ) ) d->getResource( s.subject().uri().toString() ).generate = true; } else if( s.predicate().uri().toString().endsWith( "#domain" ) ) { ResourceClass& rc = d->getResource( s.object().uri().toString() ); Property& p = d->getProperty( s.subject().uri().toString() ); p.domain = &rc; if ( !rc.properties.contains( &p ) ) rc.properties.append( &p ); rc.generate = true; } else if( s.predicate().uri().toString().endsWith( "#range" ) ) { d->getProperty(s.subject().uri().toString()).type = d->ensureNS(s.object().uri().toString()); } else if( s.predicate().uri().toString().endsWith( "#maxCardinality" ) || s.predicate().uri().toString().endsWith( "#cardinality" ) ) { d->getProperty(s.subject().uri().toString()).list = ( s.object().literal().toInt() > 1 ); } else if( s.predicate().uri().toString().endsWith( "#comment" ) ) { d->comments[d->ensureNS(s.subject().uri().toString())] = s.object().literal().toString(); } else if ( s.predicate().uri().toString().endsWith("inverseProperty") ) { d->getProperty(s.subject().uri().toString()).inverse = &d->getProperty(s.object().uri().toString()); d->getProperty(s.object().uri().toString()).inverse = &d->getProperty(s.subject().uri().toString()); } } // determine the reverse properties for( QMap::iterator propIt = d->properties.begin(); propIt != d->properties.end(); ++propIt ) { Property& p = propIt.value(); if( d->resources.contains( p.type ) ) { - qDebug() << "Setting reverse property " << p.uri << " on type " << p.type << endl; + if ( !quiet ) + qDebug() << "Setting reverse property " << p.uri << " on type " << p.type << endl; if ( !d->resources[p.type].reverseProperties.contains( &p ) ) d->resources[p.type].reverseProperties.append( &p ); } if ( !p.domain ) { p.domain = &d->resources["http://www.w3.org/2000/01/rdf-schema#Resource"]; } Q_ASSERT( d->properties.count( propIt.key() ) == 1 ); } // now assign the comments to resources and properties QMapIterator commentsIt( d->comments ); while( commentsIt.hasNext() ) { commentsIt.next(); if( d->resources.contains( commentsIt.key() ) ) d->resources[commentsIt.key()].comment = commentsIt.value(); else if( d->properties.contains( commentsIt.key() ) ) d->properties[commentsIt.key()].comment = commentsIt.value(); } // testing stuff for( QMap::iterator it = d->resources.begin(); it != d->resources.end(); ++it ) { if( !it->parent ) { it->parent = &d->resources["http://www.w3.org/2000/01/rdf-schema#Resource"]; } - qDebug() << "Resource: " << (*it).name() - << "[" << (*it).uri << "]" - << " (->" << (*it).parent->name() << ")" - << ( (*it).generateClass() ? " (will be generated)" : " (will not be generated)" ) - << endl; + if ( !quiet ) + qDebug() << "Resource: " << (*it).name() + << "[" << (*it).uri << "]" + << " (->" << (*it).parent->name() << ")" + << ( (*it).generateClass() ? " (will be generated)" : " (will not be generated)" ) + << endl; Q_ASSERT( d->resources.count( it.key() ) == 1 ); QListIterator propIt( (*it).properties ); while( propIt.hasNext() ) { const Property* p = propIt.next(); - qDebug() << " " << p->uri << " (->" << p->type << ")" << ( p->list ? QString("+") : QString("1") ) << endl; + if ( !quiet ) + qDebug() << " " << p->uri << " (->" << p->type << ")" << ( p->list ? QString("+") : QString("1") ) << endl; } } return success; } bool OntologyParser::writeSources( const QString& dir ) { bool success = true; for( QMap::const_iterator it = d->resources.constBegin(); it != d->resources.constEnd(); ++it ) { if( (*it).generateClass() ) success &= (*it).write( dir + QDir::separator() ); } return success; } QStringList OntologyParser::listHeader() { QStringList l; for( QMap::const_iterator it = d->resources.constBegin(); it != d->resources.constEnd(); ++it ) if( (*it).generateClass() ) l.append( (*it).headerName() ); return l; } QStringList OntologyParser::listSources() { QStringList l; for( QMap::const_iterator it = d->resources.constBegin(); it != d->resources.constEnd(); ++it ) if( (*it).generateClass() ) l.append( (*it).sourceName() ); return l; } diff --git a/nepomuk/rcgen/rcgen.cpp b/nepomuk/rcgen/rcgen.cpp index 6a0751be59..48fdf1a447 100644 --- a/nepomuk/rcgen/rcgen.cpp +++ b/nepomuk/rcgen/rcgen.cpp @@ -1,165 +1,169 @@ /* * * $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. * See the file "COPYING.LIB" for the exact licensing terms. */ #include #include #include #include #include "resourceclass.h" #include "ontologyparser.h" +bool quiet = false; + static int usage() { QTextStream( stderr, QIODevice::WriteOnly ) << "Usage:" << endl << " " << QCoreApplication::instance()->arguments()[0] << " --writeall [--templates [ [ ...]]] --target --ontologies " << endl << " " << QCoreApplication::instance()->arguments()[0] << " --listincludes --ontologies " << endl << " " << QCoreApplication::instance()->arguments()[0] << " --listheaders [--prefix ] --ontologies " << endl << " " << QCoreApplication::instance()->arguments()[0] << " --listsources [--prefix ] --ontologies " << endl; return 1; } int main( int argc, char** argv ) { // we probably need a QCoreApplication instance for some // stuff. If not, who cares, we don't do anything time relevant here QCoreApplication app( argc, argv ); bool writeAll = false, listHeader = false, listSource = false, listIncludes = false; QStringList ontoFiles; QString targetDir, prefix; QStringList templates; QStringList args = app.arguments(); if( args.count() < 2 ) return usage(); QStringList::const_iterator argIt = args.begin(); ++argIt; // skip the app name while (argIt != args.end()) { const QString& arg = *argIt; // new parameter if ( arg.startsWith("--") ) { // gather parameter arg QStringList paramArgs; ++argIt; while ( argIt != args.end() && !(*argIt).startsWith("--") ) { paramArgs += *argIt; ++argIt; } // now lets see what we have if ( arg == "--writeall" ) { writeAll = true; } else if ( arg == "--listincludes" ) { listIncludes = true; } else if ( arg == "--listheaders" ) { listHeader = true; } else if ( arg == "--listsources" ) { listSource = true; } else if ( arg == "--templates" ) { templates = paramArgs; } else if ( arg == "--ontologies" ) { if ( paramArgs.isEmpty() ) { return usage(); } ontoFiles = paramArgs; } else if ( arg == "--prefix" ) { if ( paramArgs.count() != 1 ) { return usage(); } prefix = paramArgs.first(); } else if ( arg == "--target" ) { if ( paramArgs.count() != 1 ) { return usage(); } targetDir = paramArgs.first(); } + else if ( arg == "--quiet" ) { + quiet = true; + } else { return usage(); } } else return usage(); } foreach( QString ontoFile, ontoFiles ) { if( !QFile::exists( ontoFile ) ) { qDebug() << "Ontology file " << ontoFile << " does not exist." << endl; return usage(); } } if( writeAll ) { if( !QFile::exists( targetDir ) ) { qDebug() << "Folder " << targetDir << " does not exist." << endl; return usage(); } } OntologyParser prsr; foreach( QString ontoFile, ontoFiles ) { if( !prsr.parse( ontoFile ) ) { qDebug() << "Parsing ontology file " << ontoFile << " failed." << endl; return usage(); } } if( writeAll ) { if( !prsr.assignTemplates( templates ) ) { return usage(); } - qDebug() << "Writing sources to " << targetDir << endl; if( !prsr.writeSources( targetDir ) ) { qDebug() << "Writing sources to " << targetDir << " failed." << endl; return usage(); } } else if( listSource ) { QStringList l = prsr.listSources(); QTextStream s( stdout, QIODevice::WriteOnly ); QStringListIterator it( l ); while( it.hasNext() ) s << prefix << it.next() << ";"; } else if( listHeader ) { QStringList l = prsr.listHeader(); QTextStream s( stdout, QIODevice::WriteOnly ); QStringListIterator it( l ); while( it.hasNext() ) s << prefix << it.next() << ";"; } else if( listIncludes ) { QStringList l = prsr.listHeader(); QTextStream s( stdout, QIODevice::WriteOnly ); QStringListIterator it( l ); while( it.hasNext() ) s << "#include " << endl; } return 0; } diff --git a/nepomuk/rcgen/resourceclass.cpp b/nepomuk/rcgen/resourceclass.cpp index 6045c0cae4..1eb713681f 100644 --- a/nepomuk/rcgen/resourceclass.cpp +++ b/nepomuk/rcgen/resourceclass.cpp @@ -1,689 +1,696 @@ /* * * $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. * See the file "COPYING.LIB" for the exact licensing terms. */ #include "resourceclass.h" #include "resourcetemplate.h" #include #include #include #include #include #include +extern bool quiet; + static const QString s_typeComment = " // We always store all Resource types as plain Resource objects.\n" " // It does not introduce any overhead (due to the implicit sharing of\n" " // the data and has the advantage that we can mix setProperty calls\n" " // with the special Resource subclass methods.\n" " // More importantly Resource loads the data as Resource objects anyway.\n"; static QString writeComment( const QString& comment, int indent ) { static const int maxLine = 50; QString s; if( !comment.isEmpty() ) { s += QString().fill( ' ', indent ); s += "/**\n" + QString().fill( ' ', indent+1 ) + "* "; QStringList words = comment.split( QRegExp("\\s"), QString::SkipEmptyParts ); int cnt = 0; for( int i = 0; i < words.count(); ++i ) { if( cnt >= maxLine ) { s += '\n' + QString().fill( ' ', indent+1 ) + "* "; cnt = 0; } s += words[i] + ' '; cnt += words[i].length(); } if( cnt > 0 ) s += '\n'; s += QString().fill( ' ', indent+1 ) + "*/"; } return s; } Property::Property() : list(true), domain(0), inverse(0) { } Property::Property( const QString& uri_, const QString& type_ ) : uri(uri_), type(type_), list(true), domain(0), inverse(0) { } QString Property::name() const { // // many predicates are named "hasSomething" // we remove the "has" becasue setHasSomething sounds weird // QString n = uri.section( QRegExp( "[#:]" ), -1 ); if( n.toLower().startsWith( "has" ) ) return n.mid( 3 ); else return n; } QString Property::typeString( bool simple, bool withNamespace ) const { QString t; if( type.contains( "XMLSchema" ) ) { // XML Schema types // FIXME: move this map somewhere else QHash xmlSchemaTypes; xmlSchemaTypes.insert( "integer", "qint64" ); xmlSchemaTypes.insert( "nonNegativeInteger", "quint64" ); xmlSchemaTypes.insert( "nonPositiveInteger", "qint64" ); xmlSchemaTypes.insert( "negativeInteger", "qint64" ); xmlSchemaTypes.insert( "positiveInteger", "quint64" ); xmlSchemaTypes.insert( "long", "qint64" ); xmlSchemaTypes.insert( "unsignedLong", "quint64" ); xmlSchemaTypes.insert( "int", "qint32" ); xmlSchemaTypes.insert( "unsignedInt", "quint32" ); xmlSchemaTypes.insert( "short", "qint16" ); xmlSchemaTypes.insert( "unsignedShort", "quint16" ); xmlSchemaTypes.insert( "byte", "char" ); xmlSchemaTypes.insert( "unsignedByte", "unsigned char" ); xmlSchemaTypes.insert( "float", "float" ); xmlSchemaTypes.insert( "double", "double" ); xmlSchemaTypes.insert( "boolean", "bool" ); xmlSchemaTypes.insert( "date", "QDate" ); xmlSchemaTypes.insert( "time", "QTime" ); xmlSchemaTypes.insert( "dateTime", "QDateTime" ); xmlSchemaTypes.insert( "string", "QString" ); t = xmlSchemaTypes[type.mid(type.lastIndexOf( "#" ) + 1 )]; } else if( type.endsWith( "#Literal" ) ) { t = "QString"; } else { t = type.section( QRegExp( "[#:]" ), -1 ); if( withNamespace ) t.prepend( "Nepomuk::" ); } if( !simple && list ) { if( t == "QString" ) return "QStringList"; else return "QList<" + t + '>'; } Q_ASSERT( !t.isEmpty() ); return t; } bool Property::hasSimpleType() const { return ( type.contains( "XMLSchema" ) || type.endsWith( "#Literal" ) ); } QString Property::setterDeclaration( const ResourceClass* rc, bool withNamespace ) const { return QString( "void %1set%2%3%4( const %5& value )" ) .arg( withNamespace ? QString("Nepomuk::%1::").arg(rc->name()) : QString() ) .arg( name()[0].toUpper() ) .arg( name().mid(1) ) .arg( list ? QString("s") : QString() ) .arg( typeString( false, withNamespace ) ); } QString Property::getterDeclaration( const ResourceClass* rc, bool withNamespace ) const { return QString( "%1 %2%3%4%5() const" ) .arg( typeString( false, withNamespace ) ) .arg( withNamespace ? QString("Nepomuk::%1::").arg(rc->name()) : QString() ) .arg( name()[0].toLower() ) .arg( name().mid(1) ) .arg( list ? QString("s") : QString() ); } QString Property::adderDeclaration( const ResourceClass* rc, bool withNamespace ) const { return QString( "void %1add%2%3( const %4& value )" ) .arg( withNamespace ? QString("Nepomuk::%1::").arg(rc->name()) : QString() ) .arg( name()[0].toUpper() ) .arg( name().mid(1) ) .arg( typeString( true, withNamespace ) ); } QString Property::reversePropertyGetterDeclaration( const ResourceClass* rc, bool withNamespace ) const { Q_ASSERT( rc ); Q_ASSERT( domain ); return QString( "%1 %2%3%4Of() const" ) .arg( QString("QList<") + domain->name( withNamespace ) + QString(">") ) .arg( withNamespace ? QString("Nepomuk::%1::").arg(rc->name()) : QString() ) .arg( name()[0].toLower() ) .arg( name().mid(1) ); } QString Property::setterDefinition( const ResourceClass* rc ) const { QString s = setterDeclaration( rc, true ) + '\n'; if( hasSimpleType() || typeString( true ) == "Resource" || !list ) { s += QString("{\n" " setProperty( \"%1\", Variant( value ) );\n" "}\n" ) .arg( uri ); } else if( list ) { s += QString("{\n" "%1" " QList l;\n" " for( %2::const_iterator it = value.constBegin();\n" " it != value.constEnd(); ++it ) {\n" " l.append( Resource( (*it) ) );\n" " }\n" " setProperty( \"%3\", Variant( l ) );\n" "}\n" ) .arg( s_typeComment ) .arg( typeString() ) .arg( uri ); } else { s += QString("{\n" "%1" " setProperty( \"%2\", Variant( Resource( value ) ) );\n" "}\n" ) .arg( s_typeComment ) .arg( uri ); } return s; } QString Property::typeConversionMethod() const { // for properties with cardinality == 1 we use a little hack since there will always be duplication of // data. if ( typeString(false) == "QStringList" ) { return QLatin1String("toStringList())"); } else if ( typeString(true) == "QString" ) { return QLatin1String("toStringList() << QString() ).first()"); } else if ( typeString(true) == "qint32" ) { return list ? QLatin1String("toIntList())") : QLatin1String("toIntList() << 0 ).first()"); } else if ( typeString(true) == "quint32" ) { return list ? QLatin1String("toUnsignedIntList())") : QLatin1String("toUnsignedIntList() << 0 ).first()"); } else if ( typeString(true) == "qint64" ) { return list ? QLatin1String("toInt64List())") : QLatin1String("toInt64List() << 0 ).first()"); } else if ( typeString(true) == "quint64" ) { return list ? QLatin1String("toUnsignedInt64List())") : QLatin1String("toUnsignedInt64List() << 0 ).first()"); } else if ( typeString(true) == "bool" ) { return list ? QLatin1String("toBoolList())") : QLatin1String("toBoolList() << false ).first()"); } else if ( typeString(true) == "double" ) { return list ? QLatin1String("toDoubleList())") : QLatin1String("toDoubleList() << 0.0 ).first()"); } else if ( typeString(true) == "QDateTime" ) { return list ? QLatin1String("toDateTimeList())") : QLatin1String("toDateTimeList() << QDateTime() ).first()"); } else if ( typeString(true) == "QDate" ) { return list ? QLatin1String("toDateList())") : QLatin1String("toDateList() << QDate() ).first()"); } else if ( typeString(true) == "QTime" ) { return list ? QLatin1String("toTimeList())") : QLatin1String("toTimeList() << QTime() ).first()"); } - qDebug() << "Unknown type:" << typeString(true); - Q_ASSERT(0); + if ( !quiet ) + qDebug() << "Unknown type:" << typeString(true); + return QString(); } QString Property::getterDefinition( const ResourceClass* rc ) const { QString s = getterDeclaration( rc, true ) + '\n'; if( hasSimpleType() ) { s += QString( "{\n" " return ( property( \"%1\" ).%2;\n" "}\n" ) .arg( uri ) .arg( typeConversionMethod() ); } else if( list ) { s += QString("{\n" "%1" " return convertResourceList<%3>( property( \"%2\" ).toResourceList() );\n" "}\n" ) .arg( s_typeComment ) .arg( uri ) .arg( typeString( true ) ); } else { s += QString("{\n" "%1" " return %2( property( \"%3\" ).toResource().uri() );\n" "}\n" ) .arg( s_typeComment ) .arg( typeString( true ) ) .arg( uri ); } return s; } QString Property::adderDefinition( const ResourceClass* rc ) const { QString s = adderDeclaration( rc, true ) + '\n'; if( hasSimpleType() ) { s += QString( "{\n" " Variant v = property( \"%1\" );\n" " v.append( value );\n" " setProperty( \"%1\", v );\n" "}\n" ) .arg( uri ); } else { s += QString( "{\n" "%1" " Variant v = property( \"%2\" );\n" " v.append( Resource( value ) );\n" " setProperty( \"%2\", v );\n" "}\n" ) .arg( s_typeComment ) .arg( uri ); } return s; } QString Property::reversePropertyGetterDefinition( const ResourceClass* rc ) const { QString s = reversePropertyGetterDeclaration( rc, true ) + '\n'; s += QString( "{\n" " return convertResourceList<%2>( ResourceManager::instance()->allResourcesWithProperty( \"%1\", *this ) );\n" "}\n" ) .arg( uri ) .arg( domain->name() ); return s; } ResourceClass::ResourceClass() : parent( 0 ), generate( false ) { } ResourceClass::ResourceClass( const QString& uri_ ) : parent( 0 ), generate( false ), uri( uri_ ) { } ResourceClass::~ResourceClass() { } QString ResourceClass::name( bool withNamespace ) const { QString s = uri.section( QRegExp( "[#:]" ), -1 ); if( withNamespace ) s.prepend( "Nepomuk::" ); return s; } QString ResourceClass::headerName() const { return name().toLower() + ".h"; } QString ResourceClass::sourceName() const { return name().toLower() + ".cpp"; } QString ResourceClass::allResourcesDeclaration( bool withNamespace ) const { return QString( "QList<%1%2> %3all%2s()" ) .arg( withNamespace ? QString("Nepomuk::") : QString() ) .arg( name() ) .arg( withNamespace ? QString("Nepomuk::%1::").arg( name() ) : QString() ); } QString ResourceClass::allResourcesDefinition() const { return QString( "%1\n" "{\n" " return Nepomuk::convertResourceList<%3>( ResourceManager::instance()->allResourcesOfType( \"%2\" ) );\n" "}\n" ) .arg( allResourcesDeclaration( true ) ) .arg( uri ) .arg( name() ); } QString ResourceClass::pseudoInheritanceDeclaration( ResourceClass* rc, bool withNamespace ) const { return QString( "%1 %2to%3() const" ) .arg( rc->name( withNamespace ) ) .arg( withNamespace ? name( true ) + "::" : QString() ) .arg( rc->name( false ) ); } QString ResourceClass::pseudoInheritanceDefinition( ResourceClass* rc ) const { return QString( "%1\n" "{\n" " return %2( *this );\n" "}\n" ) .arg( pseudoInheritanceDeclaration( rc, true ) ) .arg( rc->name( true ) ); } bool ResourceClass::writeHeader( QTextStream& stream ) const { QString s = headerTemplate; if( QFile::exists( headerTemplateFilePath ) ) { QFile f( headerTemplateFilePath ); if( !f.open( QIODevice::ReadOnly ) ) { qDebug() << "Failed to open " << headerTemplateFilePath; return false; } s = QTextStream( &f ).readAll(); } s.replace( "NEPOMUK_RESOURCECOMMENT", writeComment( comment, 0 ) ); s.replace( "NEPOMUK_RESOURCENAMEUPPER", name().toUpper() ); s.replace( "NEPOMUK_RESOURCENAME", name() ); s.replace( "NEPOMUK_PARENTRESOURCE", parent->name() ); // A resource that is not part of the currently generated stuff is supposed // to be installed in include/nepomuk if ( parent->generateClass() ) { s.replace( "NEPOMUK_PARENT_INCLUDE", QString("\"%1.h\"").arg( parent->name().toLower() ) ); } else { s.replace( "NEPOMUK_PARENT_INCLUDE", QString("").arg( parent->name().toLower() ) ); } QString methods; QTextStream ms( &methods ); QSet includes; QListIterator it( properties ); while( it.hasNext() ) { const Property* p = it.next(); if( p->type.isEmpty() ) { - qDebug() << "(ResourceClass::writeSource) type not defined for property: " << p->name() << endl; + if ( !quiet ) + qDebug() << "(ResourceClass::writeSource) type not defined for property: " << p->name() << endl; continue; } ms << writeComment( QString("Get property '%1'. ").arg(p->name()) + p->comment, 3*4 ) << endl; ms << " " << p->getterDeclaration( this ) << ";" << endl; ms << endl; ms << writeComment( QString("Set property '%1'. ").arg(p->name()) + p->comment, 3*4 ) << endl; ms << " " << p->setterDeclaration( this ) << ";" << endl; ms << endl; if( p->list ) { ms << writeComment( QString("Add a value to property '%1'. ").arg(p->name()) + p->comment, 3*4 ) << endl; ms << " " << p->adderDeclaration( this ) << ";" << endl; ms << endl; } ms << writeComment( QString( "\\return The URI of the property '%1'." ).arg( p->name() ), 3*4 ) << endl; ms << " " << "static QUrl " << p->name()[0].toLower() << p->name().mid(1) << "Uri();" << endl; ms << endl; if( !p->hasSimpleType() ) includes.insert( p->typeString( true ) ); } it = reverseProperties; while( it.hasNext() ) { const Property* p = it.next(); if( p->type.isEmpty() ) { - qDebug() << "(ResourceClass::writeSource) type not defined for property: " << p->name() << endl; + if ( !quiet ) + qDebug() << "(ResourceClass::writeSource) type not defined for property: " << p->name() << endl; continue; } if ( p->inverse ) { // we already define a reverse property. So leave the generated one out continue; } ms << writeComment( QString("Get all resources that have this resource set as property '%1'. ") .arg(p->name()) + p->comment + QString(" \\sa ResourceManager::allResourcesWithProperty"), 3*4 ) << endl; ms << " " << p->reversePropertyGetterDeclaration( this ) << ";" << endl; ms << endl; if( !p->hasSimpleType() ) includes.insert( p->domain->name() ); } // // Nepomuk does not support multiple inheritance // So we have to use a workaround instead // if( allParents.count() > 1 ) { foreach( ResourceClass* rc, allParents ) { // ignore the one we derived from if( rc != parent ) { ms << writeComment( QString("Nepomuk does not support multiple inheritance. Thus, to access " "properties from all parent classes helper methods like this are " "introduced. The object returned represents the exact same resource."), 3*4 ) << endl << " " << pseudoInheritanceDeclaration( rc, false ) << ";" << endl << endl; includes.insert( rc->name() ); } } } ms << writeComment( QString("Retrieve a list of all available %1 resources. " "This list consists of all resource of type %1 that are stored " "in the local Nepomuk meta data storage and any changes made locally. " "Be aware that in some cases this list can get very big. Then it might " "be better to use libKNep directly.").arg( name() ), 3*4 ) << endl; ms << " static " << allResourcesDeclaration( false ) << ";" << endl; QString includeString; QSetIterator includeIt( includes ); while( includeIt.hasNext() ) { includeString += " class " + includeIt.next() + ";\n"; } s.replace( "NEPOMUK_OTHERCLASSES", includeString ); s.replace( "NEPOMUK_METHODS", methods ); stream << s; return true; } bool ResourceClass::writeSource( QTextStream& stream ) const { QString s = sourceTemplate; if( QFile::exists( sourceTemplateFilePath ) ) { QFile f( sourceTemplateFilePath ); if( !f.open( QIODevice::ReadOnly ) ) { qDebug() << "Failed to open " << sourceTemplateFilePath; return false; } s = QTextStream( &f ).readAll(); } s.replace( "NEPOMUK_RESOURCENAMELOWER", name().toLower() ); s.replace( "NEPOMUK_RESOURCENAME", name() ); s.replace( "NEPOMUK_RESOURCETYPEURI", uri ); s.replace( "NEPOMUK_PARENTRESOURCE", parent->name() ); QString methods; QStringList includes; QTextStream ms( &methods ); QListIterator it( properties ); while( it.hasNext() ) { const Property* p = it.next(); if( p->type.isEmpty() ) { - qDebug() << "(ResourceClass::writeSource) type not defined for property: " << p->name() << endl; + if ( !quiet ) + qDebug() << "(ResourceClass::writeSource) type not defined for property: " << p->name() << endl; continue; } if ( !p->hasSimpleType() ) { includes.append( QString( "#include \"%1.h\"" ).arg( p->typeString( true, false ).toLower() ) ); } ms << p->getterDefinition( this ) << endl << p->setterDefinition( this ) << endl; if( p->list ) ms << p->adderDefinition( this ) << endl; // write the static method that returns the property's Uri ms << "QUrl " << name( true ) << "::" << p->name()[0].toLower() << p->name().mid(1) << "Uri()" << endl << "{" << endl << " return QUrl(\"" << p->uri << "\");" << endl << "}" << endl << endl; } it = reverseProperties; while( it.hasNext() ) { const Property* p = it.next(); if( p->type.isEmpty() ) { - qDebug() << "(ResourceClass::writeSource) type not defined for property: " << p->name() << endl; + if ( !quiet ) + qDebug() << "(ResourceClass::writeSource) type not defined for property: " << p->name() << endl; continue; } if ( p->inverse ) { // we already define a reverse property. So leave the generated one out continue; } ms << p->reversePropertyGetterDefinition( this ) << endl; includes.append( QString( "#include \"%1\"" ).arg( p->domain->headerName() ) ); } // // Nepomuk does not support multiple inheritance // So we have to use a workaround instead // if( allParents.count() > 1 ) { foreach( ResourceClass* rc, allParents ) { // ignore the one we derived from if( rc != parent ) { ms << pseudoInheritanceDefinition( rc ) << endl; includes.append( QString("#include \"%1.h\"").arg( rc->name().toLower() ) ); } } } ms << allResourcesDefinition() << endl; // HACK: remove duplicates and resource include includes = includes.toSet().toList(); includes.removeAll( "#include \"resource.h\"" ); s.replace( "NEPOMUK_METHODS", methods ); s.replace( "NEPOMUK_INCLUDES", includes.join( "\n" ) ); stream << s; return true; } bool ResourceClass::write( const QString& folder ) const { QFile f( folder + headerName() ); if( !f.open( QIODevice::WriteOnly ) ) return false; QTextStream s( &f ); if( !writeHeader( s ) ) return false; f.close(); f.setFileName( folder + sourceName() ); if( !f.open( QIODevice::WriteOnly ) ) return false; if( !writeSource( s ) ) return false; return true; } bool ResourceClass::generateClass() const { return generate; } diff --git a/nepomuk/rcgen/resourcetemplate.h b/nepomuk/rcgen/resourcetemplate.h index 6acf28f39e..89c1229328 100644 --- a/nepomuk/rcgen/resourcetemplate.h +++ b/nepomuk/rcgen/resourcetemplate.h @@ -1,163 +1,163 @@ /* * * $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. * See the file "COPYING.LIB" for the exact licensing terms. */ #ifndef _RESOURCE_TEMPLATE_H_ #define _RESOURCE_TEMPLATE_H_ static const QString gplTemplate = "/*\n" " *\n" " * $Id: $\n" " *\n" " * This file is part of the Nepomuk KDE project.\n" " * Copyright (C) 2007 Sebastian Trueg \n" " *\n" " * This library is free software; you can redistribute it and/or modify\n" " * it under the terms of the GNU Lesser General Public License as published by\n" " * the Free Software Foundation; either version 2 of the License, or\n" " * (at your option) any later version.\n" " * See the file \"COPYING\" for the exact licensing terms.\n" " */\n" "\n" "/*\n" " * This file has been generated by the Nepomuk Resource class generator.\n" " * DO NOT EDIT THIS FILE.\n" " * ANY CHANGES WILL BE LOST.\n" " */\n"; static const QString headerTemplate = gplTemplate + "\n" "#ifndef _NEPOMUK_RESOURCENAMEUPPER_H_\n" "#define _NEPOMUK_RESOURCENAMEUPPER_H_\n" "\n" "namespace Nepomuk {\n" "NEPOMUK_OTHERCLASSES" "}\n" "\n" "#include NEPOMUK_PARENT_INCLUDE\n" "#include \n" "\n" "namespace Nepomuk {\n" "\n" "NEPOMUK_RESOURCECOMMENT\n" " class NEPOMUK_EXPORT NEPOMUK_RESOURCENAME : public NEPOMUK_PARENTRESOURCE\n" " {\n" " public:\n" " /**\n" " * Create a new empty and invalid NEPOMUK_RESOURCENAME instance\n" " */\n" " NEPOMUK_RESOURCENAME();\n" " /**\n" " * Default copy constructor\n" " */\n" " NEPOMUK_RESOURCENAME( const NEPOMUK_RESOURCENAME& );\n" " NEPOMUK_RESOURCENAME( const Resource& );\n" " /**\n" " * Create a new NEPOMUK_RESOURCENAME instance representing the resource\n" " * referenced by \\a uriOrIdentifier.\n" " */\n" " NEPOMUK_RESOURCENAME( const QString& uriOrIdentifier );\n" " /**\n" " * Create a new NEPOMUK_RESOURCENAME instance representing the resource\n" " * referenced by \\a uri.\n" " */\n" " NEPOMUK_RESOURCENAME( const QUrl& uri );\n" " ~NEPOMUK_RESOURCENAME();\n" "\n" " NEPOMUK_RESOURCENAME& operator=( const NEPOMUK_RESOURCENAME& );\n" "\n" "NEPOMUK_METHODS\n" "\n" " /**\n" " * \\return The URI of the resource type that is used in NEPOMUK_RESOURCENAME instances.\n" " */\n" " static QString resourceTypeUri();\n" "\n" " protected:\n" " NEPOMUK_RESOURCENAME( const QString& uri, const QUrl& type );\n" " NEPOMUK_RESOURCENAME( const QUrl& uri, const QUrl& type );\n" " };\n" "}\n" "\n" "#endif\n"; static const QString sourceTemplate = gplTemplate + "\n" "#include \n" "#include \n" "#include \n" "#include \"NEPOMUK_RESOURCENAMELOWER.h\"\n" "\n" "NEPOMUK_INCLUDES" "\n" "Nepomuk::NEPOMUK_RESOURCENAME::NEPOMUK_RESOURCENAME()\n" -" : NEPOMUK_PARENTRESOURCE()\n" +" : NEPOMUK_PARENTRESOURCE( QUrl(), QUrl::fromEncoded(\"NEPOMUK_RESOURCETYPEURI\") )\n" "{\n" "}\n" "\n" "\n" "Nepomuk::NEPOMUK_RESOURCENAME::NEPOMUK_RESOURCENAME( const NEPOMUK_RESOURCENAME& res )\n" " : NEPOMUK_PARENTRESOURCE( res )\n" "{\n" "}\n" "\n" "\n" "Nepomuk::NEPOMUK_RESOURCENAME::NEPOMUK_RESOURCENAME( const Nepomuk::Resource& res )\n" " : NEPOMUK_PARENTRESOURCE( res )\n" "{\n" "}\n" "\n" "\n" "Nepomuk::NEPOMUK_RESOURCENAME::NEPOMUK_RESOURCENAME( const QString& uri )\n" " : NEPOMUK_PARENTRESOURCE( uri, QUrl::fromEncoded(\"NEPOMUK_RESOURCETYPEURI\") )\n" "{\n" "}\n" "\n" "Nepomuk::NEPOMUK_RESOURCENAME::NEPOMUK_RESOURCENAME( const QUrl& uri )\n" " : NEPOMUK_PARENTRESOURCE( uri, QUrl::fromEncoded(\"NEPOMUK_RESOURCETYPEURI\") )\n" "{\n" "}\n" "\n" "Nepomuk::NEPOMUK_RESOURCENAME::NEPOMUK_RESOURCENAME( const QString& uri, const QUrl& type )\n" " : NEPOMUK_PARENTRESOURCE( uri, type )\n" "{\n" "}\n" "\n" "Nepomuk::NEPOMUK_RESOURCENAME::NEPOMUK_RESOURCENAME( const QUrl& uri, const QUrl& type )\n" " : NEPOMUK_PARENTRESOURCE( uri, type )\n" "{\n" "}\n" "\n" "Nepomuk::NEPOMUK_RESOURCENAME::~NEPOMUK_RESOURCENAME()\n" "{\n" "}\n" "\n" "\n" "Nepomuk::NEPOMUK_RESOURCENAME& Nepomuk::NEPOMUK_RESOURCENAME::operator=( const NEPOMUK_RESOURCENAME& res )\n" "{\n" " Resource::operator=( res );\n" " return *this;\n" "}\n" "\n" "\n" "QString Nepomuk::NEPOMUK_RESOURCENAME::resourceTypeUri()\n" "{\n" " return \"NEPOMUK_RESOURCETYPEURI\";\n" "}\n" "\n" "NEPOMUK_METHODS\n"; #endif