Преглед на файлове

ENH: PluginFramework: added plugin stop code and plugin event support

Sascha Zelzer преди 15 години
родител
ревизия
dba89fce72

+ 59 - 1
Libs/PluginFramework/ctkPlugin.cpp

@@ -111,7 +111,65 @@
 
   void ctkPlugin::stop(const StopOptions& options)
   {
-    //TODO Plugin::stop()
+    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 (d->state != UNINSTALLED)
+    {
+      d->fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPED, this));
+    }
+    if (savedException)
+    {
+      if (const ctkPluginException* pluginExc = dynamic_cast<const ctkPluginException*>(savedException))
+      {
+        throw pluginExc;
+      }
+      else
+      {
+        throw dynamic_cast<const std::logic_error*>(savedException);
+      }
+    }
   }
 
   ctkPluginContext* ctkPlugin::getPluginContext() const

+ 83 - 85
Libs/PluginFramework/ctkPluginArchive.cpp

@@ -28,107 +28,105 @@
 #include <QFile>
 
 
-  const QString ctkPluginArchive::AUTOSTART_SETTING_STOPPED("stopped");
-  const QString ctkPluginArchive::AUTOSTART_SETTING_EAGER("eager");
-  const QString ctkPluginArchive::AUTOSTART_SETTING_ACTIVATION_POLICY("activation_policy");
-
-  ctkPluginArchive::ctkPluginArchive(ctkPluginStorage* pluginStorage,
-                const QUrl& pluginLocation, const QString& localPluginPath,
-                int pluginId)
-                  : autostartSetting(-1), id(pluginId), lastModified(0),
-                  location(pluginLocation), localPluginPath(localPluginPath),
-                  storage(pluginStorage)
+const QString ctkPluginArchive::AUTOSTART_SETTING_STOPPED("stopped");
+const QString ctkPluginArchive::AUTOSTART_SETTING_EAGER("eager");
+const QString ctkPluginArchive::AUTOSTART_SETTING_ACTIVATION_POLICY("activation_policy");
+
+ctkPluginArchive::ctkPluginArchive(ctkPluginStorage* pluginStorage,
+                                   const QUrl& pluginLocation, const QString& localPluginPath,
+                                   int pluginId)
+                                     : autostartSetting(-1), id(pluginId), lastModified(0),
+                                     location(pluginLocation), localPluginPath(localPluginPath),
+                                     storage(pluginStorage)
+{
+  QByteArray manifestResource = this->getPluginResource("META-INF/MANIFEST.MF");
+  if (manifestResource.isEmpty())
   {
-    QByteArray manifestResource = this->getPluginResource("META-INF/MANIFEST.MF");
-    if (manifestResource.isEmpty())
-    {
-      throw ctkPluginException(QString("ctkPlugin has no MANIFEST.MF resource, location=") + pluginLocation.toString());
-    }
-    manifest.read(manifestResource);
+    throw ctkPluginException(QString("ctkPlugin has no MANIFEST.MF resource, location=") + pluginLocation.toString());
   }
+  manifest.read(manifestResource);
+}
 
-  QString ctkPluginArchive::getAttribute(const QString& key) const
-  {
-    return manifest.getAttribute(key);
-  }
+QString ctkPluginArchive::getAttribute(const QString& key) const
+{
+  return manifest.getAttribute(key);
+}
 
-  QHash<QString,QString> ctkPluginArchive::getUnlocalizedAttributes() const
-  {
-    return manifest.getMainAttributes();
-  }
+QHash<QString,QString> ctkPluginArchive::getUnlocalizedAttributes() const
+{
+  return manifest.getMainAttributes();
+}
 
-  int ctkPluginArchive::getPluginId() const
-  {
-    return id;
-  }
+int ctkPluginArchive::getPluginId() const
+{
+  return id;
+}
 
-  QUrl ctkPluginArchive::getPluginLocation() const
-  {
-    return location;
-  }
+QUrl ctkPluginArchive::getPluginLocation() const
+{
+  return location;
+}
 
-  QString ctkPluginArchive::getLibLocation() const
-  {
-    return localPluginPath;
-  }
+QString ctkPluginArchive::getLibLocation() const
+{
+  return localPluginPath;
+}
 
-  QByteArray ctkPluginArchive::getPluginResource(const QString& component) const
-  {
-    return storage->getPluginResource(getPluginId(), component);
-  }
+QByteArray ctkPluginArchive::getPluginResource(const QString& component) const
+{
+  return storage->getPluginResource(getPluginId(), component);
+}
 
-  QStringList ctkPluginArchive::findResourcesPath(const QString& path) const
-  {
-    return storage->findResourcesPath(getPluginId(), path);
-  }
+QStringList ctkPluginArchive::findResourcesPath(const QString& path) const
+{
+  return storage->findResourcesPath(getPluginId(), path);
+}
 
-  int ctkPluginArchive::getStartLevel() const
-  {
-    //TODO
-    return 0;
-  }
+int ctkPluginArchive::getStartLevel() const
+{
+  //TODO
+  return 0;
+}
 
-  void ctkPluginArchive::setStartLevel(int level)
-  {
-    Q_UNUSED(level)
-    //TODO
-//    if (startLevel != level)
-//    {
-//      startLevel = level;
-//      putContent(...);
-//    }
-  }
+void ctkPluginArchive::setStartLevel(int level)
+{
+  Q_UNUSED(level)
+  //TODO
+  //    if (startLevel != level)
+  //    {
+  //      startLevel = level;
+  //      putContent(...);
+  //    }
+}
 
-  qtimestamp ctkPluginArchive::getLastModified() const
-  {
-    return lastModified;
-  }
+qtimestamp ctkPluginArchive::getLastModified() const
+{
+  return lastModified;
+}
 
-  void ctkPluginArchive::setLastModified(qtimestamp clockticks)
-  {
-    lastModified = clockticks;
-    //TDOO
-    //putContent(...)
-  }
+void ctkPluginArchive::setLastModified(qtimestamp clockticks)
+{
+  lastModified = clockticks;
+  //TDOO
+  //putContent(...)
+}
 
-  int ctkPluginArchive::getAutostartSetting() const
-  {
-    return autostartSetting;
-  }
+int ctkPluginArchive::getAutostartSetting() const
+{
+  return autostartSetting;
+}
 
