factory.cppGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00036 #include "factory.h"
00037
00038 #include <QtCore/QFile>
00039
00040 #include <kdebug.h>
00041 #include <klocale.h>
00042 #include <kconfig.h>
00043 #include <kconfiggroup.h>
00044 #include <kprocess.h>
00045 #include <kservicetypetrader.h>
00046 #include <kpluginloader.h>
00047
00048 #include "resource.h"
00049
00050 using namespace KRES;
00051
00052 class Factory::Private
00053 {
00054 public:
00055 Resource *resourceInternal ( const QString &type, const KConfigGroup *group );
00056 QString mResourceFamily;
00057 QMap<QString, KService::Ptr> mTypeMap;
00058 };
00059
00060 class FactoryMap : public QMap<QString, Factory*>
00061 {
00062 public:
00063 ~FactoryMap() { qDeleteAll(*this); }
00064 };
00065
00066 K_GLOBAL_STATIC( FactoryMap, mSelves )
00067
00068 Factory *Factory::self( const QString &resourceFamily )
00069 {
00070 kDebug();
00071
00072 Factory *factory = 0;
00073
00074 factory = mSelves->value( resourceFamily, 0 );
00075
00076 if ( !factory ) {
00077 factory = new Factory( resourceFamily );
00078 mSelves->insert( resourceFamily, factory );
00079
00080
00081 KConfig config( "kres-migratorrc" );
00082 KConfigGroup migrationCfg( &config, "Migration" );
00083 const bool enabled = migrationCfg.readEntry( "Enabled", false );
00084 const bool setupClientBrige = migrationCfg.readEntry( "SetupClientBridge", true );
00085 const int currentVersion = migrationCfg.readEntry( "Version-" + resourceFamily, 0 );
00086 const int targetVersion = migrationCfg.readEntry( "TargetVersion", 0 );
00087 if ( enabled && currentVersion < targetVersion ) {
00088 kDebug() << "Performing Akonadi migration. Good luck!";
00089 KProcess proc;
00090 QStringList args = QStringList() << "--interactive-on-change" << "--type" << resourceFamily;
00091 if ( !setupClientBrige ) {
00092 args << "--omit-client-bridge";
00093 }
00094 proc.setProgram( "kres-migrator", args );
00095 proc.start();
00096 bool result = proc.waitForStarted();
00097 if ( result ) {
00098 result = proc.waitForFinished();
00099 }
00100 if ( result && proc.exitCode() == 0 ) {
00101 kDebug() << "Akonadi migration has been successful";
00102 migrationCfg.writeEntry( "Version-" + resourceFamily, targetVersion );
00103 migrationCfg.sync();
00104 } else if ( !result || proc.exitCode() != 1 ) {
00105
00106 kError() << "Akonadi migration failed!";
00107 kError() << "command was: " << proc.program();
00108 kError() << "exit code: " << proc.exitCode();
00109 kError() << "stdout: " << proc.readAllStandardOutput();
00110 kError() << "stderr: " << proc.readAllStandardError();
00111 }
00112 }
00113
00114 }
00115
00116 return factory;
00117 }
00118
00119 Factory::Factory( const QString &resourceFamily ) :
00120 d( new KRES::Factory::Private )
00121 {
00122 d->mResourceFamily = resourceFamily;
00123 reloadConfig();
00124 }
00125
00126 void Factory::reloadConfig()
00127 {
00128 d->mTypeMap.clear();
00129 const KService::List plugins =
00130 KServiceTypeTrader::self()->query(
00131 "KResources/Plugin",
00132 QString( "[X-KDE-ResourceFamily] == '%1'" ).arg( d->mResourceFamily ) );
00133
00134 KService::List::ConstIterator it;
00135 for ( it = plugins.begin(); it != plugins.end(); ++it ) {
00136 const QVariant type = (*it)->property( "X-KDE-ResourceType" );
00137 if ( !type.toString().isEmpty() ) {
00138 d->mTypeMap.insert( type.toString(), *it );
00139 }
00140 }
00141 }
00142
00143 Factory::~Factory()
00144 {
00145 delete d;
00146 }
00147
00148 QStringList Factory::typeNames() const
00149 {
00150 return d->mTypeMap.keys();
00151 }
00152
00153 ConfigWidget *Factory::configWidget( const QString &type, QWidget *parent )
00154 {
00155 if ( type.isEmpty() || !d->mTypeMap.contains( type ) ) {
00156 return 0;
00157 }
00158
00159 KService::Ptr ptr = d->mTypeMap[ type ];
00160 KPluginLoader loader( ptr->library() );
00161 KPluginFactory *factory = loader.factory();
00162 if ( !factory ) {
00163 kDebug() << "Factory creation failed: " << loader.errorString();
00164 return 0;
00165 }
00166
00167 PluginFactoryBase *pluginFactory = static_cast<PluginFactoryBase *>( factory );
00168
00169 if ( !pluginFactory ) {
00170 kDebug() << "no plugin factory.";
00171 return 0;
00172 }
00173
00174 ConfigWidget *wdg = pluginFactory->configWidget( parent );
00175 if ( !wdg ) {
00176 kDebug() << "'" << ptr->library() << "' doesn't provide a ConfigWidget";
00177 return 0;
00178 }
00179
00180 return wdg;
00181 }
00182
00183 QString Factory::typeName( const QString &type ) const
00184 {
00185 if ( type.isEmpty() || !d->mTypeMap.contains( type ) ) {
00186 return QString();
00187 }
00188
00189 KService::Ptr ptr = d->mTypeMap[ type ];
00190 return ptr->name();
00191 }
00192
00193 QString Factory::typeDescription( const QString &type ) const
00194 {
00195 if ( type.isEmpty() || !d->mTypeMap.contains( type ) ) {
00196 return QString();
00197 }
00198
00199 KService::Ptr ptr = d->mTypeMap[ type ];
00200 return ptr->comment();
00201 }
00202
00203 Resource *Factory::Private::resourceInternal( const QString &type, const KConfigGroup *group )
00204 {
00205 kDebug() << "(" << type << ", config )";
00206
00207 if ( type.isEmpty() || !mTypeMap.contains( type ) ) {
00208 kDebug() << "no such type" << type;
00209 return 0;
00210 }
00211
00212 KService::Ptr ptr = mTypeMap[ type ];
00213 KPluginLoader loader( ptr->library() );
00214 KPluginFactory *factory = loader.factory();
00215 if ( !factory ) {
00216 kDebug() << "Factory creation failed" << loader.errorString();
00217 return 0;
00218 }
00219
00220 PluginFactoryBase *pluginFactory = static_cast<PluginFactoryBase *>( factory );
00221
00222 if ( !pluginFactory ) {
00223 kDebug() << "no plugin factory.";
00224 return 0;
00225 }
00226
00227 Resource *resource;
00228 if ( group ) {
00229 resource = pluginFactory->resource( *group );
00230 } else {
00231 resource = pluginFactory->resource();
00232 }
00233
00234 if ( !resource ) {
00235 kDebug() << "'" << ptr->library()
00236 << "' is not a" << mResourceFamily << "plugin.";
00237 return 0;
00238 }
00239
00240 resource->setType( type );
00241
00242 return resource;
00243 }
00244
00245 Resource *Factory::resource( const QString &type, const KConfigGroup &group )
00246 {
00247 return d->resourceInternal( type, &group );
00248 }
00249
00250 Resource *Factory::resource( const QString &type )
00251 {
00252 return d->resourceInternal( type, 0 );
00253 }
|