summaryrefslogtreecommitdiff
path: root/src/libs/extensionsystem/iplugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/extensionsystem/iplugin.cpp')
-rw-r--r--src/libs/extensionsystem/iplugin.cpp325
1 files changed, 325 insertions, 0 deletions
diff --git a/src/libs/extensionsystem/iplugin.cpp b/src/libs/extensionsystem/iplugin.cpp
new file mode 100644
index 0000000000..47cb702e16
--- /dev/null
+++ b/src/libs/extensionsystem/iplugin.cpp
@@ -0,0 +1,325 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "iplugin.h"
+#include "iplugin_p.h"
+#include "pluginmanager.h"
+#include "pluginspec.h"
+
+/*!
+ \class ExtensionSystem::IPlugin
+ \brief Base class for all plugins.
+
+ The IPlugin class is an abstract class that must be implemented
+ once for each plugin.
+ A plugin consists of two parts: A description file, and a library
+ that at least contains the IPlugin implementation.
+
+ \tableofcontents
+
+ \section1 Plugin Specification
+ The plugin specification file is an xml file that contains all
+ information that are necessary for loading the plugin's library,
+ plus some textual descriptions. The file must be located in
+ (a subdir of) one of the plugin manager's plugin search paths,
+ and must have the \c .xml extension.
+
+ \section2 Main Tag
+ The root tag is \c plugin. It has mandatory attributes \c name
+ and \c version, and an optional \c compatVersion.
+ \table
+ \header
+ \o Tag
+ \o Meaning
+ \row
+ \o plugin
+ \o Root element in a plugin's xml file.
+ \endtable
+ \table
+ \header
+ \o Attribute
+ \o Meaning
+ \row
+ \o name
+ \o This is used as an identifier for the plugin and can e.g.
+ be referenced in other plugin's dependencies. It is
+ also used to construct the name of the plugin library
+ as \c lib[name].[dll|.so|.dylib].
+ \row
+ \o version
+ \o Version string in the form \c {"x.y.z_n"}, used for identifying
+ the plugin.
+ \row
+ \o compatVersion
+ \o Compatibility version. Optional. If not given, it is implicitly
+ set to the same value as \c version. The compatibility version
+ is used to resolve dependencies on this plugin. See
+ \l {Dependencies}{Dependencies} for details.
+ \endtable
+
+ \section2 Plugin-describing Tags
+ These are direct children of the \c plugin tag, and are solely used
+ for more detailed (user centric) description of the plugin. All of these
+ are optional.
+ \table
+ \header
+ \o Tag
+ \o Meaning
+ \row
+ \o vendor
+ \o String that describes the plugin creator/vendor,
+ like \c {MyCompany}.
+ \row
+ \o copyright
+ \o A short copyright notice, like \c {(C) 2007-2008 MyCompany}.
+ \row
+ \o license
+ \o Possibly multi-line license information about the plugin.
+ \row
+ \o description
+ \o Possibly multi-line description of what the plugin is supposed
+ to provide.
+ \row
+ \o url
+ \o Link to further information about the plugin, like
+ \c {http://www.mycompany-online.com/products/greatplugin}.
+ \endtable
+
+ \section2 Dependencies
+ A plugin can have dependencies on other plugins. These are
+ specified in the plugin's xml file as well, to ensure that
+ these other plugins are loaded before this plugin.
+ Dependency information consists of the name of the required plugin
+ (lets denote that as \c {dependencyName}),
+ and the required version of the plugin (\c {dependencyVersion}).
+ A plugin with given \c name, \c version and \c compatVersion matches
+ the dependency if
+ \list
+ \o it's \c name matches \c dependencyName, and
+ \o \c {compatVersion <= dependencyVersion <= version}.
+ \endlist
+
+ The xml element that describes dependencies is the \c dependency tag,
+ with required attributes \c name and \c version. It is an
+ optional direct child of the \c plugin tag and can appear multiple times.
+ \table
+ \header
+ \o Tag
+ \o Meaning
+ \row
+ \o dependency
+ \o Describes a dependency on another plugin.
+ \endtable
+ \table
+ \header
+ \o Attribute
+ \o Meaning
+ \row
+ \o name
+ \o The name of the plugin, on which this plugin relies.
+ \row
+ \o version
+ \o The version to which the plugin must be compatible to
+ fill the dependency, in the form \c {"x.y.z_n"}.
+ \endtable
+
+ \section2 Example \c plugin.xml
+ \code
+ <plugin name="test" version="1.0.1" compatVersion="1.0.0">
+ <vendor>MyCompany</vendor>
+ <copyright>(C) 2007 MyCompany</copyright>
+ <license>
+ This is a default license bla
+ blubbblubb
+ end of terms
+ </license>
+ <description>
+ This plugin is just a test.
+ it demonstrates the great use of the plugin spec.
+ </description>
+ <url>http://www.mycompany-online.com/products/greatplugin</url>
+ <dependencyList>
+ <dependency name="SomeOtherPlugin" version="2.3.0_2"/>
+ <dependency name="EvenOther" version="1.0.0"/>
+ </dependencyList>
+ </plugin>
+ \endcode
+ The first dependency could for example be matched by a plugin with
+ \code
+ <plugin name="SomeOtherPlugin" version="3.1.0" compatVersion="2.2.0">
+ </plugin>
+ \endcode
+ since the name matches, and the version \c "2.3.0_2" given in the dependency tag
+ lies in the range of \c "2.2.0" and \c "3.1.0".
+
+ \section2 A Note on Plugin Versions
+ Plugin versions are in the form \c "x.y.z_n" where, x, y, z and n are
+ non-negative integer numbers. You don't have to specify the version
+ in this full form - any left-out part will implicitly be set to zero.
+ So, \c "2.10_2" is equal to \c "2.10.0_2", and "1" is the same as "1.0.0_0".
+
+ \section1 Plugin Implementation
+ Plugins must provide one implementation of the IPlugin class, located
+ in a library that matches the \c name attribute given in their
+ xml description. The IPlugin implementation must be exported and
+ made known to Qt's plugin system via the Q_EXPORT_PLUGIN macro, see the
+ Qt documentation for details on that.
+
+ After the plugins' xml files have been read, and dependencies have been
+ found, the plugin loading is done in three phases:
+ \list 1
+ \o All plugin libraries are loaded in 'root-to-leaf' order of the
+ dependency tree.
+ \o All plugins' initialize methods are called in 'root-to-leaf' order
+ of the dependency tree. This is a good place to put
+ objects in the plugin manager's object pool.
+ \o All plugins' extensionsInitialized methods are called in 'leaf-to-root'
+ order of the dependency tree. At this point, plugins can
+ be sure that all plugins that depend on this plugin have
+ been initialized completely (implying that they have put
+ objects in the object pool, if they want that during the
+ initialization sequence).
+ \endlist
+ If library loading or initialization of a plugin fails, all plugins
+ that depend on that plugin also fail.
+
+ Plugins have access to the plugin manager
+ (and it's object pool) via the PluginManager::instance()
+ method.
+*/
+
+/*!
+ \fn bool IPlugin::initialize(const QStringList &arguments, QString *errorString)
+ Called after the plugin has been loaded and the IPlugin instance
+ has been created. The initialize methods of plugins that depend
+ on this plugin are called after the initialize method of this plugin
+ has been called. Plugins should initialize their internal state in this
+ method. Returns if initialization of successful. If it wasn't successful,
+ the \a errorString should be set to a user-readable message
+ describing the reason.
+ \sa extensionsInitialized()
+*/
+
+/*!
+ \fn void IPlugin::extensionsInitialized()
+ Called after the IPlugin::initialize() method has been called,
+ and after both the IPlugin::initialize() and IPlugin::extensionsInitialized()
+ methods of plugins that depend on this plugin have been called.
+ In this method, the plugin can assume that plugins that depend on
+ this plugin are fully 'up and running'. It is a good place to
+ look in the plugin manager's object pool for objects that have
+ been provided by dependent plugins.
+ \sa initialize()
+*/
+
+/*!
+ \fn void IPlugin::shutdown()
+ Called during a shutdown sequence in the same order as initialization
+ before the plugins get deleted in reverse order.
+ This method can be used to optimize the shutdown down, e.g. to
+ disconnect from the PluginManager::aboutToRemoveObject() signal
+ if getting the signal (and probably doing lots of stuff to update
+ the internal and visible state) doesn't make sense during shutdown.
+*/
+
+using namespace ExtensionSystem;
+
+/*!
+ \fn IPlugin::IPlugin()
+ \internal
+*/
+IPlugin::IPlugin()
+ : d(new Internal::IPluginPrivate())
+{
+}
+
+/*!
+ \fn IPlugin::~IPlugin()
+ \internal
+*/
+IPlugin::~IPlugin()
+{
+ PluginManager *pm = PluginManager::instance();
+ foreach (QObject *obj, d->addedObjectsInReverseOrder)
+ pm->removeObject(obj);
+ qDeleteAll(d->addedObjectsInReverseOrder);
+ d->addedObjectsInReverseOrder.clear();
+ delete d;
+ d = 0;
+}
+
+/*!
+ \fn PluginSpec *IPlugin::pluginSpec() const
+ Returns the PluginSpec corresponding to this plugin.
+ This is not available in the constructor.
+*/
+PluginSpec *IPlugin::pluginSpec() const
+{
+ return d->pluginSpec;
+}
+
+/*!
+ \fn void IPlugin::addObject(QObject *obj)
+ Convenience method that registers \a obj in the plugin manager's
+ plugin pool by just calling PluginManager::addObject().
+*/
+void IPlugin::addObject(QObject *obj)
+{
+ PluginManager::instance()->addObject(obj);
+}
+
+/*!
+ \fn void IPlugin::addAutoReleasedObject(QObject *obj)
+ Convenience method for registering \a obj in the plugin manager's
+ plugin pool. Usually, registered objects must be removed from
+ the object pool and deleted by hand.
+ Objects added to the pool via addAutoReleasedObject are automatically
+ removed and deleted in \i reverse order of registration when
+ the IPlugin instance is destroyed.
+ \sa PluginManager::addObject()
+*/
+void IPlugin::addAutoReleasedObject(QObject *obj)
+{
+ d->addedObjectsInReverseOrder.prepend(obj);
+ PluginManager::instance()->addObject(obj);
+}
+
+/*!
+ \fn void IPlugin::removeObject(QObject *obj)
+ Convenience method that unregisters \a obj from the plugin manager's
+ plugin pool by just calling PluginManager::removeObject().
+*/
+void IPlugin::removeObject(QObject *obj)
+{
+ PluginManager::instance()->removeObject(obj);
+}
+