-  void ctkPluginArchive::setAutostartSetting(int setting)
+void ctkPluginArchive::setAutostartSetting(int setting)
+{
+  if (autostartSetting != setting)
   {
-    if (autostartSetting != setting)
-    {
-      autostartSetting = setting;
-      //TODO
-      //putContent(...)
-    }
+    autostartSetting = setting;
+    //TODO
+    //putContent(...)
   }
+}
 
-  void ctkPluginArchive::purge()
-  {
-    storage->removeArchive(this);
-
-
+void ctkPluginArchive::purge()
+{
+  storage->removeArchive(this);
 }

+ 91 - 102
Libs/PluginFramework/ctkPluginContext.cpp

@@ -20,6 +20,7 @@
 =============================================================================*/
 
 #include "ctkPluginContext.h"
+#include "ctkPluginContext_p.h"
 
 #include "ctkPluginPrivate_p.h"
 #include "ctkPluginFrameworkContext_p.h"
@@ -30,110 +31,98 @@
 #include <stdexcept>
 
 
-  class ctkPluginContextPrivate
-  {
+ctkPluginContextPrivate::ctkPluginContextPrivate(ctkPluginPrivate* plugin)
+  : plugin(plugin)
+{}
 
-  public:
-
-    ctkPluginPrivate* plugin;
-
-    ctkPluginContextPrivate(ctkPluginPrivate* plugin)
-      : plugin(plugin)
-    {}
-
-    /**
-     * Check that the plugin is still valid.
-     */
-    void isPluginContextValid() const
-    {
-      if (!plugin) {
-        throw std::logic_error("This plugin context is no longer valid");
-      }
-    }
-
-    void invalidate()
-    {
-      plugin = 0;
-    }
-
-  };
-
-
-  ctkPluginContext::ctkPluginContext(ctkPluginPrivate* plugin)
-  : d_ptr(new ctkPluginContextPrivate(plugin))
-  {}
-
-  ctkPluginContext::~ctkPluginContext()
-  {
-    Q_D(ctkPluginContext);
-    delete d;
+void ctkPluginContextPrivate::isPluginContextValid() const
+{
+  if (!plugin) {
+    throw std::logic_error("This plugin context is no longer valid");
   }
+}
 
-  ctkPlugin* ctkPluginContext::getPlugin() const
-  {
-    Q_D(const ctkPluginContext);
-    d->isPluginContextValid();
-    return d->plugin->q_func();
-  }
+void ctkPluginContextPrivate::invalidate()
+{
+  plugin = 0;
+}
 
-  ctkPlugin* ctkPluginContext::getPlugin(long id) const
-  {
-    Q_D(const ctkPluginContext);
-    return d->plugin->fwCtx->plugins->getPlugin(id);
-  }
 
-  QList<ctkPlugin*> ctkPluginContext::getPlugins() const
-  {
-    Q_D(const ctkPluginContext);
-    d->isPluginContextValid();
-    return d->plugin->fwCtx->plugins->getPlugins();
-  }
-
-  ctkPlugin* ctkPluginContext::installPlugin(const QUrl& location, QIODevice* in)
-  {
-    Q_D(ctkPluginContext);
-    d->isPluginContextValid();
-    return d->plugin->fwCtx->plugins->install(location, in);
-  }
-
-  ctkServiceRegistration* ctkPluginContext::registerService(const QStringList& clazzes, QObject* service, const ServiceProperties& properties)
-  {
-    Q_D(ctkPluginContext);
-    d->isPluginContextValid();
-    return d->plugin->fwCtx->services.registerService(d->plugin, clazzes, service, properties);
-  }
-
-  QList<ctkServiceReference> ctkPluginContext::getServiceReferences(const QString& clazz, const QString& filter)
-  {
-    Q_D(ctkPluginContext);
-    d->isPluginContextValid();
-    return d->plugin->fwCtx->services.get(clazz, filter);
-  }
-
-  ctkServiceReference ctkPluginContext::getServiceReference(const QString& clazz)
-  {
-    Q_D(ctkPluginContext);
-    d->isPluginContextValid();
-    return d->plugin->fwCtx->services.get(d->plugin, clazz);
-  }
-
-  QObject* ctkPluginContext::getService(ctkServiceReference reference)
-  {
-    Q_D(ctkPluginContext);
-    d->isPluginContextValid();
-    return reference.d_func()->getService(d->plugin->q_func());
-  }
-
-  bool ctkPluginContext::connectPluginListener(const QObject* receiver, const char* method,
-                                            Qt::ConnectionType type)
-  {
-    Q_D(ctkPluginContext);
-    // TODO check permissions for a direct connection
-    return receiver->connect(&(d->plugin->fwCtx->listeners), SIGNAL(pluginChanged(ctkPluginEvent)), method, type);
-  }
-
-  bool ctkPluginContext::connectFrameworkListener(const QObject* receiver, const char* method, Qt::ConnectionType type)
-  {
-    Q_D(ctkPluginContext);
-    return receiver->connect(&(d->plugin->fwCtx->listeners), SIGNAL(frameworkEvent(ctkPluginFrameworkEvent)), method, type);
-  }
+ctkPluginContext::ctkPluginContext(ctkPluginPrivate* plugin)
+  : d_ptr(new ctkPluginContextPrivate(plugin))
+{}
+
+ctkPluginContext::~ctkPluginContext()
+{
+  Q_D(ctkPluginContext);
+  delete d;
+}
+
+ctkPlugin* ctkPluginContext::getPlugin() const
+{
+  Q_D(const ctkPluginContext);
+  d->isPluginContextValid();
+  return d->plugin->q_func();
+}
+
+ctkPlugin* ctkPluginContext::getPlugin(long id) const
+{
+  Q_D(const ctkPluginContext);
+  return d->plugin->fwCtx->plugins->getPlugin(id);
+}
+
+QList<ctkPlugin*> ctkPluginContext::getPlugins() const
+{
+  Q_D(const ctkPluginContext);
+  d->isPluginContextValid();
+  return d->plugin->fwCtx->plugins->getPlugins();
+}
+
+ctkPlugin* ctkPluginContext::installPlugin(const QUrl& location, QIODevice* in)
+{
+  Q_D(ctkPluginContext);
+  d->isPluginContextValid();
+  return d->plugin->fwCtx->plugins->install(location, in);
+}
+
+ctkServiceRegistration* ctkPluginContext::registerService(const QStringList& clazzes, QObject* service, const ServiceProperties& properties)
+{
+  Q_D(ctkPluginContext);
+  d->isPluginContextValid();
+  return d->plugin->fwCtx->services.registerService(d->plugin, clazzes, service, properties);
+}
+
+QList<ctkServiceReference> ctkPluginContext::getServiceReferences(const QString& clazz, const QString& filter)
+{
+  Q_D(ctkPluginContext);
+  d->isPluginContextValid();
+  return d->plugin->fwCtx->services.get(clazz, filter);
+}
+
+ctkServiceReference ctkPluginContext::getServiceReference(const QString& clazz)
+{
+  Q_D(ctkPluginContext);
+  d->isPluginContextValid();
+  return d->plugin->fwCtx->services.get(d->plugin, clazz);
+}
+
+QObject* ctkPluginContext::getService(ctkServiceReference reference)
+{
+  Q_D(ctkPluginContext);
+  d->isPluginContextValid();
+  return reference.d_func()->getService(d->plugin->q_func());
+}
+
+bool ctkPluginContext::connectPluginListener(const QObject* receiver, const char* method,
+                                             Qt::ConnectionType type)
+{
+  Q_D(ctkPluginContext);
+  // TODO check permissions for a direct connection
+  return receiver->connect(&(d->plugin->fwCtx->listeners), SIGNAL(pluginChanged(ctkPluginEvent)), method, type);
+}
+
+bool ctkPluginContext::connectFrameworkListener(const QObject* receiver, const char* method, Qt::ConnectionType type)
+{
+  Q_D(ctkPluginContext);
+  return receiver->connect(&(d->plugin->fwCtx->listeners), SIGNAL(frameworkEvent(ctkPluginFrameworkEvent)), method, type);
+}

+ 45 - 0
Libs/PluginFramework/ctkPluginContext_p.h

@@ -0,0 +1,45 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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.
+
+=============================================================================*/
+
+#ifndef CTKPLUGINCONTEXTPRIVATE_H
+#define CTKPLUGINCONTEXTPRIVATE_H
+
+class ctkPluginPrivate;
+
+class ctkPluginContextPrivate
+{
+
+public:
+
+  ctkPluginPrivate* plugin;
+
+  ctkPluginContextPrivate(ctkPluginPrivate* plugin);
+
+  /**
+   * Check that the plugin is still valid.
+   */
+  void isPluginContextValid() const;
+
+  void invalidate();
+
+};
+
+#endif // CTKPLUGINCONTEXTPRIVATE_H

+ 19 - 16
Libs/PluginFramework/ctkPluginEvent.cpp

@@ -21,27 +21,30 @@
 
 #include "ctkPluginEvent.h"
 
+ctkPluginEvent::ctkPluginEvent()
+  : d(0)
+{
 
+}
 
-  ctkPluginEvent::ctkPluginEvent(Type type, ctkPlugin* plugin)
-    : d(new ctkPluginEventData(type, plugin))
-  {
-
-  }
+ctkPluginEvent::ctkPluginEvent(Type type, ctkPlugin* plugin)
+  : d(new ctkPluginEventData(type, plugin))
+{
 
-  ctkPluginEvent::ctkPluginEvent(const ctkPluginEvent& other)
-    : QObject(), d(other.d)
-  {
+}
 
-  }
+ctkPluginEvent::ctkPluginEvent(const ctkPluginEvent& other)
+  : QObject(), d(other.d)
+{
 
-  ctkPlugin* ctkPluginEvent::getPlugin() const
-  {
-    return d->plugin;
-  }
+}
 
-  ctkPluginEvent::Type ctkPluginEvent::getType() const
-  {
-    return d->type;
+ctkPlugin* ctkPluginEvent::getPlugin() const
+{
+  return d->plugin;
+}
 
+ctkPluginEvent::Type ctkPluginEvent::getType() const
+{
+  return d->type;
 }

+ 90 - 85
Libs/PluginFramework/ctkPluginEvent.h

@@ -28,103 +28,108 @@
 #include "CTKPluginFrameworkExport.h"
 
 
-  class ctkPlugin;
-  class ctkPluginEventData;
+class ctkPlugin;
+class ctkPluginEventData;
+
+/**
+ * An event from the Framework describing a plugin lifecycle change.
+ * <p>
+ * <code>ctkPluginEvent</code> objects are delivered to slots connected
+ * to ctkPluginContext::pluginChanged() or to registerd event handlers
+ * for the topic "org.commontk/framework/pluginChanged"
+ * when a change occurs in a plugins's lifecycle. A type code is used to identify
+ * the event type for future extendability.
+ *
+ * @see ctkPluginContext#connectPluginListener
+ * @see ctkEventBus
+ */
+class CTK_PLUGINFW_EXPORT ctkPluginEvent : public QObject
+{
+  Q_OBJECT
+  Q_PROPERTY(Type type READ getType CONSTANT)
+  Q_PROPERTY(ctkPlugin* plugin READ getPlugin CONSTANT)
+  Q_ENUMS(Type)
+
+  QSharedDataPointer<ctkPluginEventData> d;
+
+public:
+
+  enum Type {
+    INSTALLED,
+    STARTED,
+    STOPPED,
+    UPDATED,
+    UNINSTALLED,
+    RESOLVED,
+    UNRESOLVED,
+    STARTING,
+    STOPPING,
+    LAZY_ACTIVATION
+  };
 
   /**
-   * An event from the Framework describing a plugin lifecycle change.
-   * <p>
-   * <code>ctkPluginEvent</code> objects are delivered to slots connected
-   * to ctkPluginContext::pluginChanged() or to registerd event handlers
-   * for the topic "org.commontk/framework/pluginChanged"
-   * when a change occurs in a plugins's lifecycle. A type code is used to identify
-   * the event type for future extendability.
+   * Default constructor for use with the Qt meta object system.
+   */
+  ctkPluginEvent();
+
+  /**
+   * Creates a plugin event of the specified type.
    *
-   * @see ctkPluginContext#connectPluginListener
-   * @see ctkEventBus
+   * @param type The event type.
+   * @param plugin The plugin which had a lifecycle change.
    */
-  class CTK_PLUGINFW_EXPORT ctkPluginEvent : public QObject
-  {
-    Q_OBJECT
-    Q_PROPERTY(Type type READ getType CONSTANT)
-    Q_PROPERTY(ctkPlugin* plugin READ getPlugin CONSTANT)
-    Q_ENUMS(Type)
-
-    QSharedDataPointer<ctkPluginEventData> d;
-
-  public:
-
-    enum Type {
-      INSTALLED,
-      STARTED,
-      STOPPED,
-      UPDATED,
-      UNINSTALLED,
-      RESOLVED,
-      UNRESOLVED,
-      STARTING,
-      STOPPING,
-      LAZY_ACTIVATION
-    };
-
-    /**
-     * Creates a plugin event of the specified type.
-     *
-     * @param type The event type.
-     * @param plugin The plugin which had a lifecycle change.
-     */
-    ctkPluginEvent(Type type, ctkPlugin* plugin);
-
-    ctkPluginEvent(const ctkPluginEvent& other);
-
-    /**
-     * Returns the plugin which had a lifecycle change.
-     *
-     * @return The plugin that had a change occur in its lifecycle.
-     */
-    ctkPlugin* getPlugin() const;
-
-    /**
-     * Returns the type of lifecyle event. The type values are:
-     * <ul>
-     * <li>{@link #INSTALLED}
-     * <li>{@link #RESOLVED}
-     * <li>{@link #LAZY_ACTIVATION}
-     * <li>{@link #STARTING}
-     * <li>{@link #STARTED}
-     * <li>{@link #STOPPING}
-     * <li>{@link #STOPPED}
-     * <li>{@link #UPDATED}
-     * <li>{@link #UNRESOLVED}
-     * <li>{@link #UNINSTALLED}
-     * </ul>
-     *
-     * @return The type of lifecycle event.
-     */
-    Type getType() const;
+  ctkPluginEvent(Type type, ctkPlugin* plugin);
 
+  ctkPluginEvent(const ctkPluginEvent& other);
 
-  };
+  /**
+   * Returns the plugin which had a lifecycle change.
+   *
+   * @return The plugin that had a change occur in its lifecycle.
+   */
+  ctkPlugin* getPlugin() const;
 
-  class ctkPluginEventData : public QSharedData
-  {
-  public:
+  /**
+   * Returns the type of lifecyle event. The type values are:
+   * <ul>
+   * <li>{@link #INSTALLED}
+   * <li>{@link #RESOLVED}
+   * <li>{@link #LAZY_ACTIVATION}
+   * <li>{@link #STARTING}
+   * <li>{@link #STARTED}
+   * <li>{@link #STOPPING}
+   * <li>{@link #STOPPED}
+   * <li>{@link #UPDATED}
+   * <li>{@link #UNRESOLVED}
+   * <li>{@link #UNINSTALLED}
+   * </ul>
+   *
+   * @return The type of lifecycle event.
+   */
+  Type getType() const;
 
-    ctkPluginEventData(ctkPluginEvent::Type type, ctkPlugin* plugin)
-      : type(type), plugin(plugin)
-    {
+};
 
-    }
 
-    ctkPluginEventData(const ctkPluginEventData& other)
-      : QSharedData(other), type(other.type), plugin(other.plugin)
-    {
+class ctkPluginEventData : public QSharedData
+{
+public:
 
-    }
+  ctkPluginEventData(ctkPluginEvent::Type type, ctkPlugin* plugin)
+    : type(type), plugin(plugin)
+  {
 
-    const ctkPluginEvent::Type type;
-    ctkPlugin* const plugin;
-  };
+  }
+
+  ctkPluginEventData(const ctkPluginEventData& other)
+    : QSharedData(other), type(other.type), plugin(other.plugin)
+  {
+
+  }
+
+  const ctkPluginEvent::Type type;
+  ctkPlugin* const plugin;
+};
 
 
 #endif // CTKPLUGINEVENT_H

+ 1 - 0
Libs/PluginFramework/ctkPluginFramework.cpp

@@ -33,6 +33,7 @@
     : ctkPlugin(*new ctkPluginFrameworkPrivate(*this, fw))
   {
     qRegisterMetaType<ctkPluginFrameworkEvent>("ctkPluginFrameworkEvent");
+    qRegisterMetaType<ctkPluginEvent>("ctkPluginEvent");
   }
 
   void ctkPluginFramework::init()

+ 261 - 175
Libs/PluginFramework/ctkPluginPrivate.cpp

@@ -27,242 +27,328 @@
 #include "ctkPluginFrameworkContext_p.h"
 #include "ctkPluginFrameworkUtil_p.h"
 #include "ctkPluginActivator.h"
+#include "ctkPluginContext_p.h"
 
+#include "ctkServiceReferencePrivate.h"
 
-  const ctkPlugin::States ctkPluginPrivate::RESOLVED_FLAGS = ctkPlugin::RESOLVED | ctkPlugin::STARTING | ctkPlugin::ACTIVE | ctkPlugin::STOPPING;
+const ctkPlugin::States ctkPluginPrivate::RESOLVED_FLAGS = ctkPlugin::RESOLVED | ctkPlugin::STARTING | ctkPlugin::ACTIVE | ctkPlugin::STOPPING;
 
 
-  ctkPluginPrivate::ctkPluginPrivate(
-      ctkPlugin& qq,
-      ctkPluginFrameworkContext* fw,
-      ctkPluginArchive* pa)
-    : q_ptr(&qq), fwCtx(fw), id(pa->getPluginId()),
-    location(pa->getPluginLocation().toString()), state(ctkPlugin::INSTALLED),
-    archive(pa), pluginContext(0), pluginActivator(0), pluginLoader(pa->getLibLocation()),
-    lastModified(0), eagerActivation(false), activating(false), deactivating(false)
+ctkPluginPrivate::ctkPluginPrivate(
+    ctkPlugin& qq,
+    ctkPluginFrameworkContext* fw,
+    ctkPluginArchive* pa)
+      : q_ptr(&qq), fwCtx(fw), id(pa->getPluginId()),
+      location(pa->getPluginLocation().toString()), state(ctkPlugin::INSTALLED),
+      archive(pa), pluginContext(0), pluginActivator(0), pluginLoader(pa->getLibLocation()),
+      lastModified(0), eagerActivation(false), activating(false), deactivating(false)
+{
+  //TODO
+  //checkCertificates(pa);
+
+  checkManifestHeaders();
+
+  // fill require list
+  QString requireString = archive->getAttribute(PluginConstants::REQUIRE_PLUGIN);
+  QList<QMap<QString, QStringList> > requireList = ctkPluginFrameworkUtil::parseEntries(PluginConstants::REQUIRE_PLUGIN,
+                                                                                        requireString, true, true, false);
+  QListIterator<QMap<QString, QStringList> > i(requireList);
+  while (i.hasNext())
   {
-    //TODO
-    //checkCertificates(pa);
+    const QMap<QString, QStringList>& e = i.next();
+    const QStringList& res = e.value(PluginConstants::RESOLUTION_DIRECTIVE);
+    const QStringList& version = e.value(PluginConstants::PLUGIN_VERSION_ATTRIBUTE);
+    ctkRequirePlugin* rp = new ctkRequirePlugin(this, e.value("$key").front(),
+                                                res.empty() ? QString() : res.front(),
+                                                version.empty() ? QString() : version.front());
+    require.push_back(rp);
+  }
+}
+
+ctkPluginPrivate::ctkPluginPrivate(ctkPlugin& qq,
+                                   ctkPluginFrameworkContext* fw,
+                                   long id, const QString& loc, const QString& sym, const ctkVersion& ver)
+                                     : q_ptr(&qq), fwCtx(fw), id(id), location(loc), symbolicName(sym), version(ver),
+                                     state(ctkPlugin::INSTALLED), archive(0), pluginContext(0),
+                                     pluginActivator(0), lastModified(0),
+                                     eagerActivation(false), activating(false), deactivating(false)
+{
+
+}
 
-    checkManifestHeaders();
+ctkPluginPrivate::~ctkPluginPrivate()
+{
+  qDeleteAll(require);
+}
+
+ctkPlugin::State ctkPluginPrivate::getUpdatedState()
+{
+  if (state & ctkPlugin::INSTALLED)
+  {
+    try
+    {
+      if (state == ctkPlugin::INSTALLED)
+      {
+        fwCtx->resolvePlugin(this);
+        state = ctkPlugin::RESOLVED;
+        fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::RESOLVED, this->q_func()));
+      }
 
-    // fill require list
-    QString requireString = archive->getAttribute(PluginConstants::REQUIRE_PLUGIN);
-    QList<QMap<QString, QStringList> > requireList = ctkPluginFrameworkUtil::parseEntries(PluginConstants::REQUIRE_PLUGIN,
-                                                                         requireString, true, true, false);
-    QListIterator<QMap<QString, QStringList> > i(requireList);
-    while (i.hasNext())
+    }
+    catch (const ctkPluginException& pe)
     {
-      const QMap<QString, QStringList>& e = i.next();
-      const QStringList& res = e.value(PluginConstants::RESOLUTION_DIRECTIVE);
-      const QStringList& version = e.value(PluginConstants::PLUGIN_VERSION_ATTRIBUTE);
-      ctkRequirePlugin* rp = new ctkRequirePlugin(this, e.value("$key").front(),
-                                            res.empty() ? QString() : res.front(),
-                                            version.empty() ? QString() : version.front());
-      require.push_back(rp);
+      Q_Q(ctkPlugin);
+      this->fwCtx->listeners.frameworkError(q, pe);
+      throw;
     }
   }
 
-  ctkPluginPrivate::ctkPluginPrivate(ctkPlugin& qq,
-    ctkPluginFrameworkContext* fw,
-    long id, const QString& loc, const QString& sym, const ctkVersion& ver)
-      : q_ptr(&qq), fwCtx(fw), id(id), location(loc), symbolicName(sym), version(ver),
-      state(ctkPlugin::INSTALLED), archive(0), pluginContext(0),
-      pluginActivator(0), lastModified(0),
-      eagerActivation(false), activating(false), deactivating(false)
-  {
+  return state;
+}
 
+void ctkPluginPrivate::setAutostartSetting(const ctkPlugin::StartOptions& setting) {
+  try
+  {
+    if (archive)
+    {
+      archive->setAutostartSetting(setting);
+    }
   }
-
-  ctkPluginPrivate::~ctkPluginPrivate()
+  catch (const ctkPluginDatabaseException& e)
   {
-    qDeleteAll(require);
+    Q_Q(ctkPlugin);
+    this->fwCtx->listeners.frameworkError(q, e);
   }
+}
 
-  ctkPlugin::State ctkPluginPrivate::getUpdatedState()
+void ctkPluginPrivate::ignoreAutostartSetting()
+{
+  try
   {
-    if (state & ctkPlugin::INSTALLED)
+    if (archive)
     {
-      try
-      {
-        if (state == ctkPlugin::INSTALLED)
-        {
-          fwCtx->resolvePlugin(this);
-          state = ctkPlugin::RESOLVED;
-          fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::RESOLVED, this->q_func()));
-        }
-
-      }
-      catch (const ctkPluginException& pe)
-      {
-        Q_Q(ctkPlugin);
-        this->fwCtx->listeners.frameworkError(q, pe);
-        throw;
-      }
+      archive->setAutostartSetting(-1);
     }
+  }
+  catch (const ctkPluginDatabaseException& e)
+  {
+    Q_Q(ctkPlugin);
+    this->fwCtx->listeners.frameworkError(q, e);
+  }
+}
 
