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 }
00095 proc.setProgram( "kres-migrator", args );
00096 proc.start();
00097 bool result = proc.waitForStarted();
00098 if ( result ) {
00099 result = proc.waitForFinished();
00100 }
00101 if ( result && proc.exitCode() == 0 ) {
00102 kDebug() << "Akonadi migration has been successful";
00103 migrationCfg.writeEntry( "Version-" + resourceFamily, targetVersion );
00104 migrationCfg.sync();
00105 } else if ( !result || proc.exitCode() != 1 ) {
00106
00107 kError() << "Akonadi migration failed!";
00108 kError() << "command was: " << proc.program();
00109 kError() << "exit code: " << proc.exitCode();
00110 kError() << "stdout: " << proc.readAllStandardOutput();
00111 kError() << "stderr: " << proc.readAllStandardError();
00112 }
00113 }
00114
00115 }
00116
00117 return factory;
00118 }
00119
00120 Factory::Factory( const QString &resourceFamily ) :
00121 d( new KRES::Factory::Private )
00122 {
00123 d->mResourceFamily = resourceFamily;
00124 reloadConfig();
00125 }
00126
00127 void Factory::reloadConfig()
00128 {
00129 d->mTypeMap.clear();
00130 const KService::List plugins =
00131 KServiceTypeTrader::self()->query(
00132 "KResources/Plugin",
00133 QString( "[X-KDE-ResourceFamily] == '%1'" ).arg( d->mResourceFamily ) );
00134
00135 KService::List::ConstIterator it;
00136 for ( it = plugins.begin(); it != plugins.end(); ++it ) {
00137 const QVariant type = (*it)->property( "X-KDE-ResourceType" );
00138 if ( !type.toString().isEmpty() ) {
00139 d->mTypeMap.insert( type.toString(), *it );
00140 }
00141 }
00142 }
00143
00144 Factory::~Factory()
00145 {
00146 delete d;
00147 }
00148
00149 QStringList Factory::typeNames() const
00150 {
00151 return d->mTypeMap.keys();
00152 }
00153
00154 ConfigWidget *Factory::configWidget( const QString &type, QWidget *parent )
00155 {
00156 if ( type.isEmpty() || !d->mTypeMap.contains( type ) ) {
00157 return 0;
00158 }
00159
00160 KService::Ptr ptr = d->mTypeMap[ type ];
00161 KPluginLoader loader( ptr->library() );
00162 KPluginFactory *factory = loader.factory();
00163 if ( !factory ) {
00164 kDebug() << "Factory creation failed: " << loader.errorString();
00165 return 0;
00166 }
00167
00168 PluginFactoryBase *pluginFactory = static_cast<PluginFactoryBase *>( factory );
00169
00170 if ( !pluginFactory ) {
00171 kDebug() << "no plugin factory.";
00172 return 0;
00173 }
00174
00175 ConfigWidget *wdg = pluginFactory->configWidget( parent );
00176 if ( !wdg ) {
00177 kDebug() << "'" << ptr->library() << "' doesn't provide a ConfigWidget";
00178 return 0;
00179 }
00180
00181 return wdg;
00182 }
00183
00184 QString Factory::typeName( const QString &type ) const
00185 {
00186 if ( type.isEmpty() || !d->mTypeMap.contains( type ) ) {
00187 return QString();
00188 }
00189
00190 KService::Ptr ptr = d->mTypeMap[ type ];
00191 return ptr->name();
00192 }
00193
00194 QString Factory::typeDescription( const QString &type ) const
00195 {
00196 if ( type.isEmpty() || !d->mTypeMap.contains( type ) ) {
00197 return QString();
00198 }
00199
00200 KService::Ptr ptr = d->mTypeMap[ type ];
00201 return ptr->comment();
00202 }
00203
00204 Resource *Factory::Private::resourceInternal( const QString &type, const KConfigGroup *group )
00205 {
00206 kDebug() << "(" << type << ", config )";
00207
00208 if ( type.isEmpty() || !mTypeMap.contains( type ) ) {
00209 kDebug() << "no such type" << type;
00210 return 0;
00211 }
00212
00213 KService::Ptr ptr = mTypeMap[ type ];
00214 KPluginLoader loader( ptr->library() );
00215 KPluginFactory *factory = loader.factory();
00216 if ( !factory ) {
00217 kDebug() << "Factory creation failed" << loader.errorString();
00218 return 0;
00219 }
00220
00221 PluginFactoryBase *pluginFactory = static_cast<PluginFactoryBase *>( factory );
00222
00223 if ( !pluginFactory ) {
00224 kDebug() << "no plugin factory.";
00225 return 0;
00226 }
00227
00228 Resource *resource;
00229 if ( group ) {
00230 resource = pluginFactory->resource( *group );
00231 } else {
00232 resource = pluginFactory->resource();
00233 }
00234
00235 if ( !resource ) {
00236 kDebug() << "'" << ptr->library()
00237 << "' is not a" << mResourceFamily << "plugin.";
00238 return 0;
00239 }
00240
00241 resource->setType( type );
00242
00243 return resource;
00244 }
00245
00246 Resource *Factory::resource( const QString &type, const KConfigGroup &group )
00247 {
00248 return d->resourceInternal( type, &group );
00249 }
00250
00251 Resource *Factory::resource( const QString &type )
00252 {
00253 return d->resourceInternal( type, 0 );
00254 }