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