TerraLib and TerraView Wiki Page

TerraLib → Plugin

Introduction

A plugin is a computer program that interacts with a host application such as TerraView or TerraMA2 adding new capabilities/functionalities to it. These functionalities are added, in general, at runtime. There are several terms used instead of plugin: plug-in, addin, add-in, addon, add-on, snap-in, extension or supplement, for more information on plugin definitions see Wikipedia.

This module provides a basic framework for those who want to create plugins in the TerraLib Platform. Instead of a framework target to a specific application such as TerraView or TerraMA2, this plugin framework handles the extensions (plugins) and is capable of loading then dynamically. It provides the basic foundation to simplify the burden of dealing with plugins: check-up of dependencies, configuration reading, plugin management and startup/shutdown actions. Besides that, this framework allows plugins written using other programming languages, meanly the ones supported in the language binding modules. For instance you can create plugins in Lua, Java or R.

As pointed out by Vandevoorde (2006), for C and C++ programs plugins are typically implemented as shared libraries that are dynamically loaded (and sometimes unloaded) by the main program.

The next section will explain in details the design of this module.

Design Rationale

A simple example in C++

Implementation Details

A classe AbstractPlugin define a interface básica das implementações de suporte a plugins. Todo plugin:

  • possui algumas informações básicas descritas pela estrutura PluginInfo;
  • sabe informar se a funcionalidade incorporada/adicionada pelo plugin já foi inicializada;
  • possibilita a realização de algum tipo de inicialização de suas funcionalidades após a carga do mesmo pela aplicação alvo;
  • possibilita a finalização dos recursos incorporados/adicionados antes do seu módulo ser liberado da memória.
class AbstractPlugin : public boost::noncopyable
{
  public:
 
    //! Default constructor.
    AbstractPlugin() { }
 
    //! Virtual destructor.
    virtual ~ AbstractPlugin() { }
 
    //! Plugin information.
    virtual const PluginInfo& info() const = 0;
 
    //! Tells if the plugin has been started.
    virtual bool has_started() const = 0;
 
    //! This method will be called by applications to startup some plugin's functionality.
    /*!
      \exception plugin_startup_error It may throws an exception.
     */
    virtual void startup() = 0;
 
    //! This method will be called by applicatons to shutdown plugin's functionality.
    /*!
      \exception plugin_shutdown_error It may throws an exception.
     */
    virtual void shutdown() = 0;
};

Um plugin é descrito através de uma estrutura denominada PluginInfo. Esta estrutura contém os parâmetros essenciais para identificação e carga de um plugin, como o nome de uma biblioteca compartilhada a ser carregada dinamicamente, a lista de dependências de outros plugins e o identificador da máquina de carga do plugin.

struct PluginInfo
{
  std::string name;                      //!< The plugin name: an internal value used to identify the plugin in the system. Must be a unique value.
  std::string display_name;              //!< The plugin name to be displayed in a graphical interface.
  std::string description;               //!< A brief explanation about the plugin.
  std::string version;                   //!< The plugin version.
  std::string release;                   //!< The release date of the plugin. This may be used to identify new versions of a given plugin.
  std::string engine;                    //!< The type of plugin execution engine: C++, JAVA, LUA or any other supported engine.
  std::string license_description;       //!< A brief description about the plugin license.
  std::string license_URL;               //!< An URL where someone can find more information on the license.
  std::string site;                      //!< An URL pointing to the plugin site.
  provider_t provider;                   //!< Information about the plugin provider.
  std::vector<std::string> dependencies; //!< The list of required plugins in order to lunch the plugin.
  std::vector<Resource> resources;     //!< The list of resources used by plugin.
  std::vector<Parameter> parameters;   //!< Any configuration parameter that can be informed to plugin (map: parameter-name -> parameter-value).
  HostApplication host_application;   //!< Information about the host system. May be used to validate the plugin version.
};

As informações sobre o desenvolvedor/fornecedor do plugin são representadas pela estrutura Provider

struct Provider
{
  std::string name;   //!< Provider name: may be a person or a company.
  std::string site;   //!< The provider home page.
  std::string email;  //!< The provider contact e-mail.
};

HostApplication descreve informações sobre a aplicação para a qual o plugin foi escrito:

struct HostApplication
{
  std::string version;
};

Os recursos associados a um plugin são descritos por pares chave-valor:

typedef std::pair<std::string, std::string> Resource;

Os parâmetros associados a um plugin são descritos por pares chave-valor:

typedef std::pair<std::string, std::string> Parameter;
//! The base class for plugin engines.
class AbstractPluginEngine : public boost::noncopyable
{
  public:
 
    //! Default construtor.
    AbstractPluginEngine() { }
 
    //! Virtual destructor.
    virtual ~ AbstractPluginEngine() { }
 
    //! Every plugin engine must have a unique identifier.
    virtual const std::string& id() const = 0;
 
    //! The name of plugin engine with a brief title or description.
    virtual const std::string& name() const = 0;
 
    //! Load the informed plugin.
    /*!
      \param pinfo Information about the plugin to be loaded.
 
      \exception plugin_engine_load_error It may throws an exception.
     */
    virtual std::unique_ptr<AbstractPlugin> load(const PluginInfo& pinfo) = 0;
 
    //! Unload the informed plugin.
    /*!
      On success the informed plugin will be also destroyed 
      and its pointer will be invalidated.
 
      \exception plugin_engine_unload_error It may throws an exception.
     */
    virtual void unload(std::unique_ptr<AbstractPlugin> plugin) = 0;
};

Plugins escritos na linguagem C++ possuem um suporte padrão para carga de bibliotecas dinâmicas e outros detalhes deste tipo de linguagem. A classe CppPlugin é a classe base para plugins escritos em C++ com este suporte.

Final Remarks and Future Works

References