From 8f9f382e1c97cab2e72e97495650c73ac4b97314 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Fri, 4 Jan 2013 14:50:19 +0100 Subject: Imported Upstream version 0.3.0.5 --- PluginsManager.cpp | 889 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 889 insertions(+) create mode 100644 PluginsManager.cpp (limited to 'PluginsManager.cpp') diff --git a/PluginsManager.cpp b/PluginsManager.cpp new file mode 100644 index 0000000..4dc9157 --- /dev/null +++ b/PluginsManager.cpp @@ -0,0 +1,889 @@ +/** \file PluginsManager.cpp +\brief Define the class to manage and load the plugins +\author alpha_one_x86 +\version 0.3 +\date 2010 +\licence GPL3, see the file COPYING */ + +#include +#include +#include +#include +#include + +#include "PluginsManager.h" + +/// \brief Create the manager and load the defaults variables +PluginsManager::PluginsManager() +{ + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start"); + //load the overall instance + pluginLoaded=false; + resources=ResourcesManager::getInstance(); + options=OptionEngine::getInstance(); + + language="en"; + stopIt=false; + editionSemList.release(); + checkPluginThread=new AuthPlugin(); + englishPluginType << "CopyEngine" << "Languages" << "Listener" << "PluginLoader" << "SessionLoader" << "Themes"; + //catPlugin << tr("CopyEngine") << tr("Languages") << tr("Listener") << tr("PluginLoader") << tr("SessionLoader") << tr("Themes"); + importingPlugin=false; + connect(&decodeThread, SIGNAL(decodedIsFinish()), this, SLOT(decodingFinished())); + connect(checkPluginThread, SIGNAL(authentifiedPath(QString)), this, SLOT(newAuthPath(QString))); + connect(this, SIGNAL(finished()), this, SLOT(post_operation())); + connect(this, SIGNAL(newLanguageLoaded()), &pluginInformationWindows, SLOT(retranslateInformation())); +// connect(this, SIGNAL(pluginListingIsfinish()), options,SLOT(setInterfaceValue())); + //load the plugins list + /// \bug bug when I put here: moveToThread(this);, due to the direction connection to remove the plugin + start(); +} + +/// \brief Destroy the manager +PluginsManager::~PluginsManager() +{ + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start"); + int index=0; + int loop_size=pluginsList.size(); + while(indexisRunning()) + this->wait(0); + delete checkPluginThread; + OptionEngine::destroyInstanceAtTheLastCall(); + ResourcesManager::destroyInstanceAtTheLastCall(); +} + +/// \brief set current language +void PluginsManager::setLanguage(const QString &language) +{ + this->language=language; +} + +void PluginsManager::post_operation() +{ + pluginLoaded=true; + emit pluginListingIsfinish(); +} + +bool PluginsManager::allPluginHaveBeenLoaded() +{ + return pluginLoaded; +} + +void PluginsManager::lockPluginListEdition() +{ + editionSemList.acquire(); +} + +void PluginsManager::unlockPluginListEdition() +{ + editionSemList.release(); +} + +void PluginsManager::run() +{ + //load the path and plugins into the path + QStringList readPath; + readPath << resources->getReadPath(); + pluginsList.clear(); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"pluginsList.size(): "+QString::number(pluginsList.size())); + foreach(QString basePath,readPath) + { + foreach(QString dirSub,englishPluginType) + { + QString pluginComposed=basePath+dirSub+QDir::separator(); + QDir dir(pluginComposed); + if(stopIt) + return; + if(dir.exists()) + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"search plugin into: "+pluginComposed); + foreach(QString dirName, dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot)) + { + if(stopIt) + return; + loadPluginInformation(pluginComposed+dirName+QDir::separator()); + } + } + } + } + #ifdef ULTRACOPIER_DEBUG + int index=0; + int loop_size=pluginsList.size(); + while(indexloadSearchPath(readPath,englishPluginType); + checkPluginThread->stop(); + checkPluginThread->start(); + checkDependencies(); +} + +QString PluginsManager::categoryToString(const PluginType &category) +{ + switch(category) + { + case PluginType_CopyEngine: + return "CopyEngine"; + break; + case PluginType_Languages: + return "Languages"; + break; + case PluginType_Listener: + return "Listener"; + break; + case PluginType_PluginLoader: + return "PluginLoader"; + break; + case PluginType_SessionLoader: + return "SessionLoader"; + break; + case PluginType_Themes: + return "Themes"; + break; + default: + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"cat text not found"); + return "Unknow"; + break; + } +} + +QString PluginsManager::categoryToTranslation(const PluginType &category) +{ + return pluginInformationWindows.categoryToTranslation(category); +} + +bool PluginsManager::isSamePlugin(const PluginsAvailable &pluginA,const PluginsAvailable &pluginB) +{ + if(pluginA.category!=pluginB.category) + return false; + if(pluginA.path!=pluginB.path) + return false; + if(pluginA.name!=pluginB.name) + return false; + if(pluginA.writablePath!=pluginB.writablePath) + return false; + if(pluginA.categorySpecific!=pluginB.categorySpecific) + return false; + if(pluginA.version!=pluginB.version) + return false; + if(pluginA.informations!=pluginB.informations) + return false; + return true; +} + +bool PluginsManager::loadPluginInformation(const QString &path) +{ + PluginsAvailable tempPlugin; + tempPlugin.isAuth = false; + tempPlugin.path = path; + tempPlugin.category = PluginType_Unknow; + QDir pluginPath(path); + if(pluginPath.cdUp() && pluginPath.cdUp() && + resources->getWritablePath()!="" && + pluginPath==QDir(resources->getWritablePath())) + tempPlugin.isWritable=true; + else + tempPlugin.isWritable=false; + QFile xmlMetaData(path+"informations.xml"); + if(xmlMetaData.exists()) + { + if(xmlMetaData.open(QIODevice::ReadOnly)) + { + loadPluginXml(&tempPlugin,xmlMetaData.readAll()); + xmlMetaData.close(); + } + else + { + tempPlugin.errorString=tr("informations.xml is not accessible"); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"informations.xml is not accessible into the plugin: "+path); + } + } + else + { + tempPlugin.errorString=tr("informations.xml not found into the plugin"); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"informations.xml not found into the plugin: "+path); + } + editionSemList.acquire(); + pluginsList << tempPlugin; + editionSemList.release(); + if(tempPlugin.errorString=="") + { + emit onePluginAdded(tempPlugin); + return true; + } + else + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"Error detected, the not loaded: "+tempPlugin.errorString+", for path: "+tempPlugin.path); + return false; + } +} + +void PluginsManager::loadPluginXml(PluginsAvailable * thePlugin,const QByteArray &xml) +{ + QString errorStr; + int errorLine; + int errorColumn; + QDomDocument domDocument; + if (!domDocument.setContent(xml, false, &errorStr,&errorLine,&errorColumn)) + { + thePlugin->errorString=tr("%1, parse error at line %2, column %3: %4").arg("informations.xml").arg(errorLine).arg(errorColumn).arg(errorStr); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("%1, Parse error at line %2, column %3: %4").arg("informations.xml").arg(errorLine).arg(errorColumn).arg(errorStr)); + } + else + { + QDomElement root = domDocument.documentElement(); + if (root.tagName() != "package") + { + thePlugin->errorString=tr("\"package\" root tag not found for the xml file"); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"\"package\" root balise not found for the xml file"); + } + //load the variable + if(thePlugin->errorString=="") + loadBalise(root,"title",&(thePlugin->informations),&(thePlugin->errorString),true,true,true); + if(thePlugin->errorString=="") + loadBalise(root,"website",&(thePlugin->informations),&(thePlugin->errorString),false,true); + if(thePlugin->errorString=="") + loadBalise(root,"description",&(thePlugin->informations),&(thePlugin->errorString),true,true,true); + if(thePlugin->errorString=="") + loadBalise(root,"author",&(thePlugin->informations),&(thePlugin->errorString),true,false); + if(thePlugin->errorString=="") + loadBalise(root,"pubDate",&(thePlugin->informations),&(thePlugin->errorString),true,false); + if(thePlugin->errorString=="") + { + loadBalise(root,"version",&(thePlugin->informations),&(thePlugin->errorString),true,false); + if(thePlugin->errorString=="") + thePlugin->version=thePlugin->informations.last().last(); + } + if(thePlugin->errorString=="") + { + loadBalise(root,"category",&(thePlugin->informations),&(thePlugin->errorString),true,false); + if(thePlugin->errorString=="") + { + QString tempCat=thePlugin->informations.last().last(); + if(tempCat=="Languages") + thePlugin->category=PluginType_Languages; + else if(tempCat=="CopyEngine") + thePlugin->category=PluginType_CopyEngine; + else if(tempCat=="Listener") + thePlugin->category=PluginType_Listener; + else if(tempCat=="PluginLoader") + thePlugin->category=PluginType_PluginLoader; + else if(tempCat=="SessionLoader") + thePlugin->category=PluginType_SessionLoader; + else if(tempCat=="Themes") + thePlugin->category=PluginType_Themes; + else + thePlugin->errorString="Unknow category: "+(int)thePlugin->category; + if(thePlugin->errorString.isEmpty()) + { + if(thePlugin->category!=PluginType_Languages) + { + loadBalise(root,"architecture",&(thePlugin->informations),&(thePlugin->errorString),true,false); + if(thePlugin->errorString=="") + { + #ifndef ULTRACOPIER_VERSION_PORTABLE + if(thePlugin->informations.last().last()!=ULTRACOPIER_PLATFORM_CODE) + thePlugin->errorString="Wrong platform code: "+thePlugin->informations.last().last(); + #endif + } + } + } + } + } + if(thePlugin->errorString=="") + { + loadBalise(root,"name",&(thePlugin->informations),&(thePlugin->errorString),true,false); + if(thePlugin->errorString=="") + { + thePlugin->name=thePlugin->informations.last().last(); + int index=0; + int loop_size=pluginsList.size(); + int sub_index,loop_sub_size; + while(indexname && + pluginsList.at(index).category==thePlugin->category) + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"Plugin duplicate found ("+QString::number((int)thePlugin->category)+"/"+pluginsList.at(index).informations.at(sub_index).last()+"), already loaded, actual version skipped: "+thePlugin->version); + thePlugin->errorString=tr("Duplicated plugin found, already loaded!"); + break; + break; + } + sub_index++; + } + index++; + } + } + } + if(thePlugin->errorString=="") + loadBalise(root,"dependencies",&(thePlugin->informations),&(thePlugin->errorString),true,false); + if(thePlugin->errorString=="") + { + QDomElement child = root.firstChildElement("categorySpecific"); + if(!child.isNull() && child.isElement()) + thePlugin->categorySpecific=child; + } + } +} + +/// \brief to load the multi-language balise +void PluginsManager::loadBalise(const QDomElement &root,const QString &name,QList *informations,QString *errorString,bool needHaveOneEntryMinimum,bool multiLanguage,bool englishNeedBeFound) +{ + int foundElement=0; + bool englishTextIsFoundForThisChild=false; + QDomElement child = root.firstChildElement(name); + while(!child.isNull()) + { + if(child.isElement()) + { + QStringList newInformations; + if(multiLanguage) + { + if(child.hasAttribute("xml:lang")) + { + if(child.attribute("xml:lang")=="en") + englishTextIsFoundForThisChild=true; + foundElement++; + newInformations << child.tagName() << child.attribute("xml:lang") << child.text(); + } + else + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Have not the attribute xml:lang: child.tagName(): %1, child.text(): %2").arg(child.tagName()).arg(child.text())); + } + else + { + foundElement++; + newInformations << child.tagName() << child.text(); + } + *informations << newInformations; + } + else + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Is not Element: child.tagName(): %1").arg(child.tagName())); + child = child.nextSiblingElement(name); + } + if(multiLanguage && englishTextIsFoundForThisChild==false && englishNeedBeFound) + { + informations->clear(); + *errorString=tr("English text missing into the informations.xml for the tag: %1").arg(name); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("English text missing into the informations.xml for the tag: %1").arg(name)); + return; + } + if(needHaveOneEntryMinimum && foundElement==0) + { + informations->clear(); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Tag not found: %1").arg(name)); + *errorString=tr("Tag not found: %1").arg(name); + } +} + +/// \brief to load the get dom specific +QString PluginsManager::getDomSpecific(const QDomElement &root,const QString &name,const QList > &listChildAttribute) +{ + QDomElement child = root.firstChildElement(name); + int index,loop_size; + bool allIsFound; + while(!child.isNull()) + { + if(child.isElement()) + { + allIsFound=true; + index=0; + loop_size=listChildAttribute.size(); + while(index|>=)[a-zA-Z0-9\\-]+-([0-9]+\\.)*[0-9]+$"))) + { + pluginsList[index].informations.clear(); + pluginsList[index].errorString=tr("Dependencies part is wrong"); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Dependencies part is wrong: %1").arg(dependenciesToParse)); + break; + } + QString partName=dependenciesToParse; + partName=partName.remove(QRegExp("(<=|<|=|>|>=)")); + partName=partName.remove(QRegExp("-([0-9]+\\.)*[0-9]+")); + QString partVersion=dependenciesToParse; + partVersion=partVersion.remove(QRegExp("(<=|<|=|>|>=)")); + partVersion=partVersion.remove(QRegExp("[a-zA-Z0-9\\-]+-")); + QString partComp=dependenciesToParse; + partComp=partComp.remove(QRegExp("[a-zA-Z0-9\\-]+-([0-9]+\\.)*[0-9]+")); + //current version soft + QString pluginVersion=getPluginVersion(partName); + depCheck=compareVersion(pluginVersion,partComp,partVersion); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"dependencies to resolv, partName: "+partName+", partVersion: "+partVersion+", partComp: "+partComp+", pluginVersion: "+pluginVersion+", depCheck: "+QString::number(depCheck)); + if(!depCheck) + { + pluginsList[index].informations.clear(); + pluginsList[index].errorString=tr("Dependencies %1 are not satisfied, for plugin: %2").arg(dependenciesToParse).arg(pluginsList[index].path); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Dependencies %1 are not satisfied, for plugin: %2").arg(dependenciesToParse).arg(pluginsList[index].path)); + break; + } + indexOfDependencies++; + } + } + sub_index++; + } + index++; + } +} + +/// \brief get the version +QString PluginsManager::getPluginVersion(const QString &pluginName) +{ + if(pluginName=="ultracopier") + return ULTRACOPIER_VERSION; + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start"); + int index=0; + while(index") + defaultReturnValue=false; + while(indexreaNumberB) + return false; + if(reaNumberA") + { + if(reaNumberAreaNumberB) + return true; + } + if(sign=="<=") + { + if(reaNumberA>reaNumberB) + return false; + if(reaNumberA=") + { + if(reaNumberAreaNumberB) + return true; + } + index++; + } + return defaultReturnValue; +} + +QList PluginsManager::getPluginsByCategory(const PluginType &category) +{ + QList list; + int index=0,loop_size=pluginsList.size(); + while(index PluginsManager::getPlugins() +{ + QList list; + int index=0; + while(index dataList = tarFile.getDataList(); + if(fileList.size()>1) + { + QString basePluginArchive=""; + /* block use less for tar? + if(fileList.at(0).contains(QRegExp("[\\/]"))) + { + bool folderFoundEveryWhere=true; + basePluginArchive=fileList.at(0); + basePluginArchive.remove(QRegExp("[\\/].*$")); + for (int i = 0; i < list.size(); ++i) + { + if(!fileList.at(i).startsWith(basePluginArchive)) + { + folderFoundEveryWhere=false; + break; + } + } + if(folderFoundEveryWhere) + { + for (int i = 0; i < fileList.size(); ++i) + fileList[i].remove(0,basePluginArchive.size()); + } + else + basePluginArchive=""; + }*/ + PluginsAvailable tempPlugin; + QString categoryFinal=""; + for (int i = 0; i < fileList.size(); ++i) + if(fileList.at(i)=="informations.xml") + { + loadPluginXml(&tempPlugin,dataList.at(i)); + break; + } + if(tempPlugin.errorString=="") + { + categoryFinal=categoryToString(tempPlugin.category); + if(categoryFinal!="") + { + QString writablePath=resources->getWritablePath(); + if(writablePath!="") + { + QDir dir; + QString finalPluginPath=writablePath+categoryFinal+QDir::separator()+tempPlugin.name+QDir::separator(); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"writablePath: \""+writablePath+"\""); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"basePluginArchive: \""+basePluginArchive+"\""); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"categoryFinal: \""+categoryFinal+"\""); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Information,"finalPluginPath: \""+finalPluginPath+"\""); + if(!dir.exists(finalPluginPath)) + { + bool errorFound=false; + for (int i = 0; i < fileList.size(); ++i) + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Information,"file "+QString::number(i)+": "+finalPluginPath+fileList.at(i)); + fileList[i].remove(QRegExp("^(..?[\\/])+")); + QFile currentFile(finalPluginPath+fileList.at(i)); + QFileInfo info(currentFile); + if(!dir.exists(info.absolutePath())) + if(!dir.mkpath(info.absolutePath())) + { + resources->disableWritablePath(); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,"Unable to make the path: "+info.absolutePath()); + QMessageBox::critical(NULL,tr("Plugin loader"),tr("Unable to create a folder to install the plugin:\n%1").arg(info.absolutePath())); + errorFound=true; + break; + } + if(currentFile.open(QIODevice::ReadWrite)) + { + currentFile.write(dataList.at(i)); + currentFile.close(); + } + else + { + resources->disableWritablePath(); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,"Unable to make the file: "+info.absolutePath()+", error:"+currentFile.errorString()); + QMessageBox::critical(NULL,tr("Plugin loader"),tr("Unable to create a file to install the plugin:\n%1\nsince:%2").arg(info.absolutePath()).arg(currentFile.errorString())); + errorFound=true; + break; + } + } + if(!errorFound) + { + if(loadPluginInformation(finalPluginPath)) + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Information,"push the new plugin into the real list"); + checkDependencies(); + emit needLangToRefreshPluginList(); + } + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,"Folder with same name is present, skip the plugin installation: "+finalPluginPath); + QMessageBox::critical(NULL,tr("Plugin loader"),tr("Folder with same name is present, skip the plugin installation:\n%1").arg(finalPluginPath)); + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,"Have not writable path, then how add you plugin?"); + QMessageBox::critical(NULL,tr("Plugin loader"),tr("Unable to load the plugin content, please check it")); + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"category into informations.xml not found!"); + QMessageBox::critical(NULL,tr("Plugin loader"),tr("Unable to load the plugin content, please check it")); + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"Error in the xml: "+tempPlugin.errorString); + QMessageBox::critical(NULL,tr("Plugin loader"),tr("Unable to load the plugin content, please check it: %1").arg(tempPlugin.errorString)); + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"No file found into the plugin"); + QMessageBox::critical(NULL,tr("Plugin loader"),tr("Unable to load the plugin content, please check it")); + } + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"decodeThread.errorFound(), error: "+decodeThread.errorString()); + QMessageBox::critical(NULL,tr("Plugin loader"),tr("Unable to load the plugin content, please check it: %1").arg(decodeThread.errorString())); + } + importingPlugin=false; +} + +void PluginsManager::newAuthPath(const QString &path) +{ + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start"); + int index=0; + while(index