LibEngsas
epluginloader.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2012 EngSaS - Engineering Solutions and Services Langenbach. All rights reserved.
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  MA 02110-1301 USA.
18 */
19 
20 #ifndef EPLUGINLOADER_H
21 #define EPLUGINLOADER_H
22 
23 #include "eglobal.h"
24 #include "emodulelistwidgetitem.h"
25 
26 #include <QPluginLoader>
27 #include <QFileInfo>
28 #include <QDir>
29 #include <QObject>
30 
75 template <class PluginType> class EPluginLoader
76 {
77  public:
86  static QList<PluginType*> loadPlugins(QString searchPath, EngSaS::ModuleListWidgetItems &log);
95  static PluginType *loadPlugin(QString name, QString searchPath, EModuleListWidgetItem *item = NULL);
96 
103  PluginType *doLoadPlugin(QString absFilePath, EModuleListWidgetItem *item = NULL);
104 };
105 
106 template <class PluginType>
107 QList< PluginType* > EPluginLoader<PluginType>::loadPlugins(QString searchPath, EngSaS::ModuleListWidgetItems& log)
108 {
109  QList<PluginType*> result;
110 
111  QDir dir(searchPath);
112  if ( !dir.exists() || !dir.isReadable())
113  return result;
114 
116  QStringList files = dir.entryList(QDir::Files | QDir::Readable);
117  foreach ( QString file, files ) {
118  // handle symlinks
119  QFileInfo info(dir.filePath(file));
120  if(info.isSymLink()){
121  // check whether target is also in the list to avoid double loading
122  bool doubleEntry = false;
123  foreach(QString compareFile, files){
124  if(compareFile == file)
125  continue;
126  if(info.symLinkTarget() == dir.filePath(compareFile)){
127  doubleEntry = true;
128  break;
129  }
130  }
131  if(doubleEntry)
132  continue;
133  }
134 
136  log << item;
137  PluginType *plugin = mLoader.doLoadPlugin(dir.filePath ( file ), item);
138  if(plugin)
139  result << plugin;
140  }
141  return result;
142 }
143 
144 template <class PluginType>
145 PluginType* EPluginLoader<PluginType>::loadPlugin(QString name, QString searchPath, EModuleListWidgetItem* item)
146 {
147  if(name.isEmpty())
148  return NULL;
149 
150  QDir dir(searchPath);
151  if ( !dir.exists() || !dir.isReadable()){
152  if(item)
153  item->setErrorMessage(QObject::tr("Directory does not exists or is not readable:\n%1").arg(dir.absolutePath()));
154  return NULL;
155  }
156 
158  QStringList filter;
159  filter << QString("*%1*").arg(name);
160  QStringList files = dir.entryList (filter, QDir::Files | QDir::Readable);
161 
162  if(files.size() < 1){
163  if(item){
164  item->setErrorMessage(
165  QObject::tr("%1 not found at \n%2\n\nFilters: %3\n")
166  .arg(name)
167  .arg(dir.absolutePath())
168  .arg(filter.join(", "))
169  );
170  }
171  }
172 
173  foreach ( QString file, files ) {
174  PluginType *plugin = mLoader.doLoadPlugin(dir.filePath ( file ), item);
175  if(plugin)
176  return plugin;
177  }
178  return NULL;
179 }
180 
181 template <class PluginType>
182 PluginType* EPluginLoader<PluginType>::doLoadPlugin(QString absFilePath, EModuleListWidgetItem* item)
183 {
184  QFileInfo file(absFilePath);
185  if(item)
186  item->setFile(file.absoluteFilePath());
187  if(!file.exists() || !file.isReadable()){
188  if(item)
189  item->setErrorMessage(QObject::tr( "File does not exists or is not readable:\n%1").arg(file.absoluteFilePath()));
190  return NULL;
191  }
192 
193  if(!QLibrary::isLibrary(file.absoluteFilePath())){
194  if(item)
195  item->setErrorMessage(QObject::tr("%1 is no library file").arg(file.absoluteFilePath()));
196  return NULL;
197  }
198 
199  QPluginLoader loader ( file.absoluteFilePath() );
200  QObject *plugin = loader.instance();
201  if ( !plugin ){
202  if(item)
203  item->setErrorMessage(
204  QObject::tr( "While loading %1 an error occured:\n%2\n" )
205  .arg ( file.absoluteFilePath() ).arg(loader.errorString())
206  );
207  return NULL;
208  }
209 
210  PluginType *newPlugin = qobject_cast<PluginType *> ( plugin );
211  if ( !newPlugin ){
212  if(item)
213  item->setErrorMessage(QObject::tr("Could not load %1!\n(Plugin is not of specified type!)").arg(file.absoluteFilePath()));
214  return NULL;
215  }
216 
217  if(item){
218  item->setStatus(true);
219  QObject *object = dynamic_cast<QObject*>(newPlugin);
220  if(object)
221  item->extractFromPlugin(object);
222  }
223  return newPlugin;
224 }
225 
226 #endif // EPLUGINLOADER_H