kresources
factory.cpp
Go 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
00064 ~FactoryMap() { qDeleteAll(*this); }
00065 };
00066
00067 K_GLOBAL_STATIC( FactoryMap, mSelves )
00068
00069 Factory *Factory::self( const QString &resourceFamily )
00070 {
00071 kDebug();
00072
00073 Factory *factory = 0;
00074
00075 factory = mSelves->value( resourceFamily, 0 );
00076
00077 if ( !factory ) {
00078 factory = new Factory( resourceFamily );
00079 mSelves->insert( resourceFamily, factory );
00080
00081
00082 KConfig config( "kres-migratorrc" );
00083 KConfigGroup migrationCfg( &config, "Migration" );
00084 const bool enabled = migrationCfg.readEntry( "Enabled", false );
00085 const bool setupClientBrige = migrationCfg.readEntry( "SetupClientBridge", true );
00086 const int currentVersion = migrationCfg.readEntry( "Version-" + resourceFamily, 0 );
00087 const int targetVersion = migrationCfg.readEntry( "TargetVersion", 0 );
00088 if ( enabled && currentVersion < targetVersion ) {
00089 kDebug() << "Performing Akonadi migration. Good luck!";
00090 KProcess proc;
00091 QStringList args = QStringList() << "--interactive-on-change" << "--type" << resourceFamily;
00092 if ( !setupClientBrige )
00093 args << "--omit-client-bridge";
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 }