-    return state;
+void ctkPluginPrivate::checkManifestHeaders()
+{
+  symbolicName = archive->getAttribute(PluginConstants::PLUGIN_SYMBOLICNAME);
+
+  if (symbolicName.isEmpty())
+  {
+    throw std::invalid_argument(std::string("ctkPlugin has no symbolic name, location=") +
+                                qPrintable(location));
   }
 
-  void ctkPluginPrivate::setAutostartSetting(const ctkPlugin::StartOptions& setting) {
+  QString mpv = archive->getAttribute(PluginConstants::PLUGIN_VERSION);
+  if (!mpv.isEmpty())
+  {
     try
     {
-      if (archive)
-      {
-        archive->setAutostartSetting(setting);
-      }
+      version = ctkVersion(mpv);
     }
-    catch (const ctkPluginDatabaseException& e)
+    catch (const std::exception& e)
     {
-      Q_Q(ctkPlugin);
-      this->fwCtx->listeners.frameworkError(q, e);
+      throw std::invalid_argument(std::string("ctkPlugin does not specify a valid ") +
+                                  qPrintable(PluginConstants::PLUGIN_VERSION) + " header. Got exception: " + e.what());
     }
   }
 
-  void ctkPluginPrivate::checkManifestHeaders()
+  QString ap = archive->getAttribute(PluginConstants::PLUGIN_ACTIVATIONPOLICY);
+  if (PluginConstants::ACTIVATION_EAGER == ap)
   {
-    symbolicName = archive->getAttribute(PluginConstants::PLUGIN_SYMBOLICNAME);
+    eagerActivation = true;
+  }
+
+}
 
-    if (symbolicName.isEmpty())
+void ctkPluginPrivate::finalizeActivation()
+{
+  switch (getUpdatedState())
+  {
+  case ctkPlugin::INSTALLED:
+    // we shouldn't be here, getUpdatedState should have thrown
+    // an exception during resolving the plugin
+    throw ctkPluginException("Internal error: expected exception on plugin resolve not thrown!");
+  case ctkPlugin::STARTING:
+    if (activating) return; // finalization already in progress.
+    // Lazy activation; fall through to RESOLVED.
+  case ctkPlugin::RESOLVED:
+    //6:
+    state = ctkPlugin::STARTING;
+    activating = true;
+    qDebug() << "activating #" << this->id;
+    //7:
+    if (!pluginContext)
+    {
+      pluginContext = new ctkPluginContext(this);
+    }
+    try
     {
-      throw std::invalid_argument(std::string("ctkPlugin has no symbolic name, location=") +
-                                           qPrintable(location));
+      //TODO maybe call this in its own thread
+      start0();
     }
+    catch (...)
+    {
+      //8:
+      state = ctkPlugin::STOPPING;
+      // NYI, call outside lock
+      fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPING, this->q_func()));
+      removePluginResources();
+      delete pluginContext;
+
+      state = ctkPlugin::RESOLVED;
+      // NYI, call outside lock
+      fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPED, this->q_func()));
+      activating = false;
+      throw;
+    }
+    activating = false;
+    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 std::logic_error("ctkPlugin is in UNINSTALLED state");
+  }
+}
 
-    QString mpv = archive->getAttribute(PluginConstants::PLUGIN_VERSION);
-    if (!mpv.isEmpty())
+void ctkPluginPrivate::stop0(bool wasStarted)
+{
+  //5:
+  state = ctkPlugin::STOPPING;
+  deactivating = true;
+  //6-13:
+  const std::exception* savedException = 0;
+  try
+  {
+    //6:
+    fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPING, q_func()));
+
+    //7:
+    if (wasStarted && pluginActivator)
     {
       try
       {
-        version = ctkVersion(mpv);
+        pluginActivator->stop(pluginContext);
       }
       catch (const std::exception& e)
       {
-        throw std::invalid_argument(std::string("ctkPlugin does not specify a valid ") +
-                                    qPrintable(PluginConstants::PLUGIN_VERSION) + " header. Got exception: " + e.what());
+        savedException = new ctkPluginException("ctkPlugin::stop: PluginActivator stop failed",
+                                                ctkPluginException::ACTIVATOR_ERROR, e);
+      }
+      if (state == ctkPlugin::UNINSTALLED)
+      {
+        throw std::logic_error("Plugin is uninstalled");
       }
+      pluginActivator = 0;
     }
 
-    QString ap = archive->getAttribute(PluginConstants::PLUGIN_ACTIVATIONPOLICY);
-    if (PluginConstants::ACTIVATION_EAGER == ap)
+    // Call hooks after we've called PluginActivator::stop(), but before we've cleared all resources
+    // TODO service listener hooks
+    //fwCtx->listeners.serviceListeners.hooksBundleStopped(this);
+
+    if (pluginContext)
     {
-      eagerActivation = true;
+      pluginContext->d_func()->invalidate();
+      pluginContext = 0;
     }
