|
@@ -28,211 +28,244 @@
|
|
|
#include <QStringList>
|
|
|
|
|
|
|
|
|
- ctkPlugin::ctkPlugin(ctkPluginFrameworkContext* fw,
|
|
|
- ctkPluginArchive* pa)
|
|
|
- : d_ptr(new ctkPluginPrivate(*this, fw, pa))
|
|
|
- {
|
|
|
+ctkPlugin::ctkPlugin(ctkPluginFrameworkContext* fw,
|
|
|
+ ctkPluginArchive* pa)
|
|
|
+ : d_ptr(new ctkPluginPrivate(*this, fw, pa))
|
|
|
+{
|
|
|
|
|
|
- }
|
|
|
+}
|
|
|
|
|
|
- ctkPlugin::ctkPlugin(ctkPluginPrivate& dd)
|
|
|
- : d_ptr(&dd)
|
|
|
- {
|
|
|
+ctkPlugin::ctkPlugin(ctkPluginPrivate& dd)
|
|
|
+ : d_ptr(&dd)
|
|
|
+{
|
|
|
|
|
|
- }
|
|
|
+}
|
|
|
+
|
|
|
+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);
|
|
|
|
|
|
- ctkPlugin::~ctkPlugin()
|
|
|
+ if (d->state == UNINSTALLED)
|
|
|
{
|
|
|
- delete d_ptr;
|
|
|
+ throw std::logic_error("ctkPlugin is uninstalled");
|
|
|
}
|
|
|
|
|
|
- ctkPlugin::State ctkPlugin::getState() const
|
|
|
+ // 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)
|
|
|
{
|
|
|
- Q_D(const ctkPlugin);
|
|
|
- return d->state;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- void ctkPlugin::start(const StartOptions& options)
|
|
|
+ //3: Record non-transient start requests.
|
|
|
+ if ((options & START_TRANSIENT) == 0)
|
|
|
{
|
|
|
- Q_D(ctkPlugin);
|
|
|
-
|
|
|
- if (d->state == UNINSTALLED)
|
|
|
- {
|
|
|
- throw std::logic_error("ctkPlugin is uninstalled");
|
|
|
- }
|
|
|
-
|
|
|
- // Initialize the activation; checks initialization of lazy
|
|
|
- // activation.
|
|
|
+ d->setAutostartSetting(options);
|
|
|
+ }
|
|
|
|
|
|
- //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);
|
|
|
+ //4: Resolve plugin (if needed)
|
|
|
+ d->getUpdatedState();
|
|
|
|
|
|
- //2: start() is idempotent, i.e., nothing to do when already started
|
|
|
- if (d->state == ACTIVE)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
+ //5: Eager?
|
|
|
+ if ((options & START_ACTIVATION_POLICY) && !d->eagerActivation )
|
|
|
+ {
|
|
|
+ if (STARTING == d->state) return;
|
|
|
+ d->state = STARTING;
|
|
|
+ d->pluginContext = new ctkPluginContext(this->d_func());
|
|
|
+ ctkPluginEvent pluginEvent(ctkPluginEvent::LAZY_ACTIVATION, this);
|
|
|
+ d->fwCtx->listeners.emitPluginChanged(pluginEvent);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ d->finalizeActivation();
|
|
|
+ }
|
|
|
|
|
|
- //3: Record non-transient start requests.
|
|
|
- if ((options & START_TRANSIENT) == 0)
|
|
|
+ //6: Register Qt Mobility service xml files
|
|
|
+ //only register if we are not already in the STARTING
|
|
|
+ //or ACTIVE state
|
|
|
+ if (d->state & STARTING || d->state & ACTIVE)
|
|
|
+ {
|
|
|
+ QByteArray serviceDescriptor = getResource("servicedescriptor.xml");
|
|
|
+ if (!serviceDescriptor.isEmpty())
|
|
|
{
|
|
|
- d->setAutostartSetting(options);
|
|
|
+ d->fwCtx->services.registerService(d, serviceDescriptor);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- //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 = new ctkPluginContext(this->d_func());
|
|
|
- ctkPluginEvent pluginEvent(ctkPluginEvent::LAZY_ACTIVATION, this);
|
|
|
- d->fwCtx->listeners.emitPluginChanged(pluginEvent);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- d->finalizeActivation();
|
|
|
- }
|
|
|
+void ctkPlugin::stop(const StopOptions& options)
|
|
|
+{
|
|
|
+ Q_D(ctkPlugin);
|
|
|
|
|
|
- //6: Register Qt Mobility service xml files
|
|
|
- //only register if we are not already in the STARTING
|
|
|
- //or ACTIVE state
|
|
|
- if (d->state & STARTING || d->state & ACTIVE)
|
|
|
- {
|
|
|
- QByteArray serviceDescriptor = getResource("servicedescriptor.xml");
|
|
|
- if (!serviceDescriptor.isEmpty())
|
|
|
- {
|
|
|
- d->fwCtx->services.registerService(d, serviceDescriptor);
|
|
|
- }
|
|
|
- }
|
|
|
+ const std::exception* savedException = 0;
|
|
|
|
|
|
+ //1:
|
|
|
+ if (d->state == UNINSTALLED)
|
|
|
+ {
|
|
|
+ throw std::logic_error("Plugin is uninstalled");
|
|
|
}
|
|
|
|
|
|
- void ctkPlugin::stop(const StopOptions& options)
|
|
|
- {
|
|
|
- Q_D(ctkPlugin);
|
|
|
+ //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);
|
|
|
|
|
|
- const std::exception* savedException = 0;
|
|
|
+ //3:
|
|
|
+ if ((options & STOP_TRANSIENT) == 0)
|
|
|
+ {
|
|
|
+ d->ignoreAutostartSetting();
|
|
|
+ }
|
|
|
+ bool wasStarted = false;
|
|
|
|
|
|
- //1:
|
|
|
- if (d->state == UNINSTALLED)
|
|
|
+ switch (d->state)
|
|
|
+ {
|
|
|
+ case INSTALLED:
|
|
|
+ case RESOLVED:
|
|
|
+ case STOPPING:
|
|
|
+ case UNINSTALLED:
|
|
|
+ //4:
|
|
|
+ return;
|
|
|
+
|
|
|
+ case ACTIVE:
|
|
|
+ wasStarted = true;
|
|
|
+ case STARTING: // Lazy start...
|
|
|
+ try
|
|
|
{
|
|
|
- throw std::logic_error("Plugin is uninstalled");
|
|
|
+ d->stop0(wasStarted);
|
|
|
}
|
|
|
-
|
|
|
- //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)
|
|
|
+ catch (const std::exception* exc)
|
|
|
{
|
|
|
- d->ignoreAutostartSetting();
|
|
|
+ savedException = exc;
|
|
|
}
|
|
|
- bool wasStarted = false;
|
|
|
+ break;
|
|
|
+ };
|
|
|
|
|
|
- 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)
|
|
|
+ if (d->state != UNINSTALLED)
|
|
|
+ {
|
|
|
+ d->fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPED, this));
|
|
|
+ }
|
|
|
+ if (savedException)
|
|
|
+ {
|
|
|
+ if (const ctkPluginException* pluginExc = dynamic_cast<const ctkPluginException*>(savedException))
|
|
|
{
|
|
|
- d->fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPED, this));
|
|
|
+ throw pluginExc;
|
|
|
}
|
|
|
- if (savedException)
|
|
|
+ else
|
|
|
{
|
|
|
- if (const ctkPluginException* pluginExc = dynamic_cast<const ctkPluginException*>(savedException))
|
|
|
- {
|
|
|
- throw pluginExc;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- throw dynamic_cast<const std::logic_error*>(savedException);
|
|
|
- }
|
|
|
+ throw dynamic_cast<const std::logic_error*>(savedException);
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- ctkPluginContext* ctkPlugin::getPluginContext() const
|
|
|
- {
|
|
|
- //TODO security checks
|
|
|
- Q_D(const ctkPlugin);
|
|
|
- return d->pluginContext;
|
|
|
- }
|
|
|
+ctkPluginContext* ctkPlugin::getPluginContext() const
|
|
|
+{
|
|
|
+ //TODO security checks
|
|
|
+ Q_D(const ctkPlugin);
|
|
|
+ return d->pluginContext;
|
|
|
+}
|
|
|
+
|
|
|
+long ctkPlugin::getPluginId() const
|
|
|
+{
|
|
|
+ Q_D(const ctkPlugin);
|
|
|
+ return d->id;
|
|
|
+}
|
|
|
+
|
|
|
+QString ctkPlugin::getLocation() const
|
|
|
+{
|
|
|
+ //TODO security
|
|
|
+ Q_D(const ctkPlugin);
|
|
|
+ return d->location;
|
|
|
+}
|
|
|
|
|
|
- long ctkPlugin::getPluginId() const
|
|
|
+QHash<QString, QString> ctkPlugin::getHeaders()
|
|
|
+{
|
|
|
+ //TODO security
|
|
|
+ Q_D(ctkPlugin);
|
|
|
+ if (d->cachedRawHeaders.empty())
|
|
|
{
|
|
|
- Q_D(const ctkPlugin);
|
|
|
- return d->id;
|
|
|
+ d->cachedRawHeaders = d->archive->getUnlocalizedAttributes();
|
|
|
}
|
|
|
|
|
|
- QString ctkPlugin::getLocation() const
|
|
|
+ if (d->state == UNINSTALLED)
|
|
|
{
|
|
|
- //TODO security
|
|
|
- Q_D(const ctkPlugin);
|
|
|
- return d->location;
|
|
|
+ return d->cachedHeaders;
|
|
|
}
|
|
|
|
|
|
- QHash<QString, QString> ctkPlugin::getHeaders()
|
|
|
- {
|
|
|
- //TODO security
|
|
|
- Q_D(ctkPlugin);
|
|
|
- if (d->cachedRawHeaders.empty())
|
|
|
- {
|
|
|
- d->cachedRawHeaders = d->archive->getUnlocalizedAttributes();
|
|
|
- }
|
|
|
+ //TODO use the embedded .qm files to localize header values
|
|
|
+ return d->cachedRawHeaders;
|
|
|
+}
|
|
|
|
|
|
- if (d->state == UNINSTALLED)
|
|
|
- {
|
|
|
- return d->cachedHeaders;
|
|
|
- }
|
|
|
+QString ctkPlugin::getSymbolicName() const
|
|
|
+{
|
|
|
+ Q_D(const ctkPlugin);
|
|
|
+ return d->symbolicName;
|
|
|
+}
|
|
|
|
|
|
- //TODO use the embedded .qm files to localize header values
|
|
|
- return d->cachedRawHeaders;
|
|
|
- }
|
|
|
+QStringList ctkPlugin::getResourceList(const QString& path) const
|
|
|
+{
|
|
|
+ Q_D(const ctkPlugin);
|
|
|
+ return d->archive->findResourcesPath(path);
|
|
|
+}
|
|
|
|
|
|
- QString ctkPlugin::getSymbolicName() const
|
|
|
- {
|
|
|
- Q_D(const ctkPlugin);
|
|
|
- return d->symbolicName;
|
|
|
- }
|
|
|
+QByteArray ctkPlugin::getResource(const QString& path) const
|
|
|
+{
|
|
|
+ Q_D(const ctkPlugin);
|
|
|
+ return d->archive->getPluginResource(path);
|
|
|
+}
|
|
|
|
|
|
- QStringList ctkPlugin::getResourceList(const QString& path) const
|
|
|
- {
|
|
|
- Q_D(const ctkPlugin);
|
|
|
- return d->archive->findResourcesPath(path);
|
|
|
- }
|
|
|
+ctkVersion ctkPlugin::getVersion() const
|
|
|
+{
|
|
|
+ Q_D(const ctkPlugin);
|
|
|
+ return d->version;
|
|
|
+}
|
|
|
|
|
|
- QByteArray ctkPlugin::getResource(const QString& path) const
|
|
|
+QDebug operator<<(QDebug debug, ctkPlugin::State state)
|
|
|
+{
|
|
|
+ switch (state)
|
|
|
{
|
|
|
- Q_D(const ctkPlugin);
|
|
|
- return d->archive->getPluginResource(path);
|
|
|
+ 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";
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- ctkVersion ctkPlugin::getVersion() const
|
|
|
- {
|
|
|
- Q_D(const ctkPlugin);
|
|
|
- return d->version;
|
|
|
+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);
|
|
|
}
|