OpenWGA 7.0 - OpenWGA Concepts and Features

Design and development » Service APIs

Providing additional service APIs and implementations

OpenWGA modules can provide additional implementations for existing services APIs or could even define new service APIs where implementations could be registered.

The process to do both uses the OpenWGA module registry and simply involves registering additional module definitions for either APIs themselves or API implementations. See the instructions on OpenWGA java modules on how to register modules.

Definining service APIs

First step of defining a new service API is to create an implementation class for it. This is either a Java interface or base class that all implementors of the service must implement/extend. 

Second step (which is not necessary for single implementation services) is to create a module type class, implementing de.innovationgate.wga.modules.DeclaringModuleType, which should be the type by which implementations of your service API need to be registered. Here the method getImplementationBaseClass() should return your service API interface created before. All boolean methods on this class should return false. Method getPropertyClass() should return null.

For example: The module type for the service API to scale images:

public class ImageScalerModuleType implements DeclaringModuleType {


    public String getDescription() {

        return "A tool object to scale image data from TMLScript. OpenWGA will use the first-best that is registered.";

    }


    public String getTitle() {

        return "Image scaler module type";

    }


    public boolean isKeyBased() {

        return false;

    }


    public boolean isSelfRegistered() {

        return false;

    }


    public Class<? extends Object> getImplementationBaseClass() {

        return ImageScaler.class;

    }


    public boolean isPropertiesNeeded() {

        return false;

    }


    public Class<? extends Object> getPropertyClass() {

        return null;

    }


}

As last step create a module definition for the service API and register it in your registrar which should have the following characteristics:

  • Use class de.innovationgate.wga.modules.types.ServiceApiType on getModuleType()
  • Return the module type created in step two in getImplementationClass()
  • Implement de.innovationgate.wga.modules.KeyBasedModuleDefinition and in its method getRegistrationKey() return the name of the service API interface class as String
  • in getProperties() you may return an object of type de.innovationgate.wga.modules.types.ServiceApiProperties to give further specifications
    • setDefaultImplementation() may set the class of a service implementation that should be active by default, without anyone configuring
    • setImplementable() may set if there should actually be multiple implementations. Setting false means that always the default implementation will be used and there will be no configuration opportunity (see section below about single implementation classes)
    • setOptionalConfig() determines if the configuration of the service API implementation in admin client should be optional (i.e. it is not shown until the option is manually added)
  • Do not return any options on getOptionDefinitions() as OpenWGA will not use them

For example, the module definition foir the image scaler service API:

public class ImageScalerApiModuleDefinition implements ModuleDefinition, KeyBasedModuleDefinition {



    protected LocalisationBundleLoader _bundleLoader = 

      new LocalisationBundleLoader(WGUtils.getPackagePath(getClass()) + "/apis", getClass().getClassLoader());


    @Override

    public String getTitle(Locale locale) {

        return _bundleLoader.getBundle(locale).getString("scaler.title");

    }


    @Override

    public String getDescription(Locale locale) {

        return _bundleLoader.getBundle(locale).getString("scaler.description");

    }


    @Override

    public OptionDefinitionsMap getOptionDefinitions() {

        return null;

    }


    @Override

    public Class<? extends ModuleType> getModuleType() {

        return ServiceApiType.class;

    }


    @Override

    public Class<? extends Object> getImplementationClass() {

        return ImageScalerModuleType.class;

    }


    @Override

    public void testDependencies() throws ModuleDependencyException {

    }


    @Override

    public Object getProperties() {

        ServiceApiProperties props = new ServiceApiProperties();

        return props;

    }


    @Override

    public String getRegistrationKey() {

        return ImageScaler.class.getName();

    }


}


You can also create a service where always objects of  a single implementation class are returned and where no multiple implementations are allowed, just to provide a way to access that otherwise static service. In that special case modify the process like this:

  • Use this single implementation as your interface API in step one
  • Skip the module type creation on step two
  • On the module definition of the last step return your single implementation also in getImplementationClass() and return a ServiceApiProperties object in getProperties() having setImplementable() set to false and setDefaultImplementation() set to your single implementation class

Providing API implementations

A class that wants to implement a service API must have the following characteristics:

  • It should implement/extend the API interface class
  • It should have a default (no-arg) constructor
  • If it needs application context to operate then it should implement interface de.innovationgate.wga.server.api.WGAAwareService. This defines a method injectWGA() on which the WGA server API object, which currently instantiates the service, will be injected to it right after its instantiation.

Then you also need to register a module definition to the module registry for your implementation:

  • Return the module type of the API (returned as implementation class on the Service API definition) on getModuleType()
  • Return your implementation cass on getImplementationClass()
  • Provide the title, which on service configuration should be used as title for this implementation, in getTitle()
  • No output on getProperties(), getOptionDefinitions() needed


For example the module definition for the Advanced Image Scaler, an implementation of the Image Scaling API, looks like this:

public class AdvancedImageScalerModuleDefinition implements ModuleDefinition {


    public String getDescription(Locale locale) {

        return "An image scaler using an advanced bicubic scaling filter";

    }


    public Class getImplementationClass() {

        return AdvancedImageScaler.class;

    }


    public Class getModuleType() {

        return ImageScalerModuleType.class;

    }


    public OptionDefinitionsMap getOptionDefinitions() {

        return null;

    }


    public Object getProperties() {

        return null;

    }


    public String getTitle(Locale locale) {

        return "Advanced Image Scaler";

    }


    public void testDependencies() throws ModuleDependencyException {

    }


}