-
+    //8-10:
+    removePluginResources();
+  }
+  catch (const std::exception* exc)
+  {
+    savedException = exc;
   }
 
-  void ctkPluginPrivate::finalizeActivation()
+  if (state != ctkPlugin::UNINSTALLED)
   {
-    switch (getUpdatedState())
-    {
-      case ctkPlugin::INSTALLED:
-        // we shouldn't be here, getUpdatedState should have thrown
-        // an exception during resolving the plugin
-        throw ctkPluginException("Internal error: expected exception on plugin resolve not thrown!");
-      case ctkPlugin::STARTING:
-        if (activating) return; // finalization already in progress.
-        // Lazy activation; fall through to RESOLVED.
-      case ctkPlugin::RESOLVED:
-        //6:
-        state = ctkPlugin::STARTING;
-        activating = true;
-        qDebug() << "activating #" << this->id;
-        //7:
-        if (!pluginContext)
-        {
-          pluginContext = new ctkPluginContext(this);
-        }
-        try
-        {
-          //TODO maybe call this in its own thread
-          start0();
-        }
-        catch (...)
-        {
-          //8:
-          state = ctkPlugin::STOPPING;
-          // NYI, call outside lock
-          fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPING, this->q_func()));
-          removePluginResources();
-          delete pluginContext;
-
-          state = ctkPlugin::RESOLVED;
-          // NYI, call outside lock
-          fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPED, this->q_func()));
-          activating = false;
-          throw;
-        }
-        activating = false;
-        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 std::logic_error("ctkPlugin is in UNINSTALLED state");
-      }
+    state = ctkPlugin::RESOLVED;
+    deactivating = false;
+    //fwCtx.packages.notifyAll();
   }
 
