Skip to end of metadata
Go to start of metadata

Setting a value depending on a change

In the first example a function subscribes on changes of Projects. If a Project is changed and the "Costs" property is larger than "80", the costs are set to "80".

Download example: SettingValues.js

'use strict';

api.subscribeFor('Project', onBuildingBlockChange);

function onBuildingBlockChange(buildingblocktype, event) {
    for (var index = 0; index < event.length; index++) {
        var change = event[index];

        if (change.changeType == 'UPDATE') {

            var changedObject = api.datamodel.findByTypeAndId('Project', change.id);
            
            if (changedObject.getValue("Costs") > 80){
                changedObject.setValue("Costs", 80);
            }
        }
    }
}

Setting values of parents

In the second example a script subscribes for changes of Information Systems.

If an Information System is added, it's costs are set to "33". If it has a superordinate Information System, the costs of the inserted Information System is added to the costs of the superordinate Information System. If the superordinate Information System does not have the "Costs" attribute, it obtains the costs of the child.

Download example: ValuesOfParent.js

'use strict';

api.subscribeFor('InformationSystem', onBuildingBlockChange);

function onBuildingBlockChange(buildingblocktype, event) {
    for (var index = 0; index < event.length; index++) {
        var change = event[index];

        if (change.changeType == 'INSERT') {

            var changedObject = api.datamodel.findByTypeAndId('InformationSystem', change.id);
            changedObject.setValue("Costs", 33);
            
            var parent = changedObject.getRelatedObject("parent");
            
            if (parent) {       
                var parentCost = parent.getValue("Costs");

                if (changedObject.getValue("Costs")){
                    if (!parentCost) {
                        parent.setValue("Costs", changedObject.getValue("Costs"));
                    } else {
                        parent.setValue("Costs", parentCost+changedObject.getValue("Costs"));
                    }
                }    
            }
        }
    }
}

Changing related elements

In the next example two functions subscribe for different building block types.

If an Information System is changed, but not deleted, "bob" becomes accountable for all related Technical Components. If a Technical Component is changed, we add all entries of its accountability to the related Infrastructure Elements.

Download example: ValuesOfDifferentType.js

'use strict';

api.subscribeFor('InformationSystem', onInformationSystemChange);
api.subscribeFor('TechnicalComponent', onTechnicalComponentsChange);

function onInformationSystemChange(buildingblocktype, event) {
    for (var index = 0; index < event.length; index++) {
        var change = event[index];
        print(change.changeType + ' of InformationSystem with ID ' + change.id);

        if (change.changeType != 'DELETE') {
            var changedObject = api.datamodel.findByTypeAndId('InformationSystem', change.id);
            var relatedTechnicalComponents = changedObject.getRelatedObjects('technicalComponentReleases');
            for (var i = 0; i < relatedTechnicalComponents.length; i++) {
                relatedTechnicalComponents[i].addValue('Accountability', 'bob');
            }
        }
    }
}

function onTechnicalComponentsChange(buildingblocktype, event) {
    for (var index = 0; index < event.length; index++) {
        var change = event[index];
        print(change.changeType + ' of TechnicalComponent with ID ' + change.id);

        if (change.changeType != 'DELETE') {
            var changedObject = api.datamodel.findByTypeAndId('TechnicalComponent', change.id);
            var relatedAssociations = changedObject.getRelatedObjects('infrastructureElementAssociations');
            var relatedInfrastructureElements = new Array(0);
            for (var m = 0; m < relatedAssociations.length; m++) {
                relatedInfrastructureElements.push(relatedAssociations[m].getRelatedObject('infrastructureElement'));
            }
            var accountability = changedObject.getValues('Accountability');
            for (var i = 0; i < relatedInfrastructureElements.length; i++) {
                for (var j = 0; j < accountability.length; j++) {
                    relatedInfrastructureElements[i].addValue('Accountability', accountability[j]);
                }
            }
        }
    }
}

Generating a set of enums values like it was before the changes

In the following example we react on changes of the accountability attribute. Each time the accountability is changed, we print the set of the persons that were accountable for the Information System before the change.

By adapting this example it is possible to obtain the set of values before the change for arbitrary multivalue enums.

Download example: SetBefore.js

'use strict';

api.subscribeFor('InformationSystem', onBuildingBlockChange);

function onBuildingBlockChange(buildingblocktype, event) {
    for (var index = 0; index < event.length; index++) {
        var change = event[index];

        if (change.changeType == 'UPDATE') {
            var changedObject = api.datamodel.findByTypeAndId('InformationSystem', change.id);

            var buildingBlockChanges = change.buildingBlockChanges;

            for (var i = 0; i < buildingBlockChanges.length; i++) {

                if (buildingBlockChanges[i].persistentName == "Accountability") {
                    var changesOfAccountability = buildingBlockChanges[i];

                    //We start with the current set
                    var setBeforeChange = changedObject.getValues("Accountability");

                    //Then we add the values that were removed with the change
                    if (changesOfAccountability.removed) {
                        setBeforeChange = setBeforeChange.concat(changesOfAccountability.removed);
                    }

                    //Finally we only keep the values that are not added by the change
                    if (changesOfAccountability.added) {
                        setBeforeChange = setBeforeChange.filter(
                            function (item) {
                                return changesOfAccountability.added.indexOf(item) == -1;
                            }
                        )
                    }

                    //Now we can print the set like it was before the change
                    print("The set before the changes: " + setBeforeChange);
                }
            }
        }
    }
}

Create Seals using reactions

The next example shows how the functionality of seals can be realised as plugin.

Therefore a new enum attribute called "Seal" has to be created with the values "Valid" and "Invalid". The attribute should be created in its own attribute group. Then one can set the permissions for this group so only authorized users can change the seal.

