00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "pluginloader_p.h"
00021
00022 #include <kconfiggroup.h>
00023 #include <kdebug.h>
00024 #include <kglobal.h>
00025 #include <klocale.h>
00026 #include <kstandarddirs.h>
00027 #include <KPluginLoader>
00028
00029 #include <QtCore/QDebug>
00030
00031 #ifdef _WIN32_WCE
00032 #include <QMessageBox>
00033 #endif
00034
00035 using namespace Akonadi;
00036
00037 PluginMetaData::PluginMetaData()
00038 {
00039 }
00040
00041 PluginMetaData::PluginMetaData( const QString & lib, const QString & name, const QString & comment, const QString & cname )
00042 : library( lib ), nameLabel( name ),
00043 descriptionLabel( comment ),
00044 className(cname), loaded( false )
00045 {
00046 }
00047
00048
00049 PluginLoader* PluginLoader::mSelf = 0;
00050
00051 PluginLoader::PluginLoader()
00052 {
00053 scan();
00054 }
00055
00056 PluginLoader::~PluginLoader()
00057 {
00058 qDeleteAll( mPluginLoaders );
00059 mPluginLoaders.clear();
00060 }
00061
00062 PluginLoader* PluginLoader::self()
00063 {
00064 if ( !mSelf )
00065 mSelf = new PluginLoader();
00066
00067 return mSelf;
00068 }
00069
00070 QStringList PluginLoader::names() const
00071 {
00072 return mPluginInfos.keys();
00073 }
00074
00075 QObject* PluginLoader::createForName( const QString & name )
00076 {
00077 if ( !mPluginInfos.contains( name ) ) {
00078 kWarning( 5300 ) << "plugin name \"" << name << "\" is unknown to the plugin loader." << endl;
00079 return 0;
00080 }
00081
00082 PluginMetaData &info = mPluginInfos[ name ];
00083
00084
00085 foreach (QObject *plugin, QPluginLoader::staticInstances()) {
00086 if(QLatin1String(plugin->metaObject()->className()) == info.className) {
00087 info.loaded = true;
00088 return plugin;
00089 break;
00090 }
00091 }
00092
00093 if ( !info.loaded ) {
00094 KPluginLoader* loader = new KPluginLoader( info.library );
00095 if ( loader->fileName().isEmpty() ) {
00096 kWarning( 5300 ) << loader->errorString();
00097 delete loader;
00098 return 0;
00099 }
00100
00101 mPluginLoaders.insert( name, loader );
00102 info.loaded = true;
00103 }
00104
00105 QPluginLoader *loader = mPluginLoaders.value( name );
00106 Q_ASSERT(loader);
00107
00108 QObject *object = loader->instance();
00109 if ( !object ) {
00110 #ifdef _WIN32_WCE
00111
00112
00113 QString errMessage;
00114 errMessage.append(QLatin1String("plugin \""));
00115 errMessage.append(info.className);
00116 errMessage.append(QLatin1String("\" is not buildin static, please specify this information in the bugreport."));
00117 QMessageBox::critical(NULL,QLatin1String("Error"), errMessage);
00118
00119 #endif
00120 kWarning( 5300 ) << "unable to load plugin for plugin name \"" << name << "\"." << endl;
00121 kWarning( 5300 ) << "Error was:\"" << loader->errorString() << "\"." << endl;
00122 return 0;
00123 }
00124
00125 return object;
00126 }
00127
00128 PluginMetaData PluginLoader::infoForName( const QString & name ) const
00129 {
00130 if ( !mPluginInfos.contains( name ) )
00131 return PluginMetaData();
00132
00133 return mPluginInfos.value( name );
00134 }
00135
00136 void PluginLoader::scan()
00137 {
00138 const QStringList list = KGlobal::dirs()->findAllResources( "data", QLatin1String( "akonadi/plugins/serializer/*.desktop" ),
00139 KStandardDirs::Recursive | KStandardDirs::NoDuplicates );
00140 for ( int i = 0; i < list.count(); ++i ) {
00141 const QString entry = list.at( i );
00142
00143 KConfig config( entry, KConfig::SimpleConfig );
00144 if ( config.hasGroup( "Misc" ) && config.hasGroup( "Plugin" ) ) {
00145 KConfigGroup group( &config, "Plugin" );
00146
00147 const QString type = group.readEntry( "Type" ).toLower();
00148 if ( type.isEmpty() ) {
00149 kWarning( 5300 ) << "missing or empty [Plugin]Type value in \"" << entry << "\" - skipping" << endl;
00150 continue;
00151 }
00152
00153
00154
00155
00156 const QStringList classes = group.readXdgListEntry( "X-Akonadi-Class" );
00157 if ( classes.isEmpty() ) {
00158 kWarning( 5300 ) << "missing or empty [Plugin]X-Akonadi-Class value in \"" << entry << "\" - skipping" << endl;
00159 continue;
00160 }
00161
00162 const QString library = group.readEntry( "X-KDE-Library" );
00163 if ( library.isEmpty() ) {
00164 kWarning( 5300 ) << "missing or empty [Plugin]X-KDE-Library value in \"" << entry << "\" - skipping" << endl;
00165 continue;
00166 }
00167
00168 KConfigGroup group2( &config, "Misc" );
00169
00170 QString name = group2.readEntry( "Name" );
00171 if ( name.isEmpty() ) {
00172 kWarning( 5300 ) << "missing or empty [Misc]Name value in \"" << entry << "\" - inserting default name" << endl;
00173 name = i18n( "Unnamed plugin" );
00174 }
00175
00176 QString comment = group2.readEntry( "Comment" );
00177 if ( comment.isEmpty() ) {
00178 kWarning( 5300 ) << "missing or empty [Misc]Comment value in \"" << entry << "\" - inserting default name" << endl;
00179 comment = i18n( "No description available" );
00180 }
00181
00182 QString cname = group.readEntry( "X-KDE-ClassName" );
00183 if ( cname.isEmpty() ) {
00184 kWarning( 5300 ) << "missing or empty X-KDE-ClassName value in \"" << entry << "\"" << endl;
00185 }
00186
00187 const QStringList mimeTypes = type.split( QLatin1Char( ',' ), QString::SkipEmptyParts );
00188
00189 kDebug( 5300 ) << "registering Desktop file" << entry << "for" << mimeTypes << '@' << classes;
00190 Q_FOREACH( const QString & mimeType, mimeTypes )
00191 Q_FOREACH( const QString & classType, classes )
00192 mPluginInfos.insert( mimeType + QLatin1Char('@') + classType, PluginMetaData( library, name, comment, cname ) );
00193
00194 } else {
00195 kWarning( 5300 ) << "Desktop file \"" << entry << "\" doesn't seem to describe a plugin " << "(misses Misc and/or Plugin group)" << endl;
00196 }
00197 }
00198 }