-  void ctkPluginPrivate::start0()
+  if (savedException)
   {
-    fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STARTING, this->q_func()));
+    throw savedException;
+  }
+}
 
-    try {
-      pluginLoader.load();
-      if (!pluginLoader.isLoaded())
-      {
-        throw ctkPluginException(QString("Loading plugin %1 failed: %2").arg(pluginLoader.fileName()).arg(pluginLoader.errorString()),
-                              ctkPluginException::ACTIVATOR_ERROR);
-      }
+void ctkPluginPrivate::start0()
+{
+  fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STARTING, this->q_func()));
 
-      pluginActivator = qobject_cast<ctkPluginActivator*>(pluginLoader.instance());
-      if (!pluginActivator)
-      {
-        throw ctkPluginException(QString("Creating ctkPluginActivator instance from %1 failed: %2").arg(pluginLoader.fileName()).arg(pluginLoader.errorString()),
-                              ctkPluginException::ACTIVATOR_ERROR);
-      }
-
-      pluginActivator->start(pluginContext);
+  try {
+    pluginLoader.load();
+    if (!pluginLoader.isLoaded())
+    {
+      throw ctkPluginException(QString("Loading plugin %1 failed: %2").arg(pluginLoader.fileName()).arg(pluginLoader.errorString()),
+                               ctkPluginException::ACTIVATOR_ERROR);
+    }
 
-      if (ctkPlugin::UNINSTALLED == state)
-      {
-        throw ctkPluginException("ctkPlugin uninstalled during start()", ctkPluginException::STATECHANGE_ERROR);
-      }
-      state = ctkPlugin::ACTIVE;
+    pluginActivator = qobject_cast<ctkPluginActivator*>(pluginLoader.instance());
+    if (!pluginActivator)
+    {
+      throw ctkPluginException(QString("Creating ctkPluginActivator instance from %1 failed: %2").arg(pluginLoader.fileName()).arg(pluginLoader.errorString()),
+                               ctkPluginException::ACTIVATOR_ERROR);
     }
-    catch (const std::exception& e)
+
+    pluginActivator->start(pluginContext);
+
+    if (ctkPlugin::UNINSTALLED == state)
     {
-      throw ctkPluginException("ctkPlugin start failed", ctkPluginException::ACTIVATOR_ERROR, e);
+      throw ctkPluginException("ctkPlugin uninstalled during start()", ctkPluginException::STATECHANGE_ERROR);
     }
+    state = ctkPlugin::ACTIVE;
+  }
+  catch (const std::exception& e)
+  {
+    throw ctkPluginException("ctkPlugin start failed", ctkPluginException::ACTIVATOR_ERROR, e);
+  }
+
+  qDebug() << "activating #" << id << "completed.";
+
+  //10:
+  fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STARTED, this->q_func()));
+}
 
