DataStoreBehavior.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import inherits from 'inherits';
  2. import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
  3. import { is } from '../../../util/ModelUtil';
  4. import { isAny } from '../util/ModelingUtil';
  5. import UpdateSemanticParentHandler from '../cmd/UpdateSemanticParentHandler';
  6. /**
  7. * BPMN specific data store behavior
  8. */
  9. export default function DataStoreBehavior(
  10. canvas, commandStack, elementRegistry,
  11. eventBus) {
  12. CommandInterceptor.call(this, eventBus);
  13. commandStack.registerHandler('dataStore.updateContainment', UpdateSemanticParentHandler);
  14. function getFirstParticipant() {
  15. return elementRegistry.filter(function(element) {
  16. return is(element, 'bpmn:Participant');
  17. })[0];
  18. }
  19. function getDataStores(element) {
  20. return element.children.filter(function(child) {
  21. return is(child, 'bpmn:DataStoreReference') && !child.labelTarget;
  22. });
  23. }
  24. function updateDataStoreParent(dataStore, newDataStoreParent) {
  25. var dataStoreBo = dataStore.businessObject || dataStore;
  26. newDataStoreParent = newDataStoreParent || getFirstParticipant();
  27. if (newDataStoreParent) {
  28. var newDataStoreParentBo = newDataStoreParent.businessObject || newDataStoreParent;
  29. commandStack.execute('dataStore.updateContainment', {
  30. dataStoreBo: dataStoreBo,
  31. newSemanticParent: newDataStoreParentBo.processRef || newDataStoreParentBo,
  32. newDiParent: newDataStoreParentBo.di
  33. });
  34. }
  35. }
  36. // disable auto-resize for data stores
  37. this.preExecute('shape.create', function(event) {
  38. var context = event.context,
  39. shape = context.shape;
  40. if (is(shape, 'bpmn:DataStoreReference') &&
  41. shape.type !== 'label') {
  42. if (!context.hints) {
  43. context.hints = {};
  44. }
  45. // prevent auto resizing
  46. context.hints.autoResize = false;
  47. }
  48. });
  49. // disable auto-resize for data stores
  50. this.preExecute('elements.move', function(event) {
  51. var context = event.context,
  52. shapes = context.shapes;
  53. var dataStoreReferences = shapes.filter(function(shape) {
  54. return is(shape, 'bpmn:DataStoreReference');
  55. });
  56. if (dataStoreReferences.length) {
  57. if (!context.hints) {
  58. context.hints = {};
  59. }
  60. // prevent auto resizing for data store references
  61. context.hints.autoResize = shapes.filter(function(shape) {
  62. return !is(shape, 'bpmn:DataStoreReference');
  63. });
  64. }
  65. });
  66. // update parent on data store created
  67. this.postExecute('shape.create', function(event) {
  68. var context = event.context,
  69. shape = context.shape,
  70. parent = shape.parent;
  71. if (is(shape, 'bpmn:DataStoreReference') &&
  72. shape.type !== 'label' &&
  73. is(parent, 'bpmn:Collaboration')) {
  74. updateDataStoreParent(shape);
  75. }
  76. });
  77. // update parent on data store moved
  78. this.postExecute('shape.move', function(event) {
  79. var context = event.context,
  80. shape = context.shape,
  81. oldParent = context.oldParent,
  82. parent = shape.parent;
  83. if (is(oldParent, 'bpmn:Collaboration')) {
  84. // do nothing if not necessary
  85. return;
  86. }
  87. if (is(shape, 'bpmn:DataStoreReference') &&
  88. shape.type !== 'label' &&
  89. is(parent, 'bpmn:Collaboration')) {
  90. var participant = is(oldParent, 'bpmn:Participant') ?
  91. oldParent :
  92. getAncestor(oldParent, 'bpmn:Participant');
  93. updateDataStoreParent(shape, participant);
  94. }
  95. });
  96. // update data store parents on participant or subprocess deleted
  97. this.postExecute('shape.delete', function(event) {
  98. var context = event.context,
  99. shape = context.shape,
  100. rootElement = canvas.getRootElement();
  101. if (isAny(shape, [ 'bpmn:Participant', 'bpmn:SubProcess' ])
  102. && is(rootElement, 'bpmn:Collaboration')) {
  103. getDataStores(rootElement)
  104. .filter(function(dataStore) {
  105. return isDescendant(dataStore, shape);
  106. })
  107. .forEach(function(dataStore) {
  108. updateDataStoreParent(dataStore);
  109. });
  110. }
  111. });
  112. // update data store parents on collaboration -> process
  113. this.postExecute('canvas.updateRoot', function(event) {
  114. var context = event.context,
  115. oldRoot = context.oldRoot,
  116. newRoot = context.newRoot;
  117. var dataStores = getDataStores(oldRoot);
  118. dataStores.forEach(function(dataStore) {
  119. if (is(newRoot, 'bpmn:Process')) {
  120. updateDataStoreParent(dataStore, newRoot);
  121. }
  122. });
  123. });
  124. }
  125. DataStoreBehavior.$inject = [
  126. 'canvas',
  127. 'commandStack',
  128. 'elementRegistry',
  129. 'eventBus',
  130. ];
  131. inherits(DataStoreBehavior, CommandInterceptor);
  132. // helpers //////////
  133. function isDescendant(descendant, ancestor) {
  134. var descendantBo = descendant.businessObject || descendant,
  135. ancestorBo = ancestor.businessObject || ancestor;
  136. while (descendantBo.$parent) {
  137. if (descendantBo.$parent === ancestorBo.processRef || ancestorBo) {
  138. return true;
  139. }
  140. descendantBo = descendantBo.$parent;
  141. }
  142. return false;
  143. }
  144. function getAncestor(element, type) {
  145. while (element.parent) {
  146. if (is(element.parent, type)) {
  147. return element.parent;
  148. }
  149. element = element.parent;
  150. }
  151. }