| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 | 
							- /*=============================================================================
 
-   Library: CTK
 
-   Copyright (c) German Cancer Research Center,
 
-     Division of Medical and Biological Informatics
 
-   Licensed under the Apache License, Version 2.0 (the "License");
 
-   you may not use this file except in compliance with the License.
 
-   You may obtain a copy of the License at
 
-     http://www.apache.org/licenses/LICENSE-2.0
 
-   Unless required by applicable law or agreed to in writing, software
 
-   distributed under the License is distributed on an "AS IS" BASIS,
 
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
-   See the License for the specific language governing permissions and
 
-   limitations under the License.
 
- =============================================================================*/
 
- #include "ctkPlugin.h"
 
- #include "ctkPluginContext.h"
 
- #include "ctkPluginFrameworkUtil_p.h"
 
- #include "ctkPluginPrivate_p.h"
 
- #include "ctkPluginArchive_p.h"
 
- #include "ctkPluginFrameworkContext_p.h"
 
- #include "ctkServices_p.h"
 
- #include "ctkUtils.h"
 
- #include <QStringList>
 
- //----------------------------------------------------------------------------
 
- ctkPlugin::ctkPlugin()
 
- : d_ptr(0)
 
- {
 
- }
 
- //----------------------------------------------------------------------------
 
- void ctkPlugin::init(ctkPluginPrivate* dd)
 
- {
 
-   if (d_ptr) throw std::logic_error("ctkPlugin already initialized");
 
-   d_ptr = dd;
 
- }
 
- //----------------------------------------------------------------------------
 
- void ctkPlugin::init(const QWeakPointer<ctkPlugin>& self,
 
-                      ctkPluginFrameworkContext* fw,
 
-                      ctkPluginArchive* pa)
 
