Table of Contents
Creating a new Plugin
Plugin structure
The GroIMP software can be extended by plugins. This page describes how to write a plugin named MyPlugin.
Firstly, a plugin has to have a special directory layout. The layout depends on how you run GroIMP. There are currently two layout:
- As compiled plugin.
- As compiled classes.
In the compiled version of GroIMP (the one deployed and installed with the executable files) the plugins are loaded as:
- MyPlugin
- MyPlugin.jar
- plugin.properties
- plugin.xml
- doc/
- dependencies.jar …
In the development version of GroIMP (usually what you get from the source code, and using the –project-tree argument) the plugins are loaded as:
- MyPlugin
- target
- classes
- plugin.properties
- plugin.xml
- <compiled class files>
- <additional files copied from the src-directory>
- lib
- <needed jar-files>
Important: Note that the files plugin.xml, and plugin.properties are required.
By default GroIMP load plugins from its root/plugins directory. During development, usually the –project-tree argument is used, making GroIMP load plugin from the same directory as the needed GroIMP plugins and projects (e.g., Graph, XL-Core, IMP-3D, …). It is also possible to set an additional directory where GroIMP look for plugins in the GroIMP preferences. Or by passing the command line argument -p when starting groimp.
Using Maven
The compiled plugins follow the maven project structure. You can get a template plugin here. By default the plugin follow the structure:
- MyPlugin
- pom.xml
- src
- main
- java
- <Java source files>
- resources
- plugin.properties
- plugin.xml
- doc/
- <additional non-Java files>
- assembly
- <assembly files used for packaging>
- lib
- <needed jar-files>
The default template includes the assembly files, which you do not have to change for the packaging to a GroIMP plugin.
If possible the third party dependencies should be defined in the pom.xml file and not added to the lib directory. During the maven compilation, the dependencies defined in the pom.xml are automatically added to the target/lib directory, so GroIMP can use them (this operation is performed by the lib.xml assembly file).
Maven property file (pom.xml)
Afterwards, you should update the pom.xml file which is used by the Maven tool. Even if you use an IDE for development, a release of a plugin should be made using Maven (which do additional operations when packaging, e.g. source enhancement, deployment, doc, …). Assuming that MyPlugin needs two third party jar-libraries mylib.jar and yourlib.jar, that yourlib.jar is deplyed on Maven Central (an online repository for maven jars) and, that it references the plugins IMP-2D and IMP-3D of GroIMP, pom.xml looks as follows:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>GroIMP</artifactId> <groupId>de.grogra</groupId> <version>2.1</version> </parent> <artifactId>myPlugin</artifactId> <packaging>jar</packaging> <name>MyPlugin</name> <repositories> <repository> <id>lib-local</id> <name>lib</name> <url>file://${project.basedir}/lib/</url> </repository> <repository> <id>gitlab-maven</id> <url>https://gitlab.com/api/v4/groups/55048746/-/packages/maven</url> </repository> </repositories> <properties> <maven.assembly.plugin.move-lib>generate-resources</maven.assembly.plugin.move-lib> </properties> <dependencies> <dependency> <groupId>de.grogra</groupId> <artifactId>imp2d</artifactId> <version>${groimp.core.version}</version> </dependency> <dependency> <groupId>de.grogra</groupId> <artifactId>imp3d</artifactId> <version>${groimp.core.version}</version> </dependency> <dependency> <groupId>your.remote.lib</groupId> <artifactId>yourlib</artifactId> <version>xxx</version> </dependency> <dependency> <groupId>my.local.lib</groupId> <artifactId>mylib</artifactId> <version>xxx</version> </dependency> </dependencies> <build> <finalName>${project.name}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> </plugin> </plugins> </build> </project>
The first part - plugin info:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>GroIMP</artifactId> <groupId>de.grogra</groupId> <version>2.1</version> </parent> <artifactId>myPlugin</artifactId> <packaging>jar</packaging> <name>MyPlugin</name>
defines:
- The link dependencies to a GroIMP version (under <parent> tag and <version>).
- An artifactId for your plugin, which should start with a lowercase letter. This is the unique identifier of your plugin.
- The name of your plugin (in the <name> tag).
The second part - remote properties:
<repositories> <repository> <id>lib-local</id> <name>lib</name> <url>file://${project.basedir}/lib/</url> </repository> <repository> <id>gitlab-maven</id> <url>https://gitlab.com/api/v4/groups/55048746/-/packages/maven</url> </repository> </repositories> <properties> <maven.assembly.plugin.move-lib>generate-resources</maven.assembly.plugin.move-lib> </properties>
defines:
- The repositories where the plugin should look for custom dependencies. The first lib-local link to the lib directory in you plugin project (optional), the second gitlab-maven link to the Grogra gitlab maven repository. It you to use any deployed GroIMP plugin or GroIMP third party jars as remote Maven dependencies (i.e. you can compile and package your plugin without the GroIMP source code). It is optional if the GroIMP source code it at the root of your plugin structure (as Maven look up one directory to find the defined parent).
- The additional properties, here maven.assembly.plugin.move-lib which indicates maven that your project includes a local third party jar in the lib directory. With this property the jar mylib.jar will be automatically packaged for the compilation and deploylment into the adequate directory.
The third part - dependencies:
<dependencies> <dependency> <groupId>de.grogra</groupId> <artifactId>imp2d</artifactId> <version>${groimp.core.version}</version> </dependency> <dependency> <groupId>de.grogra</groupId> <artifactId>imp3d</artifactId> <version>${groimp.core.version}</version> </dependency> <dependency> <groupId>your.remote.lib</groupId> <artifactId>yourlib</artifactId> <version>xxx</version> </dependency> <dependency> <groupId>my.local.lib</groupId> <artifactId>mylib</artifactId> <version>xxx</version> </dependency> </dependencies>
defines the dependencies to:
- the other GroIMP plugins. The groupId is always de.grogra for GroIMP plugins.
- the third party libraries. As yourlib.jar is accessible from Maven Central (i.e. deployed online), it is best to load it from there with the groupId and artifactId defined there.The mylib.jar being a local dependencies, need to be in the lib/ directory and if possible to follow the Maven format, i.e. lib/my/local/lib/xxx/mylib-xxx.jar. This is optional but enables the GroIMP maven packaging to be automatic. Otherwise you can add the mylib.jar manually to the compiled lib directory (target/lib if GroIMP run with –project-tree, or at the root of your plugin otherwise).
Finally, the build section:
<build> <finalName>${project.name}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> </plugin> </plugins> </build>
it defines that the plugin will be packaged with its <name> instead of <artifactId>. This part is common between all GroIMP plugins, usually you don't have to modify it.
Now that the Maven file is ready, you can compile, package or install you plugin with the commands: mvn compile, mvn pakcage, mvn install.
Plugin configuration (For Groimp integration)
Plugin properties
The file _plugin.properties_ must exist in the plugin path. It can be empty, but should contain the plugin name and provider. It can also include some information on the plugin license and link. Here is an example:
pluginName = The name of your plugin provider = grogra.de aboutplugin.License = GPL aboutplugin.tabs = license aboutplugin.tab.license = License aboutplugin.tab.license.content = gpl.html
The plugin.properties also include all additional text variable you want in your plugin. Which can exist in several language, see how to translate groimp plugins in other languages.
You can also define other resources to be accessible from GroIMP in the _plugin.properties_, see how to add resources in property files.
Description
Then you have to create the plugin.xml file which is read by GroIMP to obtain required information about the plugin.
<?xml version = "1.0" encoding="UTF-8"?> <plugin id="bar.foo.myplugin" version="0.0.1" xmlns="http://grogra.de/registry"> <import plugin="de.grogra.imp2d"/> <import plugin="de.grogra.imp3d"/> <library file="mylib.jar" prefixes="{bar.lib.my,foo.lib.my}"/> <library file="yourlib.jar" prefixes="{bar.lib.your}"/> <library file="MyPlugin.jar" prefixes="{bar.foo.myplugin}"/> <registry> </registry> </plugin>
The id of MyPlugin can be chosen freely, and it must match with the name defined in the maven file <groupId>.<artifactId>. It is recommended to base the id on the Java naming convention for packages. Afterwards, the plugins to import have to be specified. Note that now you have to use the id, while the build.xml file requires the name of the directory which contains the plugin (which typically differs from the id). After the imports, specify the jar-libraries to use. The registration of the libraries has to be in an order such that earlier libraries do not depend on later ones. The last library has to be a jar-file with the same name as the project, so here it is MyPlugin.jar. The library prefixes are comma-separated lists in braces, each item is the prefix of packages which are present in the jar-file. This is used as a hint for class loaders.
Groimp menu entries
Within the registry-element, the actual content of the plugin is registered. You can look at this page for more information on GroIMP's registry structure.
Embedded documentation
The embedded documentation of GroIMP is based on the docbook format with the htmlhelp template. The docbook file must be created in src/main/resources/manual.xml. There are several docbook editors available online. With GroIMP 2.1.4 it is also possible to use a markdown file as a source of documentation, this file is then turned in to a docbook file and forwarded to the normal pipeline. A documentation on the Markdown based approach can be found here.
The compilation including the embedded help is described here
The linking of the embedded documentation to the help buttons of the panels is explained here
Linking an example
In order to make your plugin easier to get started with, it is recommended to add an example project with it. The example projects are available in GroIMP from the project panel.
To include an example project,the gsz file needs to be placed in 'src/main/resources' and in the plugin the project needs to be referenced in the plugin.xml
file with:
<ref name="examples"> <directory name="CATEGORYNAME" optionCategory="true"> <projectDir name="PROJECTNAME"> <directory name="PROJECTVERSION"> <FilterSourceFactory name="FACTORYNAME"> <resource name="PROJECTFILE.gsz" /> </FilterSourceFactory> </directory> <!-- in the case where several versions of the projects are available --> <directory name="OTHERVERSION"> <FilterSourceFactory name="FACTORYNAME"> <resource name="OTHERFILE.gsz" /> </FilterSourceFactory> </directory> </projectDir> <directory/>
Where:
- ref name=“examples” is the example registry folder.
- CATEGORYNAME is the category where the example will be grouped.
- PROJECTNAME is a name, that is used by default when displayed. But it can be overwritten in the properties.
- PROJECTVERSION is the version. One project can have several versions. They will all be available in the project explorer, by selecting them in the drop-down menu. Versions of one project need to be added within the same tag
projectDir
. The other versions will be defined with an OTHERVERSION. - FACTORYNAME is the default name displayed. Can be overwritten in the properties.
- PROJECTFILE.gsz (and any OTHERFILE.gsz) the relative path to access the project file. Usually, both the
plugin.xml
file and thePROJECTFILE
are insrc/main/resources/
.
The displayed name can be changed in the plugin.properties
file:
/examples/CATEGORYNAME.Name = any name you want /examples/CATEGORYNAME/PROJECTNAME.ProjectName = ... /examples/CATEGORYNAME/PROJECTNAME.ShortDescription = ... /examples/CATEGORYNAME/PROJECTNAME.Image = `image IMAGEPATH.png` /examples/CATEGORYNAME/PROJECTNAME.Category = ... /examples/CATEGORYNAME/PROJECTNAME.Authors = ... /examples/CATEGORYNAME/PROJECTNAME.Tags = ...
Linking a Template
Similar to the examples a FilterSourceFactory can be used to add new templates. Templates are the files that can be selected by creating a new project 'File/new/…'. To add a gsz file stored in 'src/main/resources' as a template it must be added in the template directory:
<ref name="ui"> <ref name="templates"> <FilterSourceFactory name="myTemplate"> <resource name="my_template.gsz"/> </FilterSourceFactory> </ref> </ref>
Additionally the name shown in the menu can be set in the properties file.
See more: