Example #1
0
//----------------------------------------------------------------------------
void ctkPluginPrivate::finalizeActivation()
{
  Locker sync(&operationLock);

  // 4: Resolve plugin (if needed)
  switch (getUpdatedState_unlocked())
  {
  case ctkPlugin::INSTALLED:
    Q_ASSERT_X(resolveFailException != 0, Q_FUNC_INFO, "no resolveFailException");
    throw ctkPluginException(*resolveFailException);
  case ctkPlugin::STARTING:
    if (operation.fetchAndAddOrdered(0) == ACTIVATING) return; // finalization already in progress.
    // Lazy activation; fall through to RESOLVED.
  case ctkPlugin::RESOLVED:
  {
    //6:
    state = ctkPlugin::STARTING;
    operation.fetchAndStoreOrdered(ACTIVATING);
    if (fwCtx->debug.lazy_activation)
    {
      qDebug() << "activating #" << this->id;
    }
    //7:
    if (!pluginContext)
    {
      pluginContext.reset(new ctkPluginContext(this));
    }
    // start dependencies
    startDependencies();
    //TODO plugin threading
    //ctkRuntimeException* e = bundleThread().callStart0(this);
    ctkRuntimeException* e = start0();
    operation.fetchAndStoreOrdered(IDLE);
    operationLock.wakeAll();
    if (e)
    {
      ctkRuntimeException re(*e);
      delete e;
      throw re;
    }
    break;
  }
  case ctkPlugin::ACTIVE:
    break;
  case ctkPlugin::STOPPING:
    // This happens if start is called from inside the ctkPluginActivator::stop method.
    // Don't allow it.
    throw ctkPluginException("start called from ctkPluginActivator::stop",
                             ctkPluginException::ACTIVATOR_ERROR);
  case ctkPlugin::UNINSTALLED:
    throw ctkIllegalStateException("ctkPlugin is in UNINSTALLED state");
  }
}
Example #2
0
//----------------------------------------------------------------------------
void ctkPluginPrivate::waitOnOperation(LockObject* lock, const QString& src, bool longWait)
{
  if (operation.fetchAndAddOrdered(0) != IDLE)
  {
    qint64 left = longWait ? 20000 : 500;
    QDateTime waitUntil = QDateTime::currentDateTime().addMSecs(left);
    do
    {
      lock->wait(left);
      if (operation.fetchAndAddOrdered(0) == IDLE)
      {
        return;
      }
      // TODO use Qt 4.7 QDateTime::msecsTo() API
      //left = QDateTime::currentDateTime().msecsTo(waitUntil);
      left = ctk::msecsTo(QDateTime::currentDateTime(), waitUntil);
    } while (left > 0);

    QString op;
    switch (operation.fetchAndAddOrdered(0))
    {
    case IDLE:
      // Should not happen!
      return;
    case ACTIVATING:
      op = "start";
      break;
    case DEACTIVATING:
      op = "stop";
      break;
    case RESOLVING:
      op = "resolve";
      break;
    case UNINSTALLING:
      op = "uninstall";
      break;
    case UNRESOLVING:
      op = "unresolve";
      break;
    case UPDATING:
      op = "update";
      break;
    default:
      op = "unknown operation";
      break;
    }
    throw ctkPluginException(src + " called during " + op + " of plug-in",
                             ctkPluginException::STATECHANGE_ERROR);
  }
}
Example #3
0
  void ctkPluginFrameworkContext::checkRequirePlugin(ctkPluginPrivate *plugin)
  {
    if (!plugin->require.isEmpty())
    {
      qDebug() << "checkRequirePlugin: check requiring plugin" << plugin->id;

      QListIterator<ctkRequirePlugin*> i(plugin->require);
      while (i.hasNext())
      {
        ctkRequirePlugin* pr = i.next();
        QList<ctkPlugin*> pl = plugins->getPlugins(pr->name, pr->pluginRange);
        ctkPluginPrivate* ok = 0;
        for (QListIterator<ctkPlugin*> pci(pl); pci.hasNext() && ok == 0; )
        {
          ctkPluginPrivate* p2 = pci.next()->d_func();
          if (tempResolved.contains(p2))
          {
            ok = p2;
          }
          else if (ctkPluginPrivate::RESOLVED_FLAGS & p2->state)
          {
            ok = p2;
          }
          else if (p2->state == ctkPlugin::INSTALLED) {
            QSet<ctkPluginPrivate*> oldTempResolved = tempResolved;
            tempResolved.insert(p2);
            checkRequirePlugin(p2);
            tempResolved = oldTempResolved;
            ok = p2;
          }
        }

        if (!ok && pr->resolution == ctkPluginConstants::RESOLUTION_MANDATORY)
        {
          tempResolved.clear();
          qDebug() << "checkRequirePlugin: failed to satisfy:" << pr->name;
          throw ctkPluginException(QString("Failed to resolve required plugin: %1").arg(pr->name));
        }
      }
    }


}
Example #4
0
//----------------------------------------------------------------------------
void ctkPluginFramework::uninstall()
{
  throw ctkPluginException("uninstall of System plugin is not allowed",
                           ctkPluginException::INVALID_OPERATION);
}
Example #5
0
//----------------------------------------------------------------------------
void ctkPluginPrivate::update0(const QUrl& updateLocation, bool wasActive)
{
  const bool wasResolved = state == ctkPlugin::RESOLVED;
  const int oldStartLevel = getStartLevel();
  QSharedPointer<ctkPluginArchive> newArchive;

  operation.fetchAndStoreOrdered(UPDATING);
  try
  {
    // New plugin as stream supplied?
    QUrl updateUrl(updateLocation);
    if (updateUrl.isEmpty())
    {
      // Try Plugin-UpdateLocation
      QString update = archive != 0 ? archive->getAttribute(ctkPluginConstants::PLUGIN_UPDATELOCATION) : QString();
      if (update.isEmpty())
      {
        // Take original location
        updateUrl = location;
      }
    }

    if(updateUrl.scheme() != "file")
    {
      QString msg = "Unsupported update URL:";
      msg += updateUrl.toString();
      throw ctkPluginException(msg);
    }

    newArchive = fwCtx->storage->updatePluginArchive(archive, updateUrl, updateUrl.toLocalFile());
    //checkCertificates(newArchive);
    checkManifestHeaders();
    newArchive->setStartLevel(oldStartLevel);
    fwCtx->storage->replacePluginArchive(archive, newArchive);
  }
  catch (const std::exception& e)
  {
    if (!newArchive.isNull())
    {
      newArchive->purge();
    }
    operation.fetchAndStoreOrdered(IDLE);
    if (wasActive)
    {
      try
      {
        this->q_func().data()->start();
      }
      catch (const ctkPluginException& pe)
      {
        fwCtx->listeners.frameworkError(this->q_func(), pe);
      }
    }
    try
    {
      const ctkPluginException& pe = dynamic_cast<const ctkPluginException&>(e);
      throw pe;
    }
    catch (std::bad_cast)
    {
      throw ctkPluginException(QString("Failed to get update plugin: ") + e.what(),
                               ctkPluginException::UNSPECIFIED);
    }
  }

  bool purgeOld = false;
  // TODO: check if dependent plug-ins are started. If not, set purgeOld to true.

  // Activate new plug-in
  QSharedPointer<ctkPluginArchive> oldArchive = archive;
  archive = newArchive;
  cachedRawHeaders.clear();
  state = ctkPlugin::INSTALLED;

  // Purge old archive
  if (purgeOld)
  {
    //secure.purge(this, oldProtectionDomain);
    if (oldArchive != 0)
    {
      oldArchive->purge();
    }
  }

  // Broadcast events
  if (wasResolved)
  {
    // TODO: use plugin threading
    //bundleThread().bundleChanged(new BundleEvent(BundleEvent.UNRESOLVED, this));
    fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::UNRESOLVED, this->q_func()));
  }
  //bundleThread().bundleChanged(new BundleEvent(BundleEvent.UPDATED, this));
  fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::UPDATED, this->q_func()));
  operation.fetchAndStoreOrdered(IDLE);

   // Restart plugin previously stopped in the operation
   if (wasActive)
   {
     try
     {
       this->q_func().data()->start();
     }
     catch (const ctkPluginException& pe)
     {
       fwCtx->listeners.frameworkError(this->q_func(), pe);
     }
   }
 }
Example #6
0
//----------------------------------------------------------------------------
QSharedPointer<ctkPlugin> ctkPlugins::install(const QUrl& location, QIODevice* in)
{
  if (!fwCtx)
  { // This ctkPlugins instance has been closed!
    throw std::logic_error("ctkPlugins::install(location, inputStream) called on closed plugins object.");
  }

  {
    QWriteLocker lock(&pluginsLock);

    QHash<QString, QSharedPointer<ctkPlugin> >::const_iterator it = plugins.find(location.toString());
    if (it != plugins.end())
    {
      return it.value();
    }

    // install new plugin
    ctkPluginArchive* pa = 0;
    QString localPluginPath;
    try
    {
      if (!in)
      {
        // extract the input stream from the given location


        //          //TODO Support for http proxy authentication
        //          //TODO put in update as well
        //          String auth = fwCtx.props.getProperty("http.proxyAuth");
        //          if (auth != null && !"".equals(auth)) {
        //            if ("http".equals(url.getProtocol()) ||
        //                "https".equals(url.getProtocol())) {
        //              String base64 = Util.base64Encode(auth);
        //              conn.setRequestProperty("Proxy-Authorization",
        //                                      "Basic " + base64);
        //            }
        //          }
        //          // Support for http basic authentication
        //          String basicAuth = fwCtx.props.getProperty("http.basicAuth");
        //          if (basicAuth != null && !"".equals(basicAuth)) {
        //            if ("http".equals(url.getProtocol()) ||
        //                "https".equals(url.getProtocol())) {
        //              String base64 = Util.base64Encode(basicAuth);
        //              conn.setRequestProperty("Authorization",
        //                                      "Basic " +base64);
        //            }
        //          }

        if (location.scheme() != "file")
        {
          throw std::runtime_error(std::string("Unsupported url scheme: ") + qPrintable(location.scheme()));
        }
        else
        {
          qDebug() << QString("Trying to install file:") << location.path();
          localPluginPath = location.toLocalFile();
        }
      }
      else
      {
        //TODO copy the QIODevice to a local cache
      }

      pa = fwCtx->storage->insertPlugin(location, localPluginPath);

      QSharedPointer<ctkPlugin> res(new ctkPlugin());
      res->init(res, fwCtx, pa);
      plugins.insert(location.toString(), res);

      fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::INSTALLED, res));

      return res;
    }
    catch (const std::exception& e)
    {
      if (pa)
      {
        pa->purge();
      }
      //      if (dynamic_cast<const SecurityException&>(e)) {
      //        throw;
      //      }
      //      else
      //      {
      throw ctkPluginException(QString("Failed to install plugin: ") + QString(e.what()),
                               ctkPluginException::UNSPECIFIED, &e);
      //      }
    }
  }

}