- {
 
-   if (d_ptr) throw std::logic_error("ctkPlugin already initialized");
 
-   d_ptr = new ctkPluginPrivate(self, fw, pa);
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkPlugin::~ctkPlugin()
 
- {
 
-   delete d_ptr;
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkPlugin::State ctkPlugin::getState() const
 
- {
 
-   Q_D(const ctkPlugin);
 
-   return d->state;
 
- }
 
- //----------------------------------------------------------------------------
 
- void ctkPlugin::start(const StartOptions& options)
 
- {
 
-   Q_D(ctkPlugin);
 
-   if (d->state == UNINSTALLED)
 
-   {
 
-     throw std::logic_error("ctkPlugin is uninstalled");
 
-   }
 
-   // Initialize the activation; checks initialization of lazy
 
-   // activation.
 
-   //TODO 1: If activating or deactivating, wait a litle
 
-   // we don't use mutliple threads to start plugins for now
 
-   //waitOnActivation(lock, "ctkPlugin::start", false);
 
-   //2: start() is idempotent, i.e., nothing to do when already started
 
-   if (d->state == ACTIVE)
 
-   {
 
-     return;
 
-   }
 
-   //3: Record non-transient start requests.
 
-   if ((options & START_TRANSIENT) == 0)
 
-   {
 
-     d->setAutostartSetting(options);
 
-   }
 
-   //4: Resolve plugin (if needed)
 
-   d->getUpdatedState();
 
-   //5: Eager?
 
-   if ((options & START_ACTIVATION_POLICY) && !d->eagerActivation )
 
-   {
 
-     if (STARTING == d->state) return;
 
-     d->state = STARTING;
 
-     d->pluginContext.reset(new ctkPluginContext(this->d_func()));
 
-     ctkPluginEvent pluginEvent(ctkPluginEvent::LAZY_ACTIVATION, d->q_ptr);
 
-     d->fwCtx->listeners.emitPluginChanged(pluginEvent);
 
-   }
 
-   else
 
-   {
 
-     d->finalizeActivation();
 
-   }
 
- }
 
- //----------------------------------------------------------------------------
 
- void ctkPlugin::stop(const StopOptions& options)
 
- {
 
-   Q_D(ctkPlugin);
 
-   const std::exception* savedException = 0;
 
-   //1:
 
-   if (d->state == UNINSTALLED)
 
-   {
 
-     throw std::logic_error("Plugin is uninstalled");
 
-   }
 
-   //2: If activating or deactivating, wait a litle
 
-   // We don't support threaded start/stop methods, so we don't need to wait
 
-   //waitOnActivation(fwCtx.packages, "Plugin::stop", false);
 
-   //3:
 
-   if ((options & STOP_TRANSIENT) == 0)
 
-   {
 
-     d->ignoreAutostartSetting();
 
-   }
 
-   bool wasStarted = false;
 
-   switch (d->state)
 
-   {
 
-   case INSTALLED:
 
-   case RESOLVED:
 
-   case STOPPING:
 
-   case UNINSTALLED:
 
-     //4:
 
-     return;
 
-   case ACTIVE:
 
-     wasStarted = true;
 
-   case STARTING: // Lazy start...
 
-     try
 
-     {
 
-       d->stop0(wasStarted);
 
-     }
 
-     catch (const std::exception* exc)
 
-     {
 
-       savedException = exc;
 
-     }
 
-     break;
 
-   };
 
-   if (savedException)
 
-   {
 
-     if (const ctkPluginException* pluginExc = dynamic_cast<const ctkPluginException*>(savedException))
 
-     {
 
-       throw pluginExc;
 
-     }
 
-     else
 
-     {
 
-       throw dynamic_cast<const std::logic_error*>(savedException);
 
-     }
 
-   }
 
- }
 
- //----------------------------------------------------------------------------
 
- void ctkPlugin::uninstall()
 
- {
 
-   bool wasResolved = false;
 
-   Q_D(ctkPlugin);
 
-   if (d->archive)
 
-   {
 
-     try
 
-     {
 
-       d->archive->setStartLevel(-2); // Mark as uninstalled
 
-     }
 
-     catch (...)
 
-     { }
 
-   }
 
-   d->cachedHeaders = getHeaders();
 
-   switch (d->state)
 
-   {
 
-   case UNINSTALLED:
 
-     throw std::logic_error("Plugin is in UNINSTALLED state");
 
-   case STARTING: // Lazy start
 
-   case ACTIVE:
 
-   case STOPPING:
 
-     try
 
-     {
 
-       //TODO: If activating or deactivating, wait a litle
 
-       // we don't use mutliple threads to start plugins for now
 
-       //d->waitOnActivation(fwCtx.packages, "Bundle.uninstall", false);
 
-       if (d->state & (ACTIVE | STARTING))
 
-       {
 
-         try
 
-         {
 
-           d->stop0(d->state == ACTIVE);
 
-         }
 
-         catch (const std::exception& exception)
 
-         {
 
-           // NYI! not call inside lock
 
-           d->fwCtx->listeners.frameworkError(this->d_func()->q_func(), exception);
 
-         }
 
-       }
 
-     }
 
-     catch (const std::exception& e)
 
-     {
 
-       d->deactivating = false;
 
-       //fwCtx.packages.notifyAll();
 
-       d->fwCtx->listeners.frameworkError(this->d_func()->q_func(), e);
 
-     }
 
-     // Fall through
 
-   case RESOLVED:
 
-     wasResolved = true;
 
-     // Fall through
 
-   case INSTALLED:
 
-     d->fwCtx->plugins->remove(d->location);
 
-     d->pluginActivator = 0;
 
-     if (d->pluginDir.exists())
 
-     {
 
-       if (!ctk::removeDirRecursively(d->pluginDir.absolutePath()))
 
-       {
 
-         // Plugin dir is not deleted completely, make sure we mark
 
-         // it as uninstalled for next framework restart
 
-         if (d->archive)
 
-         {
 
-           try
 
-           {
 
-             d->archive->setStartLevel(-2); // Mark as uninstalled
 
-           }
 
-           catch (const std::exception& e)
 
-           {
 
-             // NYI! Generate FrameworkError if dir still exists!?
 
-             qDebug() << "Failed to mark plugin" <<  d->id
 
-                      << "as uninstalled," << d->pluginDir.absoluteFilePath()
 
-                      << "must be deleted manually:" << e.what();
 
-           }
 
-         }
 
-       }
 
-       d->pluginDir.setFile("");
 
-     }
 
-     if (d->archive)
 
-     {
 
-       d->archive->purge();
 
-     }
 
-     // id, location and headers survive after uninstall.
 
-     // TODO: UNRESOLVED must be sent out during installed state
 
-     // This needs to be reviewed. See OSGi bug #1374
 
-     d->state = INSTALLED;
 
-     d->modified();
 
-     // Broadcast events
 
-     if (wasResolved)
 
-     {
 
-       d->fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::UNRESOLVED, d->q_ptr));
 
-     }
 
-     d->state = UNINSTALLED;
 
-     d->fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::UNINSTALLED, d->q_ptr));
 
-     break;
 
-   }
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkPluginContext* ctkPlugin::getPluginContext() const
 
- {
 
-   //TODO security checks
 
-   Q_D(const ctkPlugin);
 
-   return d->pluginContext.data();
 
- }
 
- //----------------------------------------------------------------------------
 
- long ctkPlugin::getPluginId() const
 
- {
 
-   Q_D(const ctkPlugin);
 
-   return d->id;
 
- }
 
- //----------------------------------------------------------------------------
 
- QString ctkPlugin::getLocation() const
 
- {
 
-   //TODO security
 
-   Q_D(const ctkPlugin);
 
-   return d->location;
 
- }
 
- //----------------------------------------------------------------------------
 
- QHash<QString, QString> ctkPlugin::getHeaders()
 
- {
 
-   //TODO security
 
-   Q_D(ctkPlugin);
 
-   if (d->cachedRawHeaders.empty())
 
-   {
 
-     d->cachedRawHeaders = d->archive->getUnlocalizedAttributes();
 
-   }
 
-   if (d->state == UNINSTALLED)
 
-   {
 
-     return d->cachedHeaders;
 
-   }
 
-   //TODO use the embedded .qm files to localize header values
 
-   return d->cachedRawHeaders;
 
- }
 
