Wtyczka

Wtyczka jest bundlem OSGi instalowanym w środowisku OSGi. Może być ona dynamicznie:

  • instalowana
  • aktualizowana
  • uruchamiana
  • zatrzymywana
  • odinstalowana

Wtyczka posiada własny kontekst, który pełni rolę kontenera komponentów wtyczki, serwisów, kontrolerów. Możliwe jest wstrzykiwanie zależności i korzystanie ze wszystkich dobrodziejstw SpringFramework.

Deskryptor wtyczki (suncode-plugin.xml)

Deskryptor wtyczki to plik XML który dostarcza podstawowe informacje o wtyczce oraz jest miejscem na deklaracje wykorzystywanych modułów. Plik ten jest wymagany, ponieważ dostarcza informacje o wtyczce (jej unikalny identyfikator i wyświetlaną nazwę).

Deskryptor ma następującą strukturę:

<?xml version="1.0" encoding="UTF-8"?>
<plugin key="com.suncode.plugin-tutorial" name="Tutorial Plugin">
	<plugin-details>
		<description>
			<localized language="en">Description</localized>
			<localized language="pl">Opis</localized>
		</description>
		<author>Suncode</author>
        <requirements>
            <plusworkflow>3.2.200</plusworkflow>
            <com.suncode.plugin-dbexplorer>2.0.24</com.suncode.plugin-dbexplorer>
            <com.suncode.plugin-pwe>2.3.63</com.suncode.plugin-pwe>
        </requirements>
        <free-license>XXXXXXXXXXXXXXXXXXXXX</free-license>
        <changelog>https://docs.plusworkflow.pl/confluence/display/UNICMP/Change+Log+cuf-components</changelog>
        <documentation>https://docs.plusworkflow.pl/confluence/display/UNICMP/Cuf-components</documentation>
	</plugin-details>
	
	<!-- Wszystkie kolejne elementy stanowią deklaracje modułów -->	
</plugin>

Sekcja <requirements> pozwala na określenie wymaganych zależności wtyczka. Zależność systemowa <plusworfklow> powinna być zgodna co do wersji z wersją parenta określoną w pom.xml.
Sekcja <free-license> pozwala na przypisanie wtyczce darmowej licencji - wtyczki posiadające ten wpis będą instalowały się jako "Darmowe" Wtyczki bez tej sekcji są płatne. Licencje są powiązane z identyfikatorem wtyczki - generowanie licencji jest dostępne w systemie ISO.
Sekcja <changelog> pozwala na wskazanie URLa do changeloga danej wtyczki. Link będzie dostępny do kliknięcia z poziomu centrum aktualizacji. Uwaga: link powininen wskazywać na zasoby publiczne, dostępne bez konieczności logowania.
Sekcja <documentation> pozwala na wskazanie URL z dokumentacją wtyczki. Link będzie dostępny z poziomu centrum aktualizacji.

 

Wtyczka może także zdefiniować PluginHook, jeżeli potrzebne jest wywołanie akcji przy starcie i zatrzymaniu wtyczki:

<?xml version="1.0" encoding="UTF-8"?>
<plugin key="com.suncode.plugin-tutorial" name="Tutorial Plugin" hook="com.suncode.plugin.tutorial.Hook">
	<!-- ... -->
</plugin>

Wymagania wtyczek

Wtyczka może zdefiniować swoje wymagania, które są sprawdzane podczas:

  1. uruchomienia – wtyczka nie może być uruchomiona w przypadku braku zależności mandatory
  2. aktualizacji - wyświetlany jest komunikat w którym:
    1. widoczne są nowe zależności które nie są spełnione
    2. widoczne są wtyczki które mogą wymagały innej wersji tej wtyczki (tylko przy downgrade)
  3. zatrzymania wtyczki - wyświetlany jest komunikat zawierający wszystkie wtyczki które mogą przestać działać poprawnie po zatrzymaniu tej wtyczki
  4. usunięcia wtyczki - wyświetlany jest komunikat zawierający wszystkie wtyczki które mogą przestać działać poprawnie po usunięciu tej wtyczki

