extension.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. 'use strict'
  2. import { isFunction, isObject, some } from 'min-dash'
  3. // const isFunction = isFunction,
  4. // isObject = isObject,
  5. // some = some
  6. // const isFunction = require('min-dash').isFunction,
  7. // isObject = require('min-dash').isObject,
  8. // some = require('min-dash').some
  9. const WILDCARD = '*'
  10. function CamundaModdleExtension(eventBus) {
  11. // eslint-disable-next-line @typescript-eslint/no-this-alias
  12. const self = this
  13. eventBus.on('moddleCopy.canCopyProperty', function (context) {
  14. const property = context.property,
  15. parent = context.parent
  16. return self.canCopyProperty(property, parent)
  17. })
  18. }
  19. CamundaModdleExtension.$inject = ['eventBus']
  20. /**
  21. * Check wether to disallow copying property.
  22. */
  23. CamundaModdleExtension.prototype.canCopyProperty = function (property, parent) {
  24. // (1) check wether property is allowed in parent
  25. if (isObject(property) && !isAllowedInParent(property, parent)) {
  26. return false
  27. }
  28. // (2) check more complex scenarios
  29. if (is(property, 'camunda:InputOutput') && !this.canHostInputOutput(parent)) {
  30. return false
  31. }
  32. if (isAny(property, ['camunda:Connector', 'camunda:Field']) && !this.canHostConnector(parent)) {
  33. return false
  34. }
  35. if (is(property, 'camunda:In') && !this.canHostIn(parent)) {
  36. return false
  37. }
  38. }
  39. CamundaModdleExtension.prototype.canHostInputOutput = function (parent) {
  40. // allowed in camunda:Connector
  41. const connector = getParent(parent, 'camunda:Connector')
  42. if (connector) {
  43. return true
  44. }
  45. // special rules inside bpmn:FlowNode
  46. const flowNode = getParent(parent, 'bpmn:FlowNode')
  47. if (!flowNode) {
  48. return false
  49. }
  50. if (isAny(flowNode, ['bpmn:StartEvent', 'bpmn:Gateway', 'bpmn:BoundaryEvent'])) {
  51. return false
  52. }
  53. return !(is(flowNode, 'bpmn:SubProcess') && flowNode.get('triggeredByEvent'))
  54. }
  55. CamundaModdleExtension.prototype.canHostConnector = function (parent) {
  56. const serviceTaskLike = getParent(parent, 'camunda:ServiceTaskLike')
  57. if (is(serviceTaskLike, 'bpmn:MessageEventDefinition')) {
  58. // only allow on throw and end events
  59. return getParent(parent, 'bpmn:IntermediateThrowEvent') || getParent(parent, 'bpmn:EndEvent')
  60. }
  61. return true
  62. }
  63. CamundaModdleExtension.prototype.canHostIn = function (parent) {
  64. const callActivity = getParent(parent, 'bpmn:CallActivity')
  65. if (callActivity) {
  66. return true
  67. }
  68. const signalEventDefinition = getParent(parent, 'bpmn:SignalEventDefinition')
  69. if (signalEventDefinition) {
  70. // only allow on throw and end events
  71. return getParent(parent, 'bpmn:IntermediateThrowEvent') || getParent(parent, 'bpmn:EndEvent')
  72. }
  73. return true
  74. }
  75. // module.exports = CamundaModdleExtension;
  76. export default CamundaModdleExtension
  77. // helpers //////////
  78. function is(element, type) {
  79. return element && isFunction(element.$instanceOf) && element.$instanceOf(type)
  80. }
  81. function isAny(element, types) {
  82. return some(types, function (t) {
  83. return is(element, t)
  84. })
  85. }
  86. function getParent(element, type) {
  87. if (!type) {
  88. return element.$parent
  89. }
  90. if (is(element, type)) {
  91. return element
  92. }
  93. if (!element.$parent) {
  94. return
  95. }
  96. return getParent(element.$parent, type)
  97. }
  98. function isAllowedInParent(property, parent) {
  99. // (1) find property descriptor
  100. const descriptor = property.$type && property.$model.getTypeDescriptor(property.$type)
  101. const allowedIn = descriptor && descriptor.meta && descriptor.meta.allowedIn
  102. if (!allowedIn || isWildcard(allowedIn)) {
  103. return true
  104. }
  105. // (2) check wether property has parent of allowed type
  106. return some(allowedIn, function (type) {
  107. return getParent(parent, type)
  108. })
  109. }
  110. function isWildcard(allowedIn) {
  111. return allowedIn.indexOf(WILDCARD) !== -1
  112. }