-    qDebug() << "activating #" << id << "completed.";
+void ctkPluginPrivate::removePluginResources()
+{
+  // automatic disconnect due to Qt signal slot
+  //fwCtx->listeners.removeAllListeners(this);
 
-    //10:
-    fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STARTED, this->q_func()));
+  QList<ctkServiceRegistration*> srs = fwCtx->services.getRegisteredByPlugin(this);
+  QListIterator<ctkServiceRegistration*> i(srs);
+  while (i.hasNext())
+  {
+    try
+    {
+      i.next()->unregister();
+    }
+    catch (const std::logic_error& ignore)
+    {
+      // Someone has unregistered the service after stop completed.
+      // This should not occur, but we don't want get stuck in
+      // an illegal state so we catch it.
+    }
   }
 
-  void ctkPluginPrivate::removePluginResources()
+  QList<ctkServiceRegistration*> s = fwCtx->services.getUsedByPlugin(q_func());
+  QListIterator<ctkServiceRegistration*> i2(s);
+  while (i2.hasNext())
   {
-    // automatic disconnect due to Qt signal slot
-    //fwCtx->listeners.removeAllListeners(this);
-
-    // TODO
-//    Set srs = fwCtx.services.getRegisteredByBundle(this);
-//    for (Iterator i = srs.iterator(); i.hasNext();) {
-//      try {
-//        ((ctkServiceRegistration)i.next()).unregister();
-//      } catch (IllegalStateException ignore) {
-//        // Someone has unregistered the service after stop completed.
-//        // This should not occur, but we don't want get stuck in
-//        // an illegal state so we catch it.
-//      }
-//    }
-//    Set s = fwCtx.services.getUsedByBundle(this);
-//    for (Iterator i = s.iterator(); i.hasNext(); ) {
-//      ((ServiceRegistrationImpl) i.next()).reference.ungetService(this, false);
-//    }
+    i2.next()->getReference().d_func()->ungetService(q_func(), false);
+  }
 
 }

+ 173 - 166
Libs/PluginFramework/ctkPluginPrivate_p.h

@@ -30,172 +30,179 @@
 #include <QPluginLoader>
 
 
-  class ctkPluginActivator;
-  class ctkPluginArchive;
-  class ctkPluginFrameworkContext;
-
-  class ctkPluginPrivate {
-
-  protected:
-
-    ctkPlugin * const q_ptr;
-
-  public:
-
-    Q_DECLARE_PUBLIC(ctkPlugin)
-
-    /**
-     * Construct a new plugin based on a ctkPluginArchive.
-     *
-     * @param fw ctkPluginFrameworkContext for this plugin.
-     * @param ba ctkPlugin archive representing the shared library and cached data
-     * @param checkContext AccessConrolContext to do permission checks against.
-     * @exception std::invalid_argument Faulty manifest for bundle
-     */
-    ctkPluginPrivate(ctkPlugin& qq, ctkPluginFrameworkContext* fw,
-               ctkPluginArchive* pa /*, Object checkContext*/);
-
-    /**
-     * Construct a new empty ctkPlugin.
-     *
-     * Only called for the system plugin
-     *
-     * @param fw Framework for this plugin.
-     */
-    ctkPluginPrivate(ctkPlugin& qq,
-                  ctkPluginFrameworkContext* fw,
-                  long id,
-                  const QString& loc,
-                  const QString& sym,
-                  const ctkVersion& ver);
-
-    virtual ~ctkPluginPrivate();
-
-    /**
-     * Get updated plugin state. That means check if an installed
-     * plugin has been resolved.
-     *
-     * @return ctkPlugin state
-     */
-    ctkPlugin::State getUpdatedState();
-
-    /**
-     * Save the autostart setting to the persistent plugin storage.
-     *
-     * @param setting The autostart options to save.
-     */
-    void setAutostartSetting(const ctkPlugin::StartOptions& setting);
-
-    /**
-     * Performs the actual activation.
-     */
-    void finalizeActivation();
-
-    /**
-     * Union of flags allowing plugin class access
-     */
-    static const ctkPlugin::States RESOLVED_FLAGS;
-
-    ctkPluginFrameworkContext * const fwCtx;
-
-    /**
-     * ctkPlugin identifier
-     */
-    const long id;
-
-    /**
-     * ctkPlugin location identifier
-     */
-    const QString location;
-
-    /**
-     * ctkPlugin symbolic name
-     */
-    QString symbolicName;
-
-    /**
-     * ctkPlugin version
-     */
-    ctkVersion version;
-
-    /**
-     * State of the plugin
-     */
-    ctkPlugin::State state;
-
-    /**
-     * ctkPlugin archive
-     */
-    ctkPluginArchive* archive;
-
-    /**
-     * ctkPluginContext for the plugin
-     */
-    ctkPluginContext* pluginContext;
-
-    /**
-     * ctkPluginActivator for the plugin
-     */
-    ctkPluginActivator* pluginActivator;
-
-    /**
-     * The Qt plugin loader for the plugin
-     */
-    QPluginLoader pluginLoader;
-
-    /**
-     * Time when the plugin was last modified
-     */
-    long lastModified;
-
-    /**
-     * Stores the default locale entries when uninstalled
-     */
-    QHash<QString, QString> cachedHeaders;
-
-    /**
-     * Stores the raw manifest headers
-     */
-    QHash<QString, QString> cachedRawHeaders;
-
-    /**
-     * True when this plugin has its activation policy
-     * set to "eager"
-     */
-    bool eagerActivation;
-
-    /** True during the finalization of an activation. */
-    bool activating;
-
-    /** True during the state change from active to resolved. */
-    bool deactivating;
-
-    /** Saved exception of resolve failure */
-    //ctkPluginException resolveFailException;
-
-    /** List of ctkRequirePlugin entries. */
-    QList<ctkRequirePlugin*> require;
-
-  private:
-
-    /**
-     * Check manifest and cache certain manifest headers as variables.
-     */
-    void checkManifestHeaders();
-
-    // This could potentially be run in its own thread,
-    // parallelizing plugin activations
-    void start0();
-
-    /**
-     * Remove a plugins registered listeners, registered services and
-     * used services.
-     *
-     */
-    void removePluginResources();
-
-
-  };
+class ctkPluginActivator;
+class ctkPluginArchive;
+class ctkPluginFrameworkContext;
+
+class ctkPluginPrivate {
+
+protected:
+
+  ctkPlugin * const q_ptr;
+
+public:
+
+  Q_DECLARE_PUBLIC(ctkPlugin)
+
+  /**
+   * Construct a new plugin based on a ctkPluginArchive.
+   *
+   * @param fw ctkPluginFrameworkContext for this plugin.
+   * @param ba ctkPlugin archive representing the shared library and cached data
+   * @param checkContext AccessConrolContext to do permission checks against.
+   * @exception std::invalid_argument Faulty manifest for bundle
+   */
+  ctkPluginPrivate(ctkPlugin& qq, ctkPluginFrameworkContext* fw,
+                   ctkPluginArchive* pa /*, Object checkContext*/);
+
+  /**
+   * Construct a new empty ctkPlugin.
+   *
+   * Only called for the system plugin
+   *
+   * @param fw Framework for this plugin.
+   */
+  ctkPluginPrivate(ctkPlugin& qq,
+                   ctkPluginFrameworkContext* fw,
+                   long id,
+                   const QString& loc,
+                   const QString& sym,
+                   const ctkVersion& ver);
+
+  virtual ~ctkPluginPrivate();
+
+  /**
+   * Get updated plugin state. That means check if an installed
+   * plugin has been resolved.
+   *
+   * @return ctkPlugin state
+   */
+  ctkPlugin::State getUpdatedState();
+
+  /**
+   * Save the autostart setting to the persistent plugin storage.
+   *
+   * @param setting The autostart options to save.
+   */
+  void setAutostartSetting(const ctkPlugin::StartOptions& setting);
+
+  void ignoreAutostartSetting();
+
+  /**
+   * Performs the actual activation.
+   */
+  void finalizeActivation();
+
+  /**
+   * Performs the actual stopping.
+   */
+  void stop0(bool wasStarted);
+
+  /**
+   * Union of flags allowing plugin class access
+   */
+  static const ctkPlugin::States RESOLVED_FLAGS;
+
+  ctkPluginFrameworkContext * const fwCtx;
+
+  /**
+   * ctkPlugin identifier
+   */
+  const long id;
+
+  /**
+   * ctkPlugin location identifier
+   */
+  const QString location;
+
+  /**
+   * ctkPlugin symbolic name
+   */
+  QString symbolicName;
+
+  /**
+   * ctkPlugin version
+   */
+  ctkVersion version;
+
+  /**
+   * State of the plugin
+   */
+  ctkPlugin::State state;
+
+  /**
+   * ctkPlugin archive
+   */
+  ctkPluginArchive* archive;
+
+  /**
+   * ctkPluginContext for the plugin
+   */
+  ctkPluginContext* pluginContext;
+
+  /**
+   * ctkPluginActivator for the plugin
+   */
+  ctkPluginActivator* pluginActivator;
+
+  /**
+   * The Qt plugin loader for the plugin
+   */
+  QPluginLoader pluginLoader;
+
+  /**
+   * Time when the plugin was last modified
+   */
+  long lastModified;
+
+  /**
+   * Stores the default locale entries when uninstalled
+   */
+  QHash<QString, QString> cachedHeaders;
+
+  /**
+   * Stores the raw manifest headers
+   */
+  QHash<QString, QString> cachedRawHeaders;
+
+  /**
+   * True when this plugin has its activation policy
+   * set to "eager"
+   */
+  bool eagerActivation;
+
+  /** True during the finalization of an activation. */
+  bool activating;
+
+  /** True during the state change from active to resolved. */
+  bool deactivating;
+
+  /** Saved exception of resolve failure */
+  //ctkPluginException resolveFailException;
+
+  /** List of ctkRequirePlugin entries. */
+  QList<ctkRequirePlugin*> require;
+
+private:
+
+  /**
+   * Check manifest and cache certain manifest headers as variables.
+   */
+  void checkManifestHeaders();
+
+  // This could potentially be run in its own thread,
+  // parallelizing plugin activations
+  void start0();
+
+  /**
+   * Remove a plugins registered listeners, registered services and
+   * used services.
+   *
+   */
+  void removePluginResources();
+
+
+};
 
 
 #endif // CTKPLUGINPRIVATE_P_H

+ 1 - 0
Libs/PluginFramework/ctkServiceReference.h

@@ -175,6 +175,7 @@
 
     friend class ctkServiceRegistrationPrivate;
     friend class ctkPluginContext;
+    friend class ctkPluginPrivate;
 
     ctkServiceReference(ctkServiceRegistrationPrivate* reg);