• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Nepomuk-Core

  • sources
  • kde-4.12
  • kdelibs
  • nepomuk-core
  • rcgen
codegenerator.cpp
Go to the documentation of this file.
1 /*
2  *
3  * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $
4  *
5  * This file is part of the Nepomuk KDE project.
6  * Copyright (C) 2006-2009 Sebastian Trueg <trueg@kde.org>
7  *
8  * This library is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  * See the file "COPYING.LIB" for the exact licensing terms.
13  */
14 
15 #include "codegenerator.h"
16 
17 #include "abstractcode.h"
18 #include "property.h"
19 #include "resourceclass.h"
20 #include "safecode.h"
21 
22 #include <QtCore/QFile>
23 #include <QtCore/QTextStream>
24 #include <QtCore/QRegExp>
25 #include <QtCore/QDebug>
26 #include <QtCore/QUrl>
27 #include <QtCore/QStringList>
28 #include <QtCore/QDir>
29 
30 
31 extern bool quiet;
32 
33 static QString headerTemplate( CodeGenerator::Mode mode )
34 {
35  QFile gplFile( ":gpl.tpl" );
36  gplFile.open( QIODevice::ReadOnly );
37 
38  QFile headerFile( QString::fromLatin1( ":header_%1.tpl" )
39  .arg( mode == CodeGenerator::SafeMode ? QLatin1String( "safe" ) : QLatin1String( "fast" ) ) );
40  headerFile.open( QIODevice::ReadOnly );
41 
42  QString result = QString::fromLatin1( gplFile.readAll() );
43  result += QString::fromLatin1( headerFile.readAll() );
44 
45  return result;
46 }
47 
48 static QString sourceTemplate( CodeGenerator::Mode mode )
49 {
50  QFile gplFile( ":gpl.tpl" );
51  gplFile.open( QIODevice::ReadOnly );
52 
53  QFile sourceFile( QString::fromLatin1( ":source_%1.tpl" )
54  .arg( mode == CodeGenerator::SafeMode ? QLatin1String( "safe" ) : QLatin1String( "fast" ) ) );
55  sourceFile.open( QIODevice::ReadOnly );
56 
57  QString result = QString::fromLatin1( gplFile.readAll() );
58  result += QString::fromLatin1( sourceFile.readAll() );
59 
60  return result;
61 }
62 
63 static QString writeComment( const QString& comment, int indent )
64 {
65  static const int maxLine = 50;
66 
67  QString s;
68 
69  if( !comment.isEmpty() ) {
70  s += QString().fill( ' ', indent );
71  s += "/**\n"
72  + QString().fill( ' ', indent+1 )
73  + "* ";
74 
75  QStringList words = comment.split( QRegExp("\\s"), QString::SkipEmptyParts );
76  int cnt = 0;
77  for( int i = 0; i < words.count(); ++i ) {
78  if( cnt >= maxLine ) {
79  s += '\n'
80  + QString().fill( ' ', indent+1 )
81  + "* ";
82  cnt = 0;
83  }
84 
85  s += words[i] + ' ';
86  cnt += words[i].length();
87  }
88 
89  if( cnt > 0 )
90  s += '\n';
91  s += QString().fill( ' ', indent+1 )
92  + "*/";
93  }
94 
95  return s;
96 }
97 
98 CodeGenerator::CodeGenerator( Mode mode, const QList<ResourceClass*>& classes )
99  : m_mode( mode ),
100  m_classes( classes )
101 {
102  if ( m_mode == SafeMode ) {
103  m_code = new SafeCode;
104  m_nameSpace = QLatin1String("Nepomuk2");
105  }
106 }
107 
108 CodeGenerator::~CodeGenerator()
109 {
110  delete m_code;
111 }
112 
113 bool CodeGenerator::write( const ResourceClass* resourceClass, const QString& folder ) const
114 {
115  QFile f( folder + resourceClass->headerName() );
116  if( !f.open( QIODevice::WriteOnly ) )
117  return false;
118 
119  QTextStream s( &f );
120  if( !writeHeader( resourceClass, s ) )
121  return false;
122 
123  f.close();
124 
125  f.setFileName( folder + resourceClass->sourceName() );
126  if( !f.open( QIODevice::WriteOnly ) )
127  return false;
128 
129  if( !writeSource( resourceClass, s ) )
130  return false;
131 
132  return true;
133 }
134 
135 bool CodeGenerator::writeDummyClasses( const QString &folder ) const
136 {
137  //FIXME: What do we do over here?
138  return true;
139 }
140 
141 bool CodeGenerator::writeHeader( const ResourceClass *resourceClass, QTextStream& stream ) const
142 {
143  QString s = headerTemplate( m_mode );
144  ResourceClass* parent = resourceClass->parentClass( true );
145  s.replace( "NEPOMUK_VISIBILITY_HEADER_INCLUDE", visibilityHeader() );
146  s.replace( "NEPOMUK_VISIBILITY", visibilityExportMacro() );
147  s.replace( "NEPOMUK_RESOURCECOMMENT", writeComment( resourceClass->comment(), 4 ) );
148  s.replace( "NEPOMUK_RESOURCENAMEUPPER", resourceClass->name().toUpper() );
149  s.replace( "NEPOMUK_RESOURCENAME", resourceClass->name() );
150  s.replace( "NEPOMUK_PARENTRESOURCE", parent->name() );
151 
152  // A resource that is not part of the currently generated stuff is supposed
153  // to be installed in include/nepomuk
154  if ( parent->generateClass() ) {
155  s.replace( "NEPOMUK_PARENT_INCLUDE", QString("\"%1.h\"").arg( parent->name().toLower() ) );
156  }
157  else {
158  s.replace( "NEPOMUK_PARENT_INCLUDE", QString("<Nepomuk2/Resource>") );
159  }
160 
161  QString methods;
162  QTextStream ms( &methods );
163  QSet<QString> includes;
164 
165  QListIterator<const Property*> it( resourceClass->allProperties() );
166  while( it.hasNext() ) {
167  const Property* p = it.next();
168 
169  if( p->literalRange().isEmpty() &&
170  !p->range() ) {
171  if ( !quiet )
172  qDebug() << "(CodeGenerator::writeSource) type not defined for property: " << p->name() << endl;
173  continue;
174  }
175 
176  if ( m_mode == SafeMode ) {
177  ms << writeComment( QString("Get property '%1'. ").arg(p->name()) + p->comment(), 2*4 ) << endl;
178  ms << " " << m_code->propertyGetterDeclaration( p, resourceClass ) << ";" << endl;
179  ms << endl;
180  }
181 
182  ms << writeComment( QString("Set property '%1'. ").arg(p->name()) + p->comment(), 2*4 ) << endl;
183  ms << " " << m_code->propertySetterDeclaration( p, resourceClass ) << ";" << endl;
184  ms << endl;
185 
186  if( p->isList() ) {
187  ms << writeComment( QString("Add a value to property '%1'. ").arg(p->name()) + p->comment(), 2*4 ) << endl;
188  ms << " " << m_code->propertyAdderDeclaration( p, resourceClass ) << ";" << endl;
189  ms << endl;
190  }
191 
192  ms << writeComment( QString( "\\return The URI of the property '%1'." ).arg( p->name() ), 2*4 ) << endl;
193  ms << " " << "static QUrl " << p->name()[0].toLower() << p->name().mid(1) << "Uri();" << endl;
194  ms << endl;
195 
196  if( !p->hasSimpleType() )
197  includes.insert( p->typeString( true ) );
198  }
199 
200 
201  it = resourceClass->allReverseProperties();
202  while( it.hasNext() ) {
203  const Property* p = it.next();
204 
205  if( p->literalRange().isEmpty() &&
206  !p->range() ) {
207  if ( !quiet )
208  qDebug() << "(CodeGenerator::writeSource) type not defined for property: " << p->name() << endl;
209  continue;
210  }
211 
212  if ( p->inverseProperty() ) {
213  // we already define a reverse property. So leave the generated one out
214  continue;
215  }
216 
217  if ( m_mode == SafeMode ) {
218  ms << writeComment( QString("Get all resources that have this resource set as property '%1'. ")
219  .arg(p->name()) + p->comment() + QString(" \\sa ResourceManager::allResourcesWithProperty"), 2*4 ) << endl;
220  ms << " " << m_code->propertyReversePropertyGetterDeclaration( p, resourceClass ) << ";" << endl;
221  ms << endl;
222  }
223 
224  if( !p->hasSimpleType() )
225  includes.insert( p->domain(true)->name() );
226  }
227 
228 
229  //
230  // Nepomuk does not support multiple inheritance
231  // So we have to use a workaround instead (we even include the one class used as "proper" superclass
232  // since the order of the super classes is not deterministic and may change with a different serialization)
233  //
234  if( resourceClass->allParentResources().count() > 1 ) {
235  foreach( ResourceClass* rc, resourceClass->allParentResources() ) {
236  // ignore the one we derived from
237  if( rc->generateClass() ) {
238  const QString decl = m_code->resourcePseudoInheritanceDeclaration( resourceClass, rc );
239  if ( decl.isEmpty() )
240  continue;
241  ms << writeComment( QString("Nepomuk does not support multiple inheritance. Thus, to access "
242  "properties from all parent classes helper methods like this are "
243  "introduced. The object returned represents the exact same resource."), 2*4 ) << endl
244  << " " << decl << ";" << endl << endl;
245 
246  includes.insert( rc->name() );
247  }
248  }
249  }
250 
251  //FIXME: this depends from removed (and inefficient) code
252  //if ( m_mode == SafeMode ) {
253  // ms << writeComment( QString("Retrieve a list of all available %1 resources. "
254  // "This list consists of all resource of type %1 that are stored "
255  // "in the local Nepomuk meta data storage and any changes made locally. "
256  // "Be aware that in some cases this list can get very big. Then it might "
257  // "be better to use libKNep directly.").arg( resourceClass->name() ), 2*4 ) << endl;
258  // ms << " static " << m_code->resourceAllResourcesDeclaration( resourceClass ) << ";" << endl;
259  //}
260 
261  QString includeString;
262  QSetIterator<QString> includeIt( includes );
263  while( includeIt.hasNext() ) {
264  includeString += " class " + includeIt.next() + ";\n";
265  }
266 
267  s.replace( "NEPOMUK_OTHERCLASSES", includeString );
268  s.replace( "NEPOMUK_METHODS", methods );
269 
270  stream << s;
271 
272  return true;
273 }
274 
275 bool CodeGenerator::writeSource( const ResourceClass* resourceClass, QTextStream& stream ) const
276 {
277  QString s = sourceTemplate( m_mode );
278  s.replace( "NEPOMUK_RESOURCENAMELOWER", resourceClass->name().toLower() );
279  s.replace( "NEPOMUK_RESOURCENAME", resourceClass->name() );
280  s.replace( "NEPOMUK_RESOURCETYPEURI", resourceClass->uri().toString() );
281  s.replace( "NEPOMUK_PARENTRESOURCE", resourceClass->parentClass()->name() );
282 
283  QString methods;
284  QStringList includes;
285  QTextStream ms( &methods );
286 
287  QListIterator<const Property*> it( resourceClass->allProperties() );
288  while( it.hasNext() ) {
289  const Property* p = it.next();
290 
291  if( p->literalRange().isEmpty() &&
292  !p->range() ) {
293  if ( !quiet )
294  qDebug() << "(CodeGenerator::writeSource) type not defined for property: " << p->name() << endl;
295  continue;
296  }
297 
298  if ( !p->hasSimpleType() ) {
299  includes.append( QString( "#include \"%1.h\"" ).arg( p->typeString( true ).toLower() ) );
300  }
301 
302  if ( m_mode == SafeMode )
303  ms << m_code->propertyGetterDefinition( p, resourceClass ) << endl;
304 
305  ms << m_code->propertySetterDefinition( p, resourceClass ) << endl;
306  if( p->isList() )
307  ms << m_code->propertyAdderDefinition( p, resourceClass ) << endl;
308 
309  // write the static method that returns the property's Uri
310  ms << "QUrl " << resourceClass->name( m_nameSpace ) << "::" << p->name()[0].toLower() << p->name().mid(1) << "Uri()" << endl
311  << "{" << endl
312  << " return QUrl::fromEncoded(\"" << p->uri().toString() << "\");" << endl
313  << "}" << endl << endl;
314  }
315 
316  it = resourceClass->allReverseProperties();
317  while( it.hasNext() ) {
318  const Property* p = it.next();
319 
320  if( p->literalRange().isEmpty() &&
321  !p->range() ) {
322  if ( !quiet )
323  qDebug() << "(CodeGenerator::writeSource) type not defined for property: " << p->name() << endl;
324  continue;
325  }
326 
327  if ( p->inverseProperty() ) {
328  // we already define a reverse property. So leave the generated one out
329  continue;
330  }
331 
332  //FIXME: this depends from removed (and inefficient) code
333  /*if ( m_mode == SafeMode )
334  ms << m_code->propertyReversePropertyGetterDefinition( p, resourceClass ) << endl;*/
335 
336  includes.append( QString( "#include \"%1\"" ).arg( p->domain(true)->headerName() ) );
337  }
338 
339  //
340  // Nepomuk does not support multiple inheritance
341  // So we have to use a workaround instead (we even include the one class used as "proper" superclass
342  // since the order of the super classes is not deterministic and may change with a different serialization)
343  //
344  if( resourceClass->allParentResources().count() > 1 ) {
345  foreach( ResourceClass* rc, resourceClass->allParentResources() ) {
346  // ignore the one we derived from
347  if( rc->generateClass() ) {
348  ms << m_code->resourcePseudoInheritanceDefinition( resourceClass, rc ) << endl;
349  includes.append( QString("#include \"%1.h\"").arg( rc->name().toLower() ) );
350  }
351  }
352  }
353 
354  //FIXME: this depends from removed (and inefficient) code
355  /*if ( m_mode == SafeMode )
356  ms << m_code->resourceAllResourcesDefinition( resourceClass ) << endl;*/
357 
358  // HACK: remove duplicates and resource include
359  includes = includes.toSet().toList();
360  includes.removeAll( "#include \"resource.h\"" );
361 
362  s.replace( "NEPOMUK_METHODS", methods );
363  s.replace( "NEPOMUK_INCLUDES", includes.join( "\n" ) );
364 
365  stream << s;
366 
367  return true;
368 }
369 
370 
371 bool CodeGenerator::writeSources( const QString& dir )
372 {
373  bool success = true;
374 
375  foreach( ResourceClass* rc, classes() ) {
376  if( rc->generateClass() )
377  success &= write( rc, dir + QDir::separator() );
378  }
379 
380  writeDummyClasses( dir + QDir::separator() );
381 
382  return success;
383 }
384 
385 
386 QStringList CodeGenerator::listHeader()
387 {
388  QStringList l;
389  foreach( ResourceClass* rc, classes() ) {
390  if( rc->generateClass() )
391  l.append( rc->headerName() );
392  }
393  return l;
394 }
395 
396 
397 QStringList CodeGenerator::listSources()
398 {
399  QStringList l;
400  foreach( ResourceClass* rc, classes() ) {
401  if( rc->generateClass() )
402  l.append( rc->sourceName() );
403  }
404  return l;
405 }
406 
407 
408 QString CodeGenerator::visibilityHeader() const
409 {
410  if( m_visibility.isEmpty() )
411  return QString();
412  else
413  return "#include \"" + m_visibility.toLower() + "_export.h\"";
414 }
415 
416 
417 QString CodeGenerator::visibilityExportMacro() const
418 {
419  if( m_visibility.isEmpty() )
420  return QString();
421  else
422  return m_visibility.toUpper() + "_EXPORT";
423 }
resourceclass.h
Property::isList
bool isList() const
Returns whether the property is a list of values.
Definition: rcgen/property.cpp:88
Property::comment
QString comment() const
Returns the comment of the property.
Definition: rcgen/property.cpp:78
Property::range
ResourceClass * range() const
Returns the scope of the property.
Definition: rcgen/property.cpp:63
AbstractCode::propertyAdderDefinition
virtual QString propertyAdderDefinition(const Property *property, const ResourceClass *resourceClass) const =0
Returns the definition of the property adder method.
Property::literalRange
QString literalRange() const
Returns the literal range of the property (the name of the Qt type to be used.)
Definition: rcgen/property.cpp:68
Property::uri
QUrl uri() const
Returns the uri of the property.
Definition: rcgen/property.cpp:48
ResourceClass::uri
QUrl uri() const
Returns the uri of the resource.
Definition: resourceclass.cpp:43
SafeCode
Specific code implementation with full checks.
Definition: safecode.h:27
ResourceClass::generateClass
bool generateClass() const
Returns true if this class should be generated.
Definition: resourceclass.cpp:117
ResourceClass::parentClass
ResourceClass * parentClass(bool considerGenerateClass=true) const
Returns the parent resource of the resource.
Definition: resourceclass.cpp:63
sourceTemplate
static QString sourceTemplate(CodeGenerator::Mode mode)
Definition: codegenerator.cpp:48
CodeGenerator::listHeader
QStringList listHeader()
Definition: codegenerator.cpp:386
ResourceClass::allProperties
Property::ConstPtrList allProperties() const
Returns the list of all properties of the resource.
Definition: resourceclass.cpp:97
AbstractCode::resourcePseudoInheritanceDeclaration
virtual QString resourcePseudoInheritanceDeclaration(const ResourceClass *resourceBaseClass, const ResourceClass *resourceClass, const QString &nameSpace=QString()) const =0
Returns the declaration of the resource method that provides pseudo inheritance.
codegenerator.h
CodeGenerator::Mode
Mode
Definition: codegenerator.h:29
ResourceClass
Represents a resource.
Definition: resourceclass.h:30
Property::hasSimpleType
bool hasSimpleType() const
Returns whether the property is of simple type.
Definition: rcgen/property.cpp:159
AbstractCode::propertyAdderDeclaration
virtual QString propertyAdderDeclaration(const Property *property, const ResourceClass *resourceClass, const QString &nameSpace=QString()) const =0
Returns the declaration of the property adder method.
CodeGenerator::writeSources
bool writeSources(const QString &dir)
Definition: codegenerator.cpp:371
AbstractCode::propertyGetterDefinition
virtual QString propertyGetterDefinition(const Property *property, const ResourceClass *resourceClass) const =0
Returns the definition of the property getter method.
ResourceClass::comment
QString comment() const
Returns the comment of the resource.
Definition: resourceclass.cpp:53
abstractcode.h
headerTemplate
static QString headerTemplate(CodeGenerator::Mode mode)
Definition: codegenerator.cpp:33
CodeGenerator::classes
QList< ResourceClass * > classes() const
Definition: codegenerator.h:38
ResourceClass::allReverseProperties
Property::ConstPtrList allReverseProperties() const
Returns the list of all reverse properties of the resource.
Definition: resourceclass.cpp:107
ResourceClass::sourceName
QString sourceName() const
Returns the name of the source file for this resource.
Definition: resourceclass.cpp:135
AbstractCode::propertyReversePropertyGetterDeclaration
virtual QString propertyReversePropertyGetterDeclaration(const Property *property, const ResourceClass *resourceClass, const QString &nameSpace=QString()) const =0
Returns the declaration of the property for the reverse property getter method.
writeComment
static QString writeComment(const QString &comment, int indent)
Definition: codegenerator.cpp:63
Property::domain
ResourceClass * domain(bool onlyReturnGeneratedClass=false) const
Returns the domain resource the property belongs to.
Definition: rcgen/property.cpp:98
Property
Represents the property of a resource.
Definition: rcgen/property.h:29
ResourceClass::name
QString name(const QString &nameSpace=QString()) const
Returns the name of the resource.
Definition: resourceclass.cpp:122
CodeGenerator::~CodeGenerator
~CodeGenerator()
Definition: codegenerator.cpp:108
AbstractCode::propertySetterDefinition
virtual QString propertySetterDefinition(const Property *property, const ResourceClass *resourceClass) const =0
Returns the definition of the property setter method.
quiet
bool quiet
Definition: rcgen.cpp:29
CodeGenerator::CodeGenerator
CodeGenerator(Mode mode, const QList< ResourceClass * > &classes)
Definition: codegenerator.cpp:98
ResourceClass::headerName
QString headerName() const
Returns the name of the header file for this resource.
Definition: resourceclass.cpp:130
CodeGenerator::listSources
QStringList listSources()
Definition: codegenerator.cpp:397
Property::inverseProperty
Property * inverseProperty() const
Returns the inverse property of this property.
Definition: rcgen/property.cpp:114
property.h
Property::typeString
QString typeString(bool simple=false, const QString &nameSpace=QString()) const
Retrieve a string representation of the range.
Definition: rcgen/property.cpp:132
AbstractCode::propertyGetterDeclaration
virtual QString propertyGetterDeclaration(const Property *property, const ResourceClass *resourceClass, const QString &nameSpace=QString()) const =0
Returns the declaration of the property getter method.
CodeGenerator::SafeMode
Definition: codegenerator.h:30
AbstractCode::propertySetterDeclaration
virtual QString propertySetterDeclaration(const Property *property, const ResourceClass *resourceClass, const QString &nameSpace=QString()) const =0
Returns the declaration of the property setter method.
safecode.h
ResourceClass::allParentResources
QList< ResourceClass * > allParentResources() const
Returns all parent resource of the resource.
Definition: resourceclass.cpp:87
AbstractCode::resourcePseudoInheritanceDefinition
virtual QString resourcePseudoInheritanceDefinition(const ResourceClass *resourceBaseClass, const ResourceClass *resourceClass) const =0
Returns the definition of the resource method that provides pseudo inheritance.
Property::name
QString name() const
Returns the name of the property.
Definition: rcgen/property.cpp:119
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:08 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Nepomuk-Core

Skip menu "Nepomuk-Core"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal