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

Class: bop/js/spi/SimpleBOP

SPI object for creating simplified BOP implementations.

By implementing SimpleBOP, you're choosing more restricted SPI which on the other don't require that much effort to be written properly. If you're looking for pure, fully-customizable BOP with no restrictions write your own ExtensionManager and use BOP interface with BOPRegistry API object to register it into Application Builder data model.

Obviously both options (SimpleBOP and BOP) has some pros and cons. Here is short list:

SimpleBOP - Pros:

  • No need to take care of ExtensionManager lifecycle manually.
  • No need to write method generating RT code manually.
  • No need to manually define BOPs ID as it's taken automatically based on the extension ID.
  • No need to take care of BOPExtensionDependencyFormat to register only selected Entities and Properties into the Application Builder data model.
SimpleBOP - Cons:
  • You can't apply CustomParameters as you're out of control over the ExtensionManager lifecycle and thus you can't process them anyhow.
  • Generally, you're restricted only to the simplied expectations and you can't define more custom behavior.
BOP - Pros & Cons:

Version:
  • 17.1.1
Source:
See:
Example

Example of typical implementation of custom SimpleBOP with paths to your hand-written EntityProvider and OperationProvider.

define([], function () {

    var CustomBOP = function () {
    };

    CustomBOP.prototype.getEntityProviderPath = function () {
        return '{{package}}/js/CustomEntityProvider';
    };

    CustomBOP.prototype.getOperationProviderPath = function () {
        return '{{package}}/js/CustomOperationProvider';
    };

    return CustomBOP;
});

Methods

getEntityProviderPath() → {String}

stable API

Gets relative path to the corresponding EntityProvider.

Returned string can contain special {{package}} identifier which will be automatically transformed into the path that correspond to your extension top-level package.

Version:
  • 17.1.1
Source:
Returns:
Type
String
Examples

Typical implementation returning path to your hand-written EntityProvider.

CustomBOP.prototype.getEntityProviderPath = function () {
    return '{{package}}/js/CustomEntityProvider';
};

Example of typical implementation of custom EntityProvider which is used inside SimpleBOP.

define([
    'bop/js/api/entity/DataModelFactory',
    'entity/js/api/PropertyType'
], function (
    DataModelFactory,
    PropertyType
) {

    var CustomEntityProvider = function () {
        var firstname = DataModelFactory.createProperty({
            id: 'my.custom.bop.Employee.Firstname',
            name: 'Firstname',
            type: PropertyType.TEXT
        });
        var lastname = DataModelFactory.createProperty({
            id: 'my.custom.bop.Employee.Lastname',
            name: 'Lastname',
            type: PropertyType.TEXT
        });
        var age = DataModelFactory.createProperty({
            id: 'my.custom.bop.Employee.Age',
            name: 'Age',
            type: PropertyType.NUMBER
        });
        var employee = DataModelFactory.createEntity({
            id: 'my.custom.bop.Employee',
            singularName: 'Employee',
            pluralName: 'Employees',
            properties: [firstname, lastname, age]
        });

        this._entities = [employee];
    };

    CustomEntityProvider.prototype.getEntities = function() {
        return this._entities;
    };

    return CustomEntityProvider;
});

getOperationProviderPath() → {String}

stable API

Gets relative path to the corresponding OperationProvider.

Returned string can contain special {{package}} identifier which will be automatically transformed into the path that correspond to your extension top-level package.

The constructor will be passed an representation of the dependencies that can be used to access configuration parameters and configure BOPAuthenticator

Version:
  • 17.1.1
Source:
Returns:
Type
String
Examples

Typical implementation returning path to your hand-written OperationProvider.

CustomBOP.prototype.getOperationProviderPath = function () {
    return '{{package}}/js/CustomOperationProvider';
};

Example of typical implementation of custom OperationProvider used inside of the custom SimpleBOP.

define([
    'bop/js/api/operation/OperationBuilder',
    'bop/js/api/operation/OperationInput',
    'bop/js/api/operation/OperationOutput',
    'operation/js/api/Operation',
    'operation/js/api/Operator',
    '{{package}}/js/Employee'
], function (
    OperationBuilder,
    OperationInput,
    OperationOutput,
    Operation,
    Operator,
    Employee
) {

    var CustomOperationProvider = function () {
        this._operations = [];

        var employee = Abcs.Entities().findById('my.custom.bop.Employee');
        var id = employee.getProperty('my.custom.bop.Employee.ID');
        var firstname = employee.getProperty('my.custom.bop.Employee.Firstname');
        var lastname = employee.getProperty('my.custom.bop.Employee.Lastname');
        var age = employee.getProperty('my.custom.bop.Employee.Age');

        var partialOutput = new OperationOutput({
            entity: employee
        }).property(firstname).
            property(lastname);

        var idInput = new OperationInput({
            entity: employee
        }).parameter({
            property: id,
            required: true
        });

        var firstnameLastnameInput = new OperationInput({
            entity: employee
        }).parameter(firstname).
            parameter(lastname).
            operators([
                Operator.EQUALS,
                Operator.NOT_EQUALS,
                Operator.STARTS_WITH,
                Operator.ENDS_WITH,
                Operator.CONTAINS,
                Operator.NOT_CONTAINS
            ]);

        var getAllEmployees = new OperationBuilder({
            name: 'Find all Employees',
            type: Operation.Type.READ_MANY,
            performs: function() {
                // Lets assume there is an Employee object as part of our BOP extension implementation which builds the URL based
                // on the "operationInputData" values, makes the real REST call and returns relevant OperationResult instance
                return Promise.resolve(Employee.getAll());
            }
        }).description('Longer description of what this Operation does').
            returns(partialOutput).
            takes(firstnameLastnameInput).
            build();

        var getEmployeeByID = new OperationBuilder({
            name: 'Find Employee by ID',
            type: Operation.Type.READ_ONE,
            performs: function(operationInputData) {
                // Lets assume there is an Employee object as part of our BOP extension implementation which builds the URL based
                // on the "operationInputData" values, makes the real REST call and returns relevant OperationResult instance
                return Promise.resolve(Employee.findByID(operationInputData));
            }
        }).specialType(Operation.SpecialType.QUERY_BY_ID).
            takes(idInput).
            returns(employee).
            build();

        // Register all relevant operations
        this._operations.push(getAllEmployees);
        this._operations.push(getEmployeeByID);

        // ..include the same for all other REST calls
    };

    CustomOperationProvider.prototype.getOperations = function() {
        return this._operations;
    };

    return CustomOperationProvider;
});