extension.js 3.4 KB

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