Wymagania dzielimy na:

  • optional - uruchomienie wtyczki nie jest blokowane
  • mandatory - wtyczka nigdy nie zostanie uruchomiona

 

<?xml version="1.0" encoding="UTF-8"?>
<plugin key="com.suncode.plugin-tutorial" name="Tutorial Plugin">
	<plugin-details>
		<requirements>
			<!-- Wymaganie 'mandatory' na system PlusWorkflow -->
			<plusworkflow>3.2.50</plusworkflow>
			<!-- Wymaganie 'optional' na wtyczke o kluczu "com.suncode.plugin.pluginX" -->
			<com.suncode.plugin.pluginX optional="true">1.1</com.suncode.plugin.pluginX>
		</requirements>
	</plugin-details>
</plugin>

Plik suncode-plugin.xml musi znajdować się w głównym katalogu pliku jar.

Operacje na wtyczkach

Ten rozdział pokazuje, jak korzystać z API mechanizmu wtyczekRozdział Zarządzanie wtyczkami pokazuje, jak zarządzać nimi z poziomu systemu.

JavaDoc API znajduje sie tutaj: http://javadoc.plusworkflow.pl/javadoc/plugin-framework/1.0.0/api/


Głównym komponentem mechanizmu wtyczek jest PluginFramework. W systemie PlusWorkflow musimy pobrać ten obiekt z kontekstu aplikacji:

  • wykorzystać wstrzykiwanie zależności

    @Component
    public class SomeComponent {
    	@Autowired
    	private PluginFramework framework;	
     
    	/**
    ...
    	*/
    }
  • pobrać obiekt statycznie z kontekstu aplikacji

    import com.suncode.plugin.framework.PluginFramework;
    import com.suncode.pwfl.util.SpringContext;
     
    public class SomeClass {
    	public static void doSomething(){
    		PluginFramework framework = SpringContext.getBean( PluginFramework.class );
    	/**
    	...
    */
    }
    }

Poniżej przedstawiono wykonywanie kilku podstawowych operacji:

// pobrany w dowolny sposób
// PluginFramework framework = ...
 
// 1. Instalacja wtyczki z podanego pliku
File pluginFile = new File("/fakepath");
Plugin plugin = framework.installPlugin( pluginFile );
 
// 2. Aktualizacja wtyczki
File updatedPluginFile = new File("/fakepath");
plugin.update( updatedPluginFile );
 
// 3. Uruchomienie wtyczki
plugin.start();
plugin.getState(); // PluginState.ACTIVE
 
// 4. Pobranie tłumaczenia 
// zwraca "message1" jeżeli moduł I18N nie jest obecny, w przeciwnym wypadku zwraca znalezione tłumaczenie
plugin.getMessage("message1"); 
 
// 5. Zatrzymanie wtyczki
plugin.stop();
plugin.getState(); // PluginState.STOPPED

Plugin

The plugin is an OSGi bundle installed in the OSGi environment. It can be used dynamically:

  • installed
  • updated
  • launched
  • stopped
  • uninstalled

The plugin has its own context, which acts as a container for plugin components, services, controllers. It is possible to inject inject dependencies and use all the benefits of SpringFramework.

Plugin descriptor (suncode-plugin.xml)

 

The plugin descriptor is an XML file that provides basic information about the plugin and is a place for declarations of the modules used. This file is required because it provides information about the plugin (its unique identifier and display name).

The descriptor has the following structure:

<?xml version="1.0" encoding="UTF-8"?>
<plugin key="com.suncode.plugin-tutorial" name="Tutorial Plugin">
	<plugin-details>
		<description>
			<localized language="en">Description</localized>
			<localized language="pl">Opis</localized>
		</description>
		<author>Suncode</author>
        <requirements>
            <plusworkflow>3.2.200</plusworkflow>
            <com.suncode.plugin-dbexplorer>2.0.24</com.suncode.plugin-dbexplorer>
            <com.suncode.plugin-pwe>2.3.63</com.suncode.plugin-pwe>
        </requirements>
        <free-license>XXXXXXXXXXXXXXXXXXXXX</free-license>
        <changelog>https://docs.plusworkflow.pl/confluence/display/UNICMP/Change+Log+cuf-components</changelog>
        <documentation>https://docs.plusworkflow.pl/confluence/display/UNICMP/Cuf-components</documentation>
	</plugin-details>
	
	<!-- All subsequent elements are declarations of modules -->	
