In this tutorial we will show you the steps to create a simple plentyBase plugin.
We recommend using an IDE which supports the Java language and Gradle. To get started, install IntelliJ.
For our plugin we need at least two dependencies. One of them is plentyBase itself and the other one is the
plugin framework (pf4j).
Later we will add some more elements to our build.gradle.
You will find the complete build.gradle in the extras section on this page or in the
github
repository.
dependencies { // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.1' compileOnly fileTree(dir: 'C:\Program Files (x86)\plentyBase', include: '*.jar') // On gradle 5.0 and newer you have to set the annotationProcessor. On older versions it will get called automatically annotationProcessor fileTree(dir: 'C:\Program Files (x86)\plentyBase', include: '*.jar') // https://mvnrepository.com/artifact/org.pf4j/pf4j/2.6.0 compileOnly group: 'org.pf4j', name: 'pf4j', version: '2.6.0' // On gradle 5.0 and newer you have to set the annotationProcessor. On older versions it will get called automatically annotationProcessor group: 'org.pf4j', name: 'pf4j', version: '2.6.0' }
Add this dependency
compileOnly fileTree(dir: 'C:\Program Files (x86)\plentyBase', include: '*.jar')
to your dependencies block.
Don't forget to set the annotationProcessors for both dependencies
Create a new class which extends from org.pf4j.Plugin. If you don't implement this class it will be implemented automatically by the framework.
After that you will be encouraged to implement the constructor and some missing methods like
public void start()
public void stop()
public void delete()
package helloworld; import org.pf4j.Plugin; import org.pf4j.PluginException; import org.pf4j.PluginWrapper; public class HelloWorldPlugin extends Plugin { /** * Constructor to be used by plugin manager for plugin instantiation. * Your plugins have to provide constructor with this exact signature to * be successfully loaded by manager. * * @param wrapper */ public HelloWorldPlugin(PluginWrapper wrapper) { super(wrapper); } @Override public void start() throws PluginException { } @Override public void stop() throws PluginException { } @Override public void delete() throws PluginException { } }
After this it is possible to add some more extras like:
You can add some entries to the plugin section in the context menu.
In order to extend the context menu you need to create a new class which implements the PopupMenuExtension class.
You will have to implement the method buildMenu in which you can create the menu and its actions.
Lastly, you have to add the @Extension annotation to the class so plentyBase can find and load your extension.
This is what the extension looks like in the hello world plugin
package helloworld.extensions; import com.plentymarkets.tool.plugins.api.extensions.PopupMenuExtension; import org.pf4j.Extension; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @Extension public class MenuExtension implements PopupMenuExtension { @Override public void buildMenu(Menu menu) { MenuItem menuItem = new MenuItem("Hello world!"); menuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Hello world!"); } }); menu.add(menuItem); } }
You can extend the plentyBase REST-api.
In order to extend the plentyBase REST-api you need to create a new class which implements the ServletExtension class.
You will have to implement the method getServlets in which you can create the new servlets.
Lastly, you have to add the @Extension annotation to the class so plentyBase can find and load your extension.
This is what the extension looks like in the hello world plugin
package helloworld.extensions; import com.plentymarkets.tool.plugins.api.extensions.ServletExtension; import helloworld.HelloWorldServlet; import org.pf4j.Extension; import javax.servlet.http.HttpServlet; import java.util.HashMap; import java.util.Map; @Extension public class HttpServletExtension implements ServletExtension { @Override public Map<String, HttpServlet> getServlets() { Map<String, HttpServlet> httpServletMap = new HashMap<>(); httpServletMap.put("/helloworld", new HelloWorldServlet()); return httpServletMap; } }
This is the corresponding HelloWorldServlet class:
package helloworld; import org.apache.http.entity.ContentType; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class HelloWorldServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType(ContentType.TEXT_HTML.getMimeType()); PrintWriter printWriter = resp.getWriter(); printWriter.println("Hello world from http servlet!"); } }
Your new routes will be placed under https://local.plentybase.de:7331/plugins/your-plugin-id/.
In the case of the hello world plugin the full endpoint is https://local.plentybase.de:7331/plugins/helloworld/helloworld.
You can add listeners to some events to get notified if those events are called.
You can even add your own events as you can see in the example.
This is what the extension looks like in the hello world plugin
package helloworld.extensions; import com.plentymarkets.tool.core.event.BaseEventListener; import com.plentymarkets.tool.core.event.EventBean; import com.plentymarkets.tool.plugins.api.extensions.EventExtension; import org.pf4j.Extension; import java.util.HashMap; import java.util.Map; @Extension public class EventListenerExtension implements EventExtension { @Override public Map<String, BaseEventListener> getEventListeners() { Map<String, BaseEventListener> eventListenerMap = new HashMap<>(); eventListenerMap.put("helloworld", new BaseEventListener() { @Override public void fireEvent(EventBean eventBean) { System.out.println("Hello world!"); } }); return eventListenerMap; } }
In the root of your resource directory in your project you can create a default configuration for your plugin in case there is no current configuration in your plugin data directory.
You have to create a json file called defaults.json in which you have to add your configuration parameters.
This file will be loaded if there is no configuration found.
resources/defaults.json
{ "key_one": "value_one", "key_two": true, "key_three": false, "key_four": 1234 }
To get the configuration of your plugin and the logger with file logging you need to create a new class in which
an object of PluginApplicationContext will be inserted when the plugin starts.
From this object you will get configuration and logger.
First, create a new class and set the @PluginContext annotation to it.
Then create a new static variable of type PluginApplicationContext.
Lastly, you need a static method for injecting the object. The method needs the @ContextInjector as annotation
and one parameter of type PluginApplicationContext where to set the class variable.
This is what it looks like in hello world plugin:
package helloworld; import com.plentymarkets.tool.plugins.api.context.ContextInjector; import com.plentymarkets.tool.plugins.api.context.PluginApplicationContext; import com.plentymarkets.tool.plugins.api.context.PluginContext; import org.apache.logging.log4j.Logger; @PluginContext public class PluginAppContext { protected static PluginApplicationContext pluginApplicationContext; @ContextInjector public static void inject(PluginApplicationContext context) { pluginApplicationContext = context; } public static Logger getPluginLogger() { return pluginApplicationContext.getPluginLogger(); } }
In the manifest you will need to add some information like
task uberJar(type: Jar) { manifest { attributes( "Plugin-Class": "helloworld.HelloWorldPlugin", "Plugin-Id": "hello-world", "Plugin-Version": "1.0.0", "Plugin-Description": "Description of my plentyBase plugin", "Plugin-Provider": "plentysystems AG" "Plugin-Requires": "1.6.0", "Plugin-Dependencies": x, y, z, "Plugin-License": "Apache License 2.0" ) } from sourceSets.main.output dependsOn configurations.runtimeClasspath from { configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) } } }
In order to debug your plugin you have to use the remote debug run configuration in IntelliJ.
In your plentyBase installation directory you'll find a file called vmoptions.txt in which you have to uncomment the following line:
`-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005`
Setting the suspend parameter to y lets plentyBase wait for your plugin to connect before it starts.
Now you only have to start plentyBase and then start your remote debug run connfiguration in your plugin.
Once you are ready you can build your project. Open your build.gradle and click on the little green play icon next to the new task
or execute the uberJar task.
After the build finished without any errors you will find your plugin .jar in build → libs.
There are three ways of installing your plugin in plentyBase.
One way is to take your plugin.jar and copy it to the plugin location of plentyBase.
The default location is:
On Windows:
%LocalAppData%\plentymarkets\plentybase\PluginProductive
On macOS:
~/Library/Caches/eu.plentymarkets.plentybase/PluginProductive
on Linux:
~/.plentybase/PluginProductive
After you copied the file you have to restart plentyBase.
Another way is to install your plugin on the plentyBase → Plugins page in your plentymarkets backend.
After installing the plugin this way you don't need to restart plentyBase. Your plugin starts automatically.
You can either use an API development tool like
Postman
to install a plugin in plentyBase
or you can create a new task in build.gradle to install your plugin in plentyBase.
First, you have to add a new plugin to your build.gradle.
Add the following line to the plugins {} section in your build.gradle:
id "io.github.http-builder-ng.http-plugin" version "0.1.1"
Following this you need to add some imports. You have to add these lines to the top of your gradle file:
import io.github.httpbuilderng.http.*
import groovyx.net.http.*
import static groovyx.net.http.MultipartContent.multipart
The last step is to add the install task:
task installPlugin(dependsOn: uberJar, type: HttpTask) { config { request.uri = 'https://local.plentybase.de:7331' } post { request.uri.path = '/plugins/install' request.contentType = 'multipart/form-data' request.headers['Authorization'] = '' request.body = multipart { field 'activated', 'true' part 'plugin', jar.getArchiveFileName().get(), 'application/java-archive', jar.getArchiveFile().get().asFile } request.encoder 'multipart/form-data', OkHttpEncoders.&multipart request.encoder('application/java-archive') { ChainedHttpConfig config, ToServer req -> req.toServer(new ByteArrayInputStream(jar.getArchiveFile().get().asFile.bytes)) } response.success { println "Successful" } } }