ctkPluginFrameworkContext.cpp

Go to the documentation of this file.
00001 /*=============================================================================
00002 
00003   Library: CTK
00004 
00005   Copyright (c) 2010 German Cancer Research Center,
00006     Division of Medical and Biological Informatics
00007 
00008   Licensed under the Apache License, Version 2.0 (the "License");
00009   you may not use this file except in compliance with the License.
00010   You may obtain a copy of the License at
00011 
00012     http://www.apache.org/licenses/LICENSE-2.0
00013 
00014   Unless required by applicable law or agreed to in writing, software
00015   distributed under the License is distributed on an "AS IS" BASIS,
00016   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00017   See the License for the specific language governing permissions and
00018   limitations under the License.
00019 
00020 =============================================================================*/
00021 
00022 #include "ctkPluginFrameworkContext_p.h"
00023 
00024 #include "ctkPluginFrameworkPrivate_p.h"
00025 #include "ctkPluginArchive_p.h"
00026 #include "ctkPluginConstants.h"
00027 
00028 
00029   QMutex ctkPluginFrameworkContext::globalFwLock;
00030   int ctkPluginFrameworkContext::globalId = 1;
00031 
00032 
00033   ctkPluginFrameworkContext::ctkPluginFrameworkContext(
00034       const ctkPluginFrameworkFactory::Properties& initProps)
00035         : plugins(0), services(this), systemPlugin(this),
00036         storage(this), props(initProps)
00037   {
00038 
00039     {
00040       QMutexLocker lock(&globalFwLock);
00041       id = globalId++;
00042     }
00043 
00044     log() << "created";
00045   }
00046 
00047   void ctkPluginFrameworkContext::init()
00048   {
00049     log() << "initializing";
00050 
00051 //    if (Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
00052 //        .equals(props.getProperty(Constants.FRAMEWORK_STORAGE_CLEAN))) {
00053 //      deleteFWDir();
00054 //      // Must remove the storage clean property since it should not be
00055 //      // used more than once!
00056 //      props.removeProperty(Constants.FRAMEWORK_STORAGE_CLEAN);
00057 //    }
00058 //    props.save();
00059 
00060     ctkPluginFrameworkPrivate* const systemPluginPrivate = systemPlugin.d_func();
00061     systemPluginPrivate->initSystemPlugin();
00062 
00063     plugins = new ctkPlugins(this);
00064 
00065     plugins->load();
00066 
00067     log() << "inited";
00068 
00069     log() << "Installed plugins:";
00070     // Use the ordering in the plugin storage to get a sorted list of plugins.
00071     QList<ctkPluginArchive*> allPAs = storage.getAllPluginArchives();
00072     for (int i = 0; i < allPAs.size(); ++i)
00073     {
00074       ctkPluginArchive* pa = allPAs[i];
00075       ctkPlugin* p = plugins->getPlugin(pa->getPluginLocation().toString());
00076       log() << " #" << p->getPluginId() << " " << p->getSymbolicName() << ":"
00077           << p->getVersion() << " location:" << p->getLocation();
00078     }
00079   }
00080 
00081   void ctkPluginFrameworkContext::uninit()
00082   {
00083     log() << "uninit";
00084 
00085     //ctkPluginFrameworkPrivate* const systemPluginPrivate = systemPlugin.d_func();
00086     //systemPluginPrivate->uninitSystemBundle();
00087 
00088     plugins->clear();
00089     delete plugins;
00090     plugins = 0;
00091 
00092     storage.close();
00093 
00094   }
00095 
00096   int ctkPluginFrameworkContext::getId() const
00097   {
00098     return id;
00099   }
00100 
00101   void ctkPluginFrameworkContext::checkOurPlugin(ctkPlugin* plugin) const
00102   {
00103     ctkPluginPrivate* pp = plugin->d_func();
00104     if (this != pp->fwCtx)
00105     {
00106       throw std::invalid_argument("ctkPlugin does not belong to this framework: " + plugin->getSymbolicName().toStdString());
00107     }
00108   }
00109 
00110   QDebug ctkPluginFrameworkContext::log() const
00111   {
00112     QDebug dbg(qDebug());
00113     dbg << "Framework instance " << getId() << ": ";
00114     return dbg;
00115   }
00116 
00117   void ctkPluginFrameworkContext::resolvePlugin(ctkPluginPrivate* plugin)
00118   {
00119     qDebug() << "resolve:" << plugin->symbolicName << "[" << plugin->id << "]";
00120 
00121     // If we enter with tempResolved set, it means that we already have
00122     // resolved plugins. Check that it is true!
00123     if (tempResolved.size() > 0 && !tempResolved.contains(plugin))
00124     {
00125       ctkPluginException pe("resolve: InternalError1!", ctkPluginException::RESOLVE_ERROR);
00126       listeners.frameworkError(plugin->q_func(), pe);
00127       throw pe;
00128     }
00129 
00130     tempResolved.clear();
00131     tempResolved.insert(plugin);
00132 
00133     checkRequirePlugin(plugin);
00134 
00135     tempResolved.clear();
00136 
00137     qDebug() << "resolve: Done for" << plugin->symbolicName << "[" << plugin->id << "]";
00138   }
00139 
00140   void ctkPluginFrameworkContext::checkRequirePlugin(ctkPluginPrivate *plugin)
00141   {
00142     if (!plugin->require.isEmpty())
00143     {
00144       qDebug() << "checkRequirePlugin: check requiring plugin" << plugin->id;
00145 
00146       QListIterator<ctkRequirePlugin*> i(plugin->require);
00147       while (i.hasNext())
00148       {
00149         ctkRequirePlugin* pr = i.next();
00150         QList<ctkPlugin*> pl = plugins->getPlugins(pr->name, pr->pluginRange);
00151         ctkPluginPrivate* ok = 0;
00152         for (QListIterator<ctkPlugin*> pci(pl); pci.hasNext() && ok == 0; )
00153         {
00154           ctkPluginPrivate* p2 = pci.next()->d_func();
00155           if (tempResolved.contains(p2))
00156           {
00157             ok = p2;
00158           }
00159           else if (ctkPluginPrivate::RESOLVED_FLAGS & p2->state)
00160           {
00161             ok = p2;
00162           }
00163           else if (p2->state == ctkPlugin::INSTALLED) {
00164             QSet<ctkPluginPrivate*> oldTempResolved = tempResolved;
00165             tempResolved.insert(p2);
00166             checkRequirePlugin(p2);
00167             tempResolved = oldTempResolved;
00168             ok = p2;
00169           }
00170         }
00171 
00172         if (!ok && pr->resolution == PluginConstants::RESOLUTION_MANDATORY)
00173         {
00174           tempResolved.clear();
00175           qDebug() << "checkRequirePlugin: failed to satisfy:" << pr->name;
00176           throw ctkPluginException(QString("Failed to resolve required plugin: %1").arg(pr->name));
00177         }
00178       }
00179     }
00180 
00181 
00182 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines