Skip to content

04. Nalu Processor Plugin

github-actions[bot] edited this page Oct 13, 2024 · 6 revisions

Nalu Processor Plugins

At the moment we see two different types of widget sets in the GWT world. On the one side we have widgets based on GWT Widget-class (like GWT itself, GXT, SmartGWT, etc.). To add a widget to another the well-know add-method is used.

On the other side we have widgets based on the HTMLElement-class (f.e.: Elemento, Domino-UI, etc.). HTMLElement-widgets adds another widget by calling the appendChild-method.

The differences in the way how widgets are added to the DOM forces Nalu to use different implementations. To avoid that Nalu delivers both implementations (and therefore will add a dependency to GWT), Nalu provides a plugin mechanism, that separate these classes.

Currently available are plugins for:

  • Widget-based libraries

  • HTMLElement-based libraries

Plugin Interface

To avoid creating a dependency to GWT Widget-class or to Elemental2 HTMLElement, Nalu outsourced the depending on classes into a plugin.

The plugin interface provides a set of methods, that needed to be outsourced (because they are platform dependent).

The plugin interface:

public interface IsNaluProcessorPlugin {

  void alert(String message);

  boolean attach(String selector,
                 Object asElement);

  boolean confirm(String message);

  String getStartRoute();

  Map<String, String> getQueryParameters();

  void register(RouteChangeHandler handler);

  void remove(String selector);

  void route(String newRoute,
             boolean replace);

  void initialize(ShellConfiguration shellConfiguration);

  @FunctionalInterface
  interface RouteChangeHandler {

    void onRouteChange(String newRoute);

  }

}

The methods of the ÌsPlugin-interface are:

  • alert(String message): display the message text inside a popup

  • attach(String selector, Object asElement): these methods add the asElement-object to the DOM using the selector

  • confirm(String message): open a popup with the message and requests a yes-no-decision

  • getStartRoute(): returns the start route which will be used in cased the application is started without a bookmark

  • getQueryParameters(): returns a map containing the url parameters at application start

  • initialize(ShellConfiguration shellConfiguration): resetting the context inside the plugin

  • register(HashHandler handler): register a hash handler. will be called in case the hash changes

  • remove(String selector): removes everything located under the DOM element with the id selector

  • route(String newRoute, boolean replace): add the new route (as hash) to the url. if replace is false the hash did not get updated

Currently, there are two existing plugins:

  • a Domino-UI (Version 2) Plugin for widget sets based on org.dominokit.domino.ui.IsElement
  • an Elemental2 plugin for widget sets based on HTMLElement
  • an Elemento plugin for widget sets based on HTMLElement or IsElement
  • a GWT plugin for widget sets based on GWT Widget

Domino-UI (Version 2) based Widget Sets

In case your widget set is based on Domino-UI (Version 2), you should use, the nalu-plugin-domino-v2.

Configure the Application

To use the plugin, you have to add the following lines to your pom:

    <dependency>
      <groupId>com.github.nalukit</groupId>
      <artifactId>nalu-plugin-domino-v2</artifactId>
      <version>LATEST</version>
    </dependency>

Using the plugin

To tell Nalu, that the application is using the Domino-UI-V2 plugin, you have to create the plugin and use the instance as a parameter of the run method:

public class Application
  implements EntryPoint {

  public void onModuleLoad() {
    // Create the application.
    // The ApplicationImpl-class will be generated by the framework.
    MyApplication application = new MyApplicationImpl();
    // start the application by calling the run()-method.
    application.run(new NaluPluginDominoV2());
  }
}

To define a node of the DOM as an extension point where children can be added, just set an id using the id-attribute. The selector attribute inside the @Controller-annotation will be used to look for a node inside the DOM with the selector value as id. Once the node is found, all children of the node will be removed and the new child added.

Elemental2 based Widget Sets

In case your widget set is based on Elemental2, you have to use, the nalu-plugin-elemental2.

Configure the Application

To use the plugin, you have to add the following lines to your pom:

    <dependency>
      <groupId>com.github.nalukit</groupId>
      <artifactId>nalu-plugin-elemental2</artifactId>
      <version>LATEST</version>
    </dependency>

Using the plugin

To tell Nalu, that the application is using the Elemental2 plugin, you have to create the plugin and use the instance as a parameter of the run method:

public class Application
  implements EntryPoint {

  public void onModuleLoad() {
    // Create the application.
    // The ApplicationImpl-class will be generated by the framework.
    MyApplication application = new MyApplicationImpl();
    // start the application by calling the run()-method.
    application.run(new NaluPluginElemental2());
  }
}

To define a node of the DOM as an extension point where children can be added, just set an id using the id-attribute. The selector attribute inside the @Controller-annotation will be used to look for a node inside the DOM with the selector value as id. Once the node is found, all children of the node will be removed and the new child added.

Elemento based Widget Sets

In case your widget set is based on Elemento, you have to use, the nalu-plugin-elemento.

Configure the Application

To use the plugin, you have to add the following lines to your pom:

    <dependency>
      <groupId>com.github.nalukit</groupId>
      <artifactId>nalu-plugin-elemento</artifactId>
      <version>LATEST</version>
    </dependency>

Using the plugin

To tell Nalu, that the application is using the Elemento plugin, you have to create the plugin and use the instance as a parameter of the run method:

public class Application
  implements EntryPoint {

  public void onModuleLoad() {
    // Create the application.
    // The ApplicationImpl-class will be generated by the framework.
    MyApplication application = new MyApplicationImpl();
    // start the application by calling the run()-method.
    application.run(new NaluPluginElemento());
  }
}

To define a node of the DOM as an extension point where children can be added, just set an id using the id-attribute. The selector attribute inside the @Controller-annotation will be used to look for a node inside the DOM with the selector value as id. Once the node is found, all children of the node will be removed and the new child added.

GWT based Widget Sets

In case your widget set is based on the GWT Widget-class, you have to use, the nalu-plugin-gwt.

Configure the Application

To use the plugin, you have to add the following lines to your pom:

    <dependency>
      <groupId>com.github.nalukit</groupId>
      <artifactId>nalu-plugin-gwt</artifactId>
      <version>LATEST</version>
    </dependency>
    <dependency>
      <groupId>com.github.nalukit</groupId>
      <artifactId>nalu-plugin-gwt-processor</artifactId>
      <version>LATEST</version>
    </dependency>

In opposite to the Elemental2 plugin the GWT plugin needs another processor.

Using the plugin

To tell Nalu, that the application is using the GWT plugin, you have to create the plugin and use the instance as a parameter of the run method:

public class Application
  implements EntryPoint {

  public void onModuleLoad() {
    // Create the application.
    // The ApplicationImpl-class will be generated by the framework.
    MyApplication application = new MyApplicationImpl();
    // start the application by calling the run()-method.
    application.run(new NaluPluginGWT());
  }
}

Because of the different way GWT sinks events, etc. Nalu uses the add-method of the Widget-class to append a child. Using these plugins a little bit more work. The application has to create a method for every extension point and annotate the method with @Selector. A method annotated with @Selector must accept one parameter (type is Widget).

The last thing, the application has to do, is trigger the processor by calling:

   IsSelectorProvider<Shell> provider = new MySelectorProviderImpl();
   provider.initialize(this);

Nalu will use the simple name of the class and add the string 'SelectorProviderImpl'. In case you want to set a provider for a class which is called 'contentComponent', the generated provider will be named: 'ContentComponentSelectorProviderImpl'!

In case you are not sure, what's the name of the generated class is, take a look at 'target/generated-sources/annotations'.

A good place to trigger the processor is the component bind-method.

Here is an example of a Shell class using the GWT plugin:

@Shell("applicationShell")
public class ApplicationShell
  extends AbstractCompositeShell<MyApplicationContext> {

  public Shell() {
    super();
  }

  ...

  @Override
  public void bind() {
    IsSelectorProvider<Shell> provider = new ShellSelectorProviderImpl();
    provider.initialize(this);
  }

  @Selector("content")
  public void setContent(Widget widget) {
    // add the widget ...
  }

  @Selector("sideNav")
  public void setNavigation(Widget widget) {
    // add the widget ...
  }
}

Custom Plugin

Creating a new plugin is quite simple. One of the junit tests of Nalu needed a plugin that runs in batch mode. A new plugin was created and used by the test. Instead of the Widget- or HTMLElement-class, this plugin handles String.

You will find the test case here:

JUnit test case with a custom plugin

One interesting point of the test case is, that Nalu works outside the GWT ecosystem. So, it can be expected, that Nalu can be used on server side (with servlets) or with Android, etc.