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