472 lines
13 KiB
JavaScript
472 lines
13 KiB
JavaScript
'use strict';
|
|
|
|
var findExtension = require('../Helper').findExtension,
|
|
findExtensions = require('../Helper').findExtensions;
|
|
|
|
var createActivitiProperty = require('../CreateHelper').createActivitiProperty,
|
|
createInputParameter = require('../CreateHelper').createInputParameter,
|
|
createOutputParameter = require('../CreateHelper').createOutputParameter,
|
|
createActivitiIn = require('../CreateHelper').createActivitiIn,
|
|
createActivitiOut = require('../CreateHelper').createActivitiOut,
|
|
createActivitiInWithBusinessKey = require('../CreateHelper').createActivitiInWithBusinessKey,
|
|
createActivitiExecutionListenerScript = require('../CreateHelper').createActivitiExecutionListenerScript,
|
|
createActivitiFieldInjection = require('../CreateHelper').createActivitiFieldInjection;
|
|
|
|
var forEach = require('lodash/forEach');
|
|
|
|
var ACTIVITI_SERVICE_TASK_LIKE = [
|
|
'activiti:class',
|
|
'activiti:delegateExpression',
|
|
'activiti:expression'
|
|
];
|
|
|
|
/**
|
|
* A handler that changes the modeling template of a BPMN element.
|
|
*/
|
|
function ChangeElementTemplateHandler(modeling, commandStack, bpmnFactory) {
|
|
|
|
function getOrCreateExtensionElements(element) {
|
|
|
|
var bo = element.businessObject;
|
|
|
|
var extensionElements = bo.extensionElements;
|
|
|
|
// add extension elements
|
|
if (!extensionElements) {
|
|
extensionElements = bpmnFactory.create('bpmn:ExtensionElements', {
|
|
values: []
|
|
});
|
|
|
|
modeling.updateProperties(element, {
|
|
extensionElements: extensionElements
|
|
});
|
|
}
|
|
|
|
return extensionElements;
|
|
}
|
|
|
|
function updateModelerTemplate(element, newTemplate) {
|
|
modeling.updateProperties(element, {
|
|
'activiti:modelerTemplate': newTemplate && newTemplate.id
|
|
});
|
|
}
|
|
|
|
function updateIoMappings(element, newTemplate, context) {
|
|
|
|
var newMappings = createInputOutputMappings(newTemplate, bpmnFactory),
|
|
oldMappings;
|
|
|
|
if (!newMappings) {
|
|
return;
|
|
}
|
|
|
|
if (context) {
|
|
commandStack.execute('properties-panel.update-businessobject', {
|
|
element: element,
|
|
businessObject: context,
|
|
properties: { inputOutput: newMappings }
|
|
});
|
|
} else {
|
|
context = getOrCreateExtensionElements(element);
|
|
oldMappings = findExtension(element, 'activiti:InputOutput');
|
|
commandStack.execute('properties-panel.update-businessobject-list', {
|
|
element: element,
|
|
currentObject: context,
|
|
propertyName: 'values',
|
|
objectsToAdd: [ newMappings ],
|
|
objectsToRemove: oldMappings ? [ oldMappings ] : []
|
|
});
|
|
}
|
|
}
|
|
|
|
function updateActivitiField(element, newTemplate, context) {
|
|
|
|
var newMappings = createActivitiFieldInjections(newTemplate, bpmnFactory),
|
|
oldMappings;
|
|
|
|
if (!newMappings) {
|
|
return;
|
|
}
|
|
if (context) {
|
|
commandStack.execute('properties-panel.update-businessobject', {
|
|
element: element,
|
|
businessObject: context,
|
|
properties: { field: newMappings }
|
|
});
|
|
} else {
|
|
context = getOrCreateExtensionElements(element);
|
|
oldMappings = findExtensions(element, ['activiti:Field']);
|
|
|
|
commandStack.execute('properties-panel.update-businessobject-list', {
|
|
element: element,
|
|
currentObject: context,
|
|
propertyName: 'values',
|
|
objectsToAdd: newMappings,
|
|
objectsToRemove: oldMappings ? oldMappings : []
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
function updateActivitiProperties(element, newTemplate, context) {
|
|
|
|
var newProperties = createActivitiProperties(newTemplate, bpmnFactory),
|
|
oldProperties;
|
|
|
|
if (!newProperties) {
|
|
return;
|
|
}
|
|
|
|
if (context) {
|
|
commandStack.execute('properties-panel.update-businessobject', {
|
|
element: element,
|
|
businessObject: context,
|
|
properties: { properties: newProperties }
|
|
});
|
|
} else {
|
|
context = getOrCreateExtensionElements(element);
|
|
oldProperties = findExtension(element, 'activiti:Properties');
|
|
|
|
commandStack.execute('properties-panel.update-businessobject-list', {
|
|
element: element,
|
|
currentObject: context,
|
|
propertyName: 'values',
|
|
objectsToAdd: [ newProperties ],
|
|
objectsToRemove: oldProperties ? [ oldProperties ] : []
|
|
});
|
|
}
|
|
}
|
|
|
|
function updateProperties(element, newTemplate, context) {
|
|
|
|
var newProperties = createBpmnPropertyUpdates(newTemplate, bpmnFactory);
|
|
|
|
var newPropertiesCount = Object.keys(newProperties).length;
|
|
|
|
if (!newPropertiesCount) {
|
|
return;
|
|
}
|
|
|
|
if (context) {
|
|
commandStack.execute('properties-panel.update-businessobject', {
|
|
element: element,
|
|
businessObject: context,
|
|
properties: newProperties
|
|
});
|
|
} else {
|
|
modeling.updateProperties(element, newProperties);
|
|
}
|
|
}
|
|
|
|
function updateInOut(element, newTemplate, context) {
|
|
|
|
var newInOut = createActivitiInOut(newTemplate, bpmnFactory),
|
|
oldInOut;
|
|
|
|
if (!newInOut) {
|
|
return;
|
|
}
|
|
|
|
if (context) {
|
|
commandStack.execute('properties-panel.update-businessobject', {
|
|
element: element,
|
|
businessObject: context,
|
|
properties: { inout: newInOut }
|
|
});
|
|
} else {
|
|
context = getOrCreateExtensionElements(element);
|
|
oldInOut = findExtensions(context, [ 'activiti:In', 'activiti:Out' ]);
|
|
|
|
commandStack.execute('properties-panel.update-businessobject-list', {
|
|
element: element,
|
|
currentObject: context,
|
|
propertyName: 'values',
|
|
objectsToAdd: newInOut,
|
|
objectsToRemove: oldInOut
|
|
});
|
|
}
|
|
}
|
|
|
|
function updateExecutionListener(element, newTemplate, context) {
|
|
|
|
var newExecutionListeners = createActivitiExecutionListeners(newTemplate, bpmnFactory),
|
|
oldExecutionsListeners;
|
|
|
|
if (!newExecutionListeners.length) {
|
|
return;
|
|
}
|
|
|
|
if (context) {
|
|
commandStack.execute('properties-panel.update-businessobject', {
|
|
element: element,
|
|
businessObject: context,
|
|
properties: { executionListener: newExecutionListeners }
|
|
});
|
|
} else {
|
|
context = getOrCreateExtensionElements(element);
|
|
oldExecutionsListeners = findExtensions(context, [ 'activiti:ExecutionListener' ]);
|
|
|
|
commandStack.execute('properties-panel.update-businessobject-list', {
|
|
element: element,
|
|
currentObject: context,
|
|
propertyName: 'values',
|
|
objectsToAdd: newExecutionListeners,
|
|
objectsToRemove: oldExecutionsListeners
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update / recreate a scoped element.
|
|
*
|
|
* @param {djs.model.Base} element the diagram parent element
|
|
* @param {String} scopeName name of the scope, i.e. activiti:Connector
|
|
* @param {Object} scopeDefinition
|
|
*/
|
|
function updateScopeElements(element, scopeName, scopeDefinition) {
|
|
|
|
var scopeElement = bpmnFactory.create(scopeName);
|
|
|
|
// update activiti:inputOutput
|
|
updateIoMappings(element, scopeDefinition, scopeElement);
|
|
|
|
// update activiti:field
|
|
updateActivitiField(element, scopeDefinition, scopeElement);
|
|
|
|
// update activiti:properties
|
|
updateActivitiProperties(element, scopeDefinition, scopeElement);
|
|
|
|
// update other properties (bpmn:condition, activiti:async, ...)
|
|
updateProperties(element, scopeDefinition, scopeElement);
|
|
|
|
// update activiti:in and activiti:out
|
|
updateInOut(element, scopeDefinition, scopeElement);
|
|
|
|
// update activiti:executionListener
|
|
updateExecutionListener(element, scopeDefinition, scopeElement);
|
|
|
|
var extensionElements = getOrCreateExtensionElements(element);
|
|
var oldScope = findExtension(extensionElements, scopeName);
|
|
|
|
commandStack.execute('properties-panel.update-businessobject-list', {
|
|
element: element,
|
|
currentObject: extensionElements,
|
|
propertyName: 'values',
|
|
objectsToAdd: [ scopeElement ],
|
|
objectsToRemove: oldScope ? [ oldScope ] : []
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Compose an element template change action, updating all
|
|
* necessary underlying properties.
|
|
*
|
|
* @param {Object} context
|
|
* @param {Object} context.element
|
|
* @param {Object} context.oldTemplate
|
|
* @param {Object} context.newTemplate
|
|
*/
|
|
this.preExecute = function(context) {
|
|
|
|
var element = context.element,
|
|
newTemplate = context.newTemplate;
|
|
|
|
// update activiti:modelerTemplate attribute
|
|
updateModelerTemplate(element, newTemplate);
|
|
|
|
if (newTemplate) {
|
|
|
|
// update activiti:inputOutput
|
|
updateIoMappings(element, newTemplate);
|
|
|
|
// update activiti:field
|
|
updateActivitiField(element, newTemplate);
|
|
|
|
// update activiti:properties
|
|
updateActivitiProperties(element, newTemplate);
|
|
|
|
// update other properties (bpmn:condition, activiti:async, ...)
|
|
updateProperties(element, newTemplate);
|
|
|
|
// update activiti:in and activiti:out
|
|
updateInOut(element, newTemplate);
|
|
|
|
// update activiti:executionListener
|
|
updateExecutionListener(element, newTemplate);
|
|
|
|
// loop on scopes properties
|
|
forEach(newTemplate.scopes, function(scopeDefinition, scopeName) {
|
|
updateScopeElements(element, scopeName, scopeDefinition);
|
|
});
|
|
|
|
}
|
|
};
|
|
}
|
|
|
|
ChangeElementTemplateHandler.$inject = [ 'modeling', 'commandStack', 'bpmnFactory' ];
|
|
|
|
module.exports = ChangeElementTemplateHandler;
|
|
|
|
|
|
|
|
// helpers /////////////////////////////
|
|
|
|
function createBpmnPropertyUpdates(template, bpmnFactory) {
|
|
|
|
var propertyUpdates = {};
|
|
|
|
template.properties.forEach(function(p) {
|
|
|
|
var binding = p.binding,
|
|
bindingTarget = binding.name,
|
|
propertyValue;
|
|
|
|
if (binding.type === 'property') {
|
|
|
|
if (bindingTarget === 'conditionExpression') {
|
|
propertyValue = bpmnFactory.create('bpmn:FormalExpression', {
|
|
body: p.value,
|
|
language: binding.scriptFormat
|
|
});
|
|
} else {
|
|
propertyValue = p.value;
|
|
}
|
|
|
|
// assigning activiti:async to true|false
|
|
// assigning bpmn:conditionExpression to { $type: 'bpmn:FormalExpression', ... }
|
|
propertyUpdates[bindingTarget] = propertyValue;
|
|
|
|
// make sure we unset other "implementation types"
|
|
// when applying a activiti:class template onto a preconfigured
|
|
// activiti:delegateExpression element
|
|
if (ACTIVITI_SERVICE_TASK_LIKE.indexOf(bindingTarget) !== -1) {
|
|
ACTIVITI_SERVICE_TASK_LIKE.forEach(function(prop) {
|
|
if (prop !== bindingTarget) {
|
|
propertyUpdates[prop] = undefined;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
return propertyUpdates;
|
|
}
|
|
|
|
function createActivitiFieldInjections(template, bpmnFactory) {
|
|
var injections = [];
|
|
|
|
template.properties.forEach(function(p) {
|
|
var binding = p.binding,
|
|
bindingType = binding.type;
|
|
if (bindingType === 'activiti:field') {
|
|
injections.push(createActivitiFieldInjection(
|
|
binding, p.value, bpmnFactory
|
|
));
|
|
}
|
|
});
|
|
|
|
if (injections.length) {
|
|
return injections;
|
|
}
|
|
}
|
|
|
|
function createActivitiProperties(template, bpmnFactory) {
|
|
|
|
var properties = [];
|
|
|
|
template.properties.forEach(function(p) {
|
|
var binding = p.binding,
|
|
bindingType = binding.type;
|
|
|
|
if (bindingType === 'activiti:property') {
|
|
properties.push(createActivitiProperty(
|
|
binding, p.value, bpmnFactory
|
|
));
|
|
}
|
|
});
|
|
|
|
if (properties.length) {
|
|
return bpmnFactory.create('activiti:Properties', {
|
|
values: properties
|
|
});
|
|
}
|
|
}
|
|
|
|
function createInputOutputMappings(template, bpmnFactory) {
|
|
|
|
var inputParameters = [],
|
|
outputParameters = [];
|
|
|
|
template.properties.forEach(function(p) {
|
|
var binding = p.binding,
|
|
bindingType = binding.type;
|
|
|
|
if (bindingType === 'activiti:inputParameter') {
|
|
inputParameters.push(createInputParameter(
|
|
binding, p.value, bpmnFactory
|
|
));
|
|
}
|
|
|
|
if (bindingType === 'activiti:outputParameter') {
|
|
outputParameters.push(createOutputParameter(
|
|
binding, p.value, bpmnFactory
|
|
));
|
|
}
|
|
});
|
|
|
|
// do we need to create new ioMappings (?)
|
|
if (outputParameters.length || inputParameters.length) {
|
|
return bpmnFactory.create('activiti:InputOutput', {
|
|
inputParameters: inputParameters,
|
|
outputParameters: outputParameters
|
|
});
|
|
}
|
|
}
|
|
|
|
function createActivitiInOut(template, bpmnFactory) {
|
|
|
|
var inOuts = [];
|
|
|
|
template.properties.forEach(function(p) {
|
|
var binding = p.binding,
|
|
bindingType = binding.type;
|
|
|
|
if (bindingType === 'activiti:in') {
|
|
inOuts.push(createActivitiIn(
|
|
binding, p.value, bpmnFactory
|
|
));
|
|
} else
|
|
if (bindingType === 'activiti:out') {
|
|
inOuts.push(createActivitiOut(
|
|
binding, p.value, bpmnFactory
|
|
));
|
|
} else
|
|
if (bindingType === 'activiti:in:businessKey') {
|
|
inOuts.push(createActivitiInWithBusinessKey(
|
|
binding, p.value, bpmnFactory
|
|
));
|
|
}
|
|
});
|
|
|
|
return inOuts;
|
|
}
|
|
|
|
|
|
function createActivitiExecutionListeners(template, bpmnFactory) {
|
|
|
|
var executionListener = [];
|
|
|
|
template.properties.forEach(function(p) {
|
|
var binding = p.binding,
|
|
bindingType = binding.type;
|
|
|
|
if (bindingType === 'activiti:executionListener') {
|
|
executionListener.push(createActivitiExecutionListenerScript(
|
|
binding, p.value, bpmnFactory
|
|
));
|
|
}
|
|
});
|
|
|
|
return executionListener;
|
|
}
|