</plugin>

The <requirements> section allows you to specify the required plugin dependencies. The <plusworfklow> system dependency should match as to version with the parent version specified in pom.xml.
The <free-license> section allows you to assign a free license to the plugin - plugins having this entry will install as "Free" Plugins without this section are paid. Licenses are associated with the plugin ID - license generation is available in the ISO system.
The <changelog> section allows you to indicate the URL to the changelog of a given plugin. The link will be available to click on from the update center. Note: the link should point to a public resource, accessible without login.
The <documentation> section allows you to point to the URL with the plugin's documentation. The link will be available to click from the update center.

 

The plugin can also define PluginHook, if an action is needed to be triggered when the plugin starts and stops:

<?xml version="1.0" encoding="UTF-8"?>
<plugin key="com.suncode.plugin-tutorial" name="Tutorial Plugin" hook="com.suncode.plugin.tutorial.Hook">
	<!-- ... -->
</plugin>

Plugin requirements

A plugin can define its requirements, which are checked during:

  1. launch - the plug-in cannot be launched if there are no mandatory dependencies
  2. update - a message is displayed in which:
    1. new dependencies that are not met are visible
    2. visible are plugins that may have required a different version of this plugin (only for downgrade)
  3. stopping a plugin - a message is displayed containing all plug-ins that may stop working properly after stopping this plugin
  4. deleting a plugin - a message is displayed containing all plug-ins that may stop working properly after deleting this plugin

Requirements are divided into:

  • optional - launching the plugin is not blocked
  • mandatory - the plugin will never be launched

 

<?xml version="1.0" encoding="UTF-8"?>
<plugin key="com.suncode.plugin-tutorial" name="Tutorial Plugin">
	<plugin-details>
		<requirements>
			<!-- Requirement 'mandatory' for PlusWorkflow system -->
			<plusworkflow>3.2.50</plusworkflow>
			<!-- Requirement 'optional' on plugin with key "com.suncode.plugin.pluginX" -->
			<com.suncode.plugin.pluginX optional="true">1.1</com.suncode.plugin.pluginX>
		</requirements>
	</plugin-details>
</plugin>

The suncode-plugin.xml file must be in the main directory of the jar file.


Plugin operations

This chapter shows how to use the plugin mechanism API. The Plugins management shows how to manage plugins from within the system.

The JavaDoc API can be found here: http://javadoc.plusworkflow.pl/javadoc/plugin-framework/1.0.0/api/


 

The main component of the plugin mechanism is the PluginFramework. In PlusWorkflow, we need to retrieve this object from the application context:

  • use dependency injection

    @Component
    public class SomeComponent {
    	@Autowired
    	private PluginFramework framework;	
     
    	/**
    ...
    	*/
    }
  • retrieve the object statically from the application context

    import com.suncode.plugin.framework.PluginFramework;
    import com.suncode.pwfl.util.SpringContext;
     
    public class SomeClass {
    	public static void doSomething(){
    		PluginFramework framework = SpringContext.getBean( PluginFramework.class );
    	/**
    	...
    */
    }
    }

The following shows the performance of some basic operations:

// taken any method
// PluginFramework framework = ...
 
// 1. Installation of the plugin from the given file
File pluginFile = new File("/fakepath");
Plugin plugin = framework.installPlugin( pluginFile );
 
// 2. Plugin update
File updatedPluginFile = new File("/fakepath");
plugin.update( updatedPluginFile );
 
// 3. Launching the plugin
plugin.start();
plugin.getState(); // PluginState.ACTIVE
 
// 4. Translation download 
// zwraca "message1" jeżeli moduł I18N nie jest obecny, w przeciwnym wypadku zwraca znalezione tłumaczenie
plugin.getMessage("message1"); 
 
// 5. Stopping the plugin
plugin.stop();
plugin.getState(); // PluginState.STOPPED