- //----------------------------------------------------------------------------
 
- QString ctkPlugin::getSymbolicName() const
 
- {
 
-   Q_D(const ctkPlugin);
 
-   return d->symbolicName;
 
- }
 
- //----------------------------------------------------------------------------
 
- QStringList ctkPlugin::getResourceList(const QString& path) const
 
- {
 
-   Q_D(const ctkPlugin);
 
-   return d->archive->findResourcesPath(path);
 
- }
 
- //----------------------------------------------------------------------------
 
- QStringList ctkPlugin::findResources(const QString& path,
 
-                                      const QString& pattern, bool recurse) const
 
- {
 
-   Q_D(const ctkPlugin);
 
-   return d->findResourceEntries(path, pattern, recurse);
 
- }
 
- //----------------------------------------------------------------------------
 
- QByteArray ctkPlugin::getResource(const QString& path) const
 
- {
 
-   Q_D(const ctkPlugin);
 
-   return d->archive->getPluginResource(path);
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkPluginLocalization ctkPlugin::getPluginLocalization(
 
-   const QLocale& locale, const QString& base) const
 
- {
 
-   Q_D(const ctkPlugin);
 
-   // There are five searching candidates possible:
 
-   // base +
 
-   //    "_" + language1 + "_" + country1 + ".qm"
 
-   // or "_" + language1 + ".qm"
 
-   // or "_" + language2 + "_" + country2 + ".qm"
 
-   // or "_" + language2 + ".qm"
 
-   // or ""  + ".qm"
 
-   //
 
-   // Where language1[_country1[_variation1]] is the requested locale,
 
-   // and language2[_country2[_variation2]] is the default locale.
 
-   QChar localeSep('_');
 
-   QChar baseSep('_');
 
-   QStringList searchCandidates;
 
-   QStringList localeParts = locale.name().split(localeSep);
 
-   QStringList defaultParts = QLocale().name().split(localeSep);
 
-   searchCandidates << baseSep + localeParts[0] + localeSep + localeParts[1];
 
-   searchCandidates << baseSep + localeParts[0];
 
-   searchCandidates << baseSep + defaultParts[0] + localeSep + defaultParts[1];
 
-   searchCandidates << baseSep + defaultParts[0];
 
-   searchCandidates << "";
 
-   QString localizationPath = base.left(base.lastIndexOf('/'));
 
-   QStringList resourceList = this->getResourceList(localizationPath);
 
-   foreach(QString resource, resourceList)
 
-   {
 
-     foreach(QString candidate, searchCandidates)
 
-     {
 
-       if (resource.endsWith(candidate + ".qm"))
 
-       {
 
-         return ctkPluginLocalization(localizationPath + '/' + resource, locale, d->q_ptr);
 
-       }
 
-     }
 
-   }
 
-   return ctkPluginLocalization();
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkVersion ctkPlugin::getVersion() const
 
- {
 
-   Q_D(const ctkPlugin);
 
-   return d->version;
 
- }
 
- //----------------------------------------------------------------------------
 
- QDebug operator<<(QDebug debug, ctkPlugin::State state)
 
- {
 
-   switch (state)
 
-   {
 
-   case ctkPlugin::UNINSTALLED:
 
-     return debug << "UNINSTALLED";
 
-   case ctkPlugin::INSTALLED:
 
-     return debug << "INSTALLED";
 
-   case ctkPlugin::RESOLVED:
 
-     return debug << "RESOLVED";
 
-   case ctkPlugin::STARTING:
 
-     return debug << "STARTING";
 
-   case ctkPlugin::STOPPING:
 
-     return debug << "STOPPING";
 
-   case ctkPlugin::ACTIVE:
 
-     return debug << "ACTIVE";
 
-   default:
 
-     return debug << "unknown";
 
-   }
 
- }
 
- //----------------------------------------------------------------------------
 
- QDebug operator<<(QDebug debug, const ctkPlugin& plugin)
 
- {
 
-   debug.nospace() << "ctkPlugin[" << "id=" << plugin.getPluginId() <<
 
-       ", state=" << plugin.getState() << ", loc=" << plugin.getLocation() <<
 
-       ", symName=" << plugin.getSymbolicName() << "]";
 
-   return debug.maybeSpace();
 
- }
 
- //----------------------------------------------------------------------------
 
- QDebug operator<<(QDebug debug, ctkPlugin const * plugin)
 
- {
 
-   return operator<<(debug, *plugin);
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkLogStream& operator<<(ctkLogStream& stream, ctkPlugin const * plugin)
 
- {
 
-   stream << plugin->getSymbolicName();
 
-   return stream;
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkLogStream& operator<<(ctkLogStream& stream, const QSharedPointer<ctkPlugin>& plugin)
 
- {
 
-   return operator<<(stream, plugin.data());
 
- }
 
 
  |