JavaScript Extension Development API for Oracle Visual Builder Cloud Service - Classic Applications

Class: extensions.dt/js/spi/ExtensionManager

This API module allows authors of ABCS extensions to define their behaviour.

The infrastructure calls its methods ExtensionManager.initialise and ExtensionManager.destroy when the application which holds the extension is opened or closed.

It's guranteed that the infrastructure will never call ExtensionManager.initialise or ExtensionManager.destroy method twice in row. They can be called N times, but always altering.

A composite operation consisting from calls to the ExtensionManager.initialise or ExtensionManager.destroy methods must be idempotent. Which means that when the two methods are called in sequence, the state of the system must be exactly the same as before the calls.

The module path is specified in the extension manifest under the "extensionManager" key.

Version:
  • 16.3.1
Source:
Example

Simple shared object extension

define([
      'core/js/api/SharedObjectRegistry'
  ], function (sharedObjectRegistry) {
      'use strict';
      function MyExtensionManager() {
      }
      MyExtensionManager._OBJECT_ID = 'com.mycompany.extensions.myExtension.message';
      MyExtensionManager.prototype.initialise = function () {
          sharedObjectRegistry.register(MyExtensionManager._OBJECT_ID, 'Ahoy!');
          return Promise.resolve();
      };
      MyExtensionManager.prototype.destroy = function () {
          sharedObjectRegistry.unregister(MyExtensionManager._OBJECT_ID);
          return Promise.resolve();
      };
      MyExtensionManager.prototype.generateRuntimeCode = function () {
          return Promise.resolve('function() {\n\
              return new Promise(function(f,r) {\n\
                  require([\'core/js/api/SharedObjectRegistry\'], function(sharedObjectRegistry) {\n\
                      sharedObjectRegistry.register(\'com.mycompany.extensions.myExtension.message\', \'Ahoy!\');\n\
                      f();\n\
                  }, r);\n\
              });\n\
          }\n');
      };
      return new MyExtensionManager();
  });

Methods

destroy(dependencies) → {Promise}

stable API

This method is responsible for destroying of the extension.

Extension author may call any ABCS stable APIs here to remove any changes which were previously done in the ExtensionManager.initialise method from the system.

BOP extension typically un-registers its EntityProvider and OperationProvider here. Custom UI component un-register its creator, PIs, view generators etc.

The method is called by the infrastructure when the application which owns or refers the extension is destroyed (closed).

An array of ExtensionManager.Dependency objects is passed to the method. Each of them represents one dependency to the extension from a dependent object. The passed dependencies are identical to those which were previously passed to the ExtensionManager.initialise method.

This method is called only after all dependents which depends on this extension were destroyed (the destroy sequence is reverse to the initialisation sequence).

It's the responsibility of the extension itself to understand any dependencies parameters and adjust its behaviour accordingly.

Parameters:
Name Type Description
dependencies Array.<module:extensions.dt/js/spi/ExtensionManager.Dependency>

array of Dependency objects which the extension is target of.

Version:
  • 16.3.1
Source:
Returns:

promise of the extension being destroyed.

Type
Promise
Example

De-registration of a shared object

CurrentTimeExtensionManager.prototype.destroy = function (dependencies) {
   sharedObjectRegistry.unregister('com.company.abcs.extensions.currentTime');
   return Promise.resolve();
};

generateRuntimeCode(dependencies) → {Promise.<String>}

stable API

Generates a body of javascript function responsible for initialisation of the extension in runtime.

The javascript code is placed to a global extensions/shareable objects initialiser which runs when the ABCS application is initialised in runtime.

If this extension has dependencies to other shareable objects, these shareable objects will be initialised before the code returned from this method runs.

The returned code must contain a function body and the function must return a Promise object. The promise must only be resolved when the code finishes its work which means the extension is initialised in the runtime environment.

During the runtime application artefact generation, the extensions are initialised according to the applications dependencies in similar manner as in design time.

Note: You may use several techniques to built the code in text form:

  • return the code as a string - simple variant, allows to easily generate the code based on the input parameters passed via the dependencies, however it's bit more error prone as you need to properly escape the content of the string.
  • alternatively if your code is long and complex enough, you can keep it as a separate file in the sources of the extension and then load that module using the the requirejs text plugin. This way you can also easily make the file a template and use some templating mechanism to resolve templating variables. This method spares you the painful escaping of the previous simple method.
  • use Function.toString() - you can simply declare the required function in code form (not as string) and then use the Function.toString() method to convert the code to the required textual form.
Parameters:
Name Type Description
dependencies Array.<module:extensions.dt/js/spi/ExtensionManager.Dependency>

array of Dependency objects which the extension is target of.

Version:
  • 16.3.1
Source:
Returns:

promise of javascript code in text form

Type
Promise.<String>
Examples

Trivial synchronous initialisation code

ExtensionManager.prototype.generateRuntimeCode = function() {
return 'function () {\n\
   return Promise.resolve();\n\
 }\n';
}

Trivial synchronous initialisation code using the Function.toString() method of producing the code

ExtensionManager.prototype.generateRuntimeCode = function() {
     return function () {
         return Promise.resolve();
     }.toString();
}

More complex asynchronous initialisation code

