123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- import {
- find,
- forEach,
- isArray,
- isDefined,
- isObject,
- matchPattern,
- reduce,
- has,
- sortBy
- } from 'min-dash';
- var DISALLOWED_PROPERTIES = [
- 'artifacts',
- 'dataInputAssociations',
- 'dataOutputAssociations',
- 'default',
- 'flowElements',
- 'lanes',
- 'incoming',
- 'outgoing'
- ];
- /**
- * @typedef {Function} <moddleCopy.canCopyProperties> listener
- *
- * @param {Object} context
- * @param {Array<string>} context.propertyNames
- * @param {ModdleElement} context.sourceElement
- * @param {ModdleElement} context.targetElement
- *
- * @returns {Array<string>|boolean} - Return properties to be copied or false to disallow
- * copying.
- */
- /**
- * @typedef {Function} <moddleCopy.canCopyProperty> listener
- *
- * @param {Object} context
- * @param {ModdleElement} context.parent
- * @param {*} context.property
- * @param {string} context.propertyName
- *
- * @returns {*|boolean} - Return copied property or false to disallow
- * copying.
- */
- /**
- * @typedef {Function} <moddleCopy.canSetCopiedProperty> listener
- *
- * @param {Object} context
- * @param {ModdleElement} context.parent
- * @param {*} context.property
- * @param {string} context.propertyName
- *
- * @returns {boolean} - Return false to disallow
- * setting copied property.
- */
- /**
- * Utility for copying model properties from source element to target element.
- *
- * @param {EventBus} eventBus
- * @param {BpmnFactory} bpmnFactory
- * @param {BpmnModdle} moddle
- */
- export default function ModdleCopy(eventBus, bpmnFactory, moddle) {
- this._bpmnFactory = bpmnFactory;
- this._eventBus = eventBus;
- this._moddle = moddle;
- // copy extension elements last
- eventBus.on('moddleCopy.canCopyProperties', function(context) {
- var propertyNames = context.propertyNames;
- if (!propertyNames || !propertyNames.length) {
- return;
- }
- return sortBy(propertyNames, function(propertyName) {
- return propertyName === 'extensionElements';
- });
- });
- // default check whether property can be copied
- eventBus.on('moddleCopy.canCopyProperty', function(context) {
- var parent = context.parent,
- parentDescriptor = isObject(parent) && parent.$descriptor,
- propertyName = context.propertyName;
- if (propertyName && DISALLOWED_PROPERTIES.indexOf(propertyName) !== -1) {
- // disallow copying property
- return false;
- }
- if (propertyName &&
- parentDescriptor &&
- !find(parentDescriptor.properties, matchPattern({ name: propertyName }))) {
- // disallow copying property
- return false;
- }
- });
- // do NOT allow to copy empty extension elements
- eventBus.on('moddleCopy.canSetCopiedProperty', function(context) {
- var property = context.property;
- if (is(property, 'bpmn:ExtensionElements') && (!property.values || !property.values.length)) {
- // disallow setting copied property
- return false;
- }
- });
- }
- ModdleCopy.$inject = [
- 'eventBus',
- 'bpmnFactory',
- 'moddle'
- ];
- /**
- * Copy model properties of source element to target element.
- *
- * @param {ModdleElement} sourceElement
- * @param {ModdleElement} targetElement
- * @param {Array<string>} [propertyNames]
- *
- * @param {ModdleElement}
- */
- ModdleCopy.prototype.copyElement = function(sourceElement, targetElement, propertyNames) {
- var self = this;
- if (propertyNames && !isArray(propertyNames)) {
- propertyNames = [ propertyNames ];
- }
- propertyNames = propertyNames || getPropertyNames(sourceElement.$descriptor);
- var canCopyProperties = this._eventBus.fire('moddleCopy.canCopyProperties', {
- propertyNames: propertyNames,
- sourceElement: sourceElement,
- targetElement: targetElement
- });
- if (canCopyProperties === false) {
- return targetElement;
- }
- if (isArray(canCopyProperties)) {
- propertyNames = canCopyProperties;
- }
- // copy properties
- forEach(propertyNames, function(propertyName) {
- var sourceProperty;
- if (has(sourceElement, propertyName)) {
- sourceProperty = sourceElement.get(propertyName);
- }
- var copiedProperty = self.copyProperty(sourceProperty, targetElement, propertyName);
- var canSetProperty = self._eventBus.fire('moddleCopy.canSetCopiedProperty', {
- parent: targetElement,
- property: copiedProperty,
- propertyName: propertyName
- });
- if (canSetProperty === false) {
- return;
- }
- if (isDefined(copiedProperty)) {
- targetElement.set(propertyName, copiedProperty);
- }
- });
- return targetElement;
- };
- /**
- * Copy model property.
- *
- * @param {*} property
- * @param {ModdleElement} parent
- * @param {string} propertyName
- *
- * @returns {*}
- */
- ModdleCopy.prototype.copyProperty = function(property, parent, propertyName) {
- var self = this;
- // allow others to copy property
- var copiedProperty = this._eventBus.fire('moddleCopy.canCopyProperty', {
- parent: parent,
- property: property,
- propertyName: propertyName
- });
- // return if copying is NOT allowed
- if (copiedProperty === false) {
- return;
- }
- if (copiedProperty) {
- if (isObject(copiedProperty) && copiedProperty.$type && !copiedProperty.$parent) {
- copiedProperty.$parent = parent;
- }
- return copiedProperty;
- }
- var propertyDescriptor = this._moddle.getPropertyDescriptor(parent, propertyName);
- // do NOT copy Ids and references
- if (propertyDescriptor.isId || propertyDescriptor.isReference) {
- return;
- }
- // copy arrays
- if (isArray(property)) {
- return reduce(property, function(childProperties, childProperty) {
- // recursion
- copiedProperty = self.copyProperty(childProperty, parent, propertyName);
- // copying might NOT be allowed
- if (copiedProperty) {
- copiedProperty.$parent = parent;
- return childProperties.concat(copiedProperty);
- }
- return childProperties;
- }, []);
- }
- // copy model elements
- if (isObject(property) && property.$type) {
- if (this._moddle.getElementDescriptor(property).isGeneric) {
- return;
- }
- copiedProperty = self._bpmnFactory.create(property.$type);
- copiedProperty.$parent = parent;
- // recursion
- copiedProperty = self.copyElement(property, copiedProperty);
- return copiedProperty;
- }
- // copy primitive properties
- return property;
- };
- // helpers //////////
- export function getPropertyNames(descriptor, keepDefaultProperties) {
- return reduce(descriptor.properties, function(properties, property) {
- if (keepDefaultProperties && property.default) {
- return properties;
- }
- return properties.concat(property.name);
- }, []);
- }
- function is(element, type) {
- return element && (typeof element.$instanceOf === 'function') && element.$instanceOf(type);
- }
|