The following plugin reacts on changes of Information Systems.The seal of the Information System becomes invalid, when the seal was valid before and the value of the seal itself is not changed. Then the value of the Seal-attribute is set to "Invalid". This is possible as the plugins are independent of the permissions of the user.

Download example: Seal.js

'use strict';

api.subscribeFor('InformationSystem', onBuildingBlockChange);

function onBuildingBlockChange(buildingblocktype, event) {
    for (var index = 0; index < event.length; index++) {
        var change = event[index];

        if (change.changeType == 'UPDATE') {
            var changedObject = api.datamodel.findByTypeAndId('InformationSystem', change.id);

            //Check if there was a valid seal before, otherwise nothing to do
            if (changedObject.getValue("Seal") == "Valid") {
                var changeSeal = true;

                //Check if the property seal was changed
                //in this case the seal is not changed again
                //otherwise it would become impossible to set the seals to valid
                var buildingBlockChanges = change.buildingBlockChanges;
                for (var i = 0; i < buildingBlockChanges.length; i++) {
                    if (buildingBlockChanges[i].persistentName == "Seal") {
                        var changeSeal = false;
                    }
                }

                if (changeSeal) {
                    changedObject.setValue("Seal", "Invalid");
                }
            }
        }
    }
}

List names of attributes and relations

In this example a script subscribes to changes on every building block type that has a name and description.

If a building block with the name "__reaction" is added, the script will generate a list with names of all attributes and relations this building block type supports, then save it to the new building block's description.

Download example: GetNames.jsResult screenshot

'use strict';

api.subscribeFor('BusinessDomain', getNames);
api.subscribeFor('BusinessProcess', getNames);
api.subscribeFor('BusinessUnit', getNames);
api.subscribeFor('Product', getNames);
api.subscribeFor('Project', getNames);
api.subscribeFor('BusinessFunction', getNames);
api.subscribeFor('BusinessObject', getNames);
api.subscribeFor('InformationSystemDomain', getNames);
api.subscribeFor('InformationSystem', getNames);
api.subscribeFor('InformationFlow', getNames);
api.subscribeFor('ITService', getNames);
api.subscribeFor('ArchitecturalDomain', getNames);
api.subscribeFor('TechnicalComponent', getNames);
api.subscribeFor('InfrastructureElement', getNames);

function getNames(BuildingBlockType, Event) {
    for (var eventIndex = 0; Event.length > eventIndex; eventIndex++) {
        if ('insert'.toLocaleLowerCase() === Event[eventIndex].changeType.toLocaleLowerCase()) {
            for (var changeTypeIndex = 0; Event[eventIndex].buildingBlockChanges.length > changeTypeIndex; changeTypeIndex++) {
				//check if attribute 'name' is '__reaction'
                if (('name'.toLocaleLowerCase() === Event[eventIndex].buildingBlockChanges[changeTypeIndex].persistentName.toLocaleLowerCase()) && ('__reaction'.toLocaleLowerCase() === Event[eventIndex].buildingBlockChanges[changeTypeIndex].added.toLocaleLowerCase())) {
					//Get the currently added building block from the data model
                    var newBuildingBlock = api.datamodel.findByTypeAndId(BuildingBlockType, Event[eventIndex].id);
                    var descriptionString = '(' + BuildingBlockType + ')\r\n\r\n=Attributes=';
                    var bbAttributes = api.datamodel.getAllPropertyNamesByType(BuildingBlockType);
                    for (var attributeIndex = 0; bbAttributes.length > attributeIndex; attributeIndex++) {
                        descriptionString += '\r\n* ' + bbAttributes[attributeIndex];
                    }
                    descriptionString += '\r\n\r\n=Relations=';
                    var bbRelationTypes = api.datamodel.getAllRelationshipNamesByType(BuildingBlockType);
                    for (var relationIndex = 0; bbRelationTypes.length > relationIndex; relationIndex++) {
                        descriptionString += '\r\n* ' + bbRelationTypes[relationIndex];
                    }

                    newBuildingBlock.setValue('description', descriptionString);
                }
            }
        }
    }
}

Connecting and disconnectiong business mappings and attributable relations

In this examples it is shown how to connect two building blocks via an attributable relation and how to disconnect two elements connected via a business mapping when only the ids of the building blocks are known.

Download examples: connect.js disconnect.js

Connect
'use strict';
api.registerExecution(onDirectExecute);

function onDirectExecute() {
    var object = api.datamodel.findByTypeAndId('InformationSystem', 203);
    var object2 = api.datamodel.findByTypeAndId('TechnicalComponent', 323);
    var connect = api.datamodel.create('Is2TcAssociation');
    connect.connect(object, "informationSystem");
    connect.connect(object2, "technicalComponent");
} 
Disconnect
'use strict';
api.registerExecution(onDirectExecute);

function onDirectExecute() {
    var allBMs = api.datamodel.findByType('BusinessMapping');
    var bfId = 68;
    var boId = 9;

    api.printLog(allBMs.length);

    for (var index=0; index < allBMs.length; index++) {
        if(allBMs[index].getRelatedObject('businessFunction') &&
            allBMs[index].getRelatedObject('businessFunction').getId()== bfId &&
            allBMs[index].getRelatedObject('businessObject') &&
            allBMs[index].getRelatedObject('businessObject').getId()== boId &&
            !allBMs[index].getRelatedObject('informationSystem')&&
            !allBMs[index].getRelatedObject('businessUnit')&&
            !allBMs[index].getRelatedObject('businessProcess')&&
            !allBMs[index].getRelatedObject('product') &&
            !allBMs[index].getRelatedObject('itService')){
                print(allBMs[index].getId());
                allBMs[index].remove();
        }
    }
}

  • No labels