ExtensionManager.prototype.generateRuntimeCode = function() {
return 'function () {\n\
   return new Promise(function (f, r) {\n\
       require([\'yourPackage/js/YourModule\'], function (YourModule) {\n\
          //if the initialisation itself is asynchronous don\'t forget the resolve the promise\n\
          //when the initialisation finishes, e.g.:\n\
          YourModule.getPromiseOfSomethingAsync().then(f).catch(r);\n\
       }, r);\n\
   });\n\
 }\n';
}

Using the separate runtime code template

define([
      'core/js/api/SharedObjectRegistry',
      'text!com.mycompany.extensions.myExtension/templates/RuntimeInitialiser.js'
      ], function (
          sharedObjectRegistry,
          runtimeInitialiserTemplate
          ) {
      'use strict';
      function MyExtensionManager() {
      }
      MyExtensionManager._OBJECT_ID = 'com.mycompany.extensions.myExtension.message';
      ...
      MyExtensionManager.prototype.generateRuntimeCode = function () {
          //possibly resolve templating variables used in the templates/RuntimeInitialiser.js file here
          return runtimeInitialiserTemplate;
      };
      return new MyExtensionManager();
 });

initialise(dependencies) → {Promise}

stable API

This method is responsible for initialisation of the extension.

Extension author may call any ABCS stable APIs here to "install" the extension to the VM. For example BOP extension typically registers its EntityProvider and OperationProvider in this method. Custom UI component register its creator, PIs, view generators etc. here.

The method is called by the infrastructure when the application which owns or refers the extension is initialised (opened).

An array of ExtensionManager.Dependency objects is passed to the method. Each of them represents one dependency to the extension from a dependent object.

It is guaranteed that this method is called only after all dependencies which this extension has have been resolved which means the corresponding dependency targets (extensions or more generic shareable objects) are initialised.

It's the responsibility of the extension itself to understand any dependencies parameters and adjust its behaviour accordingly.

Parameters:
Name Type Description
dependencies Array.<module:extensions.dt/js/spi/ExtensionManager.Dependency>

array of Dependency objects which the extension is target of.

Version:
  • 16.3.1
Source:
Returns:

promise of the extension being initialised.

Type
Promise
Example

Registration of a shared object

CurrentTimeExtensionManager.prototype.initialise = function (dependencies) {
   sharedObjectRegistry.register('com.company.abcs.extensions.currentTime', CurrentTime);
   return Promise.resolve();
};

Type Definitions

ExtensionDependencyFormat

stable API

Defines the format of the dependency to an ABCS extension.

Properties:
Name Type Description
sourceType string

Type of the source object which provides the referred extension.

If the source object represents an application, the value of the key needs to be 'application'.

sourceId string

Id of the source object which provides the referred extension.

Typically the value is an application ID.

Please beware this is application ID, not project ID. The application ID includes the application version.

extensionId string

Id of the referred extension.

Version:
  • 16.3.1
Source:
Example

An example of a dependency to an extension

{
     sourceType: 'application',
     sourceId: 'myApplication-1.0',
     extensionId: 'com.mycompany.abcs.extensions.myTwitterBOP'
}

ExtensionManifestFormat

stable API

Defines the format of extension manifest.

Properties:
Name Type Description
id string

The extension ID. Needs to be unique - so ideally w/ a namespace.

displayName string

Human readable name of the extension.

description string

Human readable description of the extension.

type string

Defines type of the extension. Types are defined in ExtensionType .

package string

The AMD modules package.

All the AMD modules which makes the extension needs to use this package to refer to each other. The designer is responsible for configuring the requirejs packages appropriately in both DT and RT.

The package also needs to be unique

extensionManager string

Path of an AMD module which returns object used to control the extension in design time. The path must begin with the value of 'package' key.

The returned object needs to "implement" (contain its methods) the extensions.dt/js/spi/ExtensionManager module.

runtime string

Runtime section of the manifest.

resources string

Contains a list of resources which needs to be exported to the generated application artefact (for runtime).

Please note that these are resource files references (no module names) so the paths needs to contain extensions even for javascript files.

dependencies string

Contains an array of dependencies descriptions of the extension.

Version:
  • 16.3.1
Source:
Example

An example manifest

{
 "id": "com.mycompany.myComponent",
 "displayName": "My Component",
 "description": "My First UI Custom Component",
 "type": "uicomponent",
 "package": "com.mycompany.myComponent",
 "extensionManager": "com.mycompany.myComponent/js/ExtensionManager",
 "runtime": {
    "resources": [
        "js/Constants.js",
        "js/Initialiser.js",
        "templates/blackbox.html",
        "images/oracle.gif"
    ]
 },
 "dependencies": [
    {
        sourceType: 'application',
        sourceId: 'myApplication-1.0',
        extensionId: 'com.mycomp.abcs.extensions.myTwitterBOP'
    }
 ]
}

ExtensionType

stable API

Defines types of ABCS extensions.

Properties:
Name Type Description
uicomponent string

Visual/UI custom component.

sharedObject string

Application wide shared custom object.

businessObjectsProvider string

Business Objects Provider.

theme string

Theme

Version:
  • 16.3.1
Source: