all files / lib/features/modeling/behavior/ ReplaceConnectionBehavior.js

100% Statements 42/42
96.67% Branches 29/30
100% Functions 5/5
100% Lines 42/42
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137                              963×       442× 442× 442×         442×                           440× 314× 31×     314× 12×           440×   63×     63×       440×           440× 42×         440× 17×             963×   324× 324×   324×     963×         137×   137×     963× 296× 296× 296× 296×       296× 29×         29× 29×         296×                    
import {
  forEach,
  find,
  matchPattern
} from 'min-dash';
 
import inherits from 'inherits';
 
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
 
import { is } from '../../../util/ModelUtil';
 
 
export default function ReplaceConnectionBehavior(eventBus, modeling, bpmnRules) {
 
  CommandInterceptor.call(this, eventBus);
 
  function fixConnection(connection) {
 
    var source = connection.source,
        target = connection.target,
        parent = connection.parent;
 
    // do not do anything if connection
    // is already deleted (may happen due to other
    // behaviors plugged-in before)
    if (!parent) {
      return;
    }
 
    var replacementType,
        remove;
 
    /**
     * Check if incoming or outgoing connections
     * can stay or could be substituted with an
     * appropriate replacement.
     *
     * This holds true for SequenceFlow <> MessageFlow.
     */
 
    if (is(connection, 'bpmn:SequenceFlow')) {
      if (!bpmnRules.canConnectSequenceFlow(source, target)) {
        remove = true;
      }
 
      if (bpmnRules.canConnectMessageFlow(source, target)) {
        replacementType = 'bpmn:MessageFlow';
      }
    }
 
    // transform message flows into sequence flows, if possible
 
    if (is(connection, 'bpmn:MessageFlow')) {
 
      if (!bpmnRules.canConnectMessageFlow(source, target)) {
        remove = true;
      }
 
      if (bpmnRules.canConnectSequenceFlow(source, target)) {
        replacementType = 'bpmn:SequenceFlow';
      }
    }
 
    if (is(connection, 'bpmn:Association') && !bpmnRules.canConnectAssociation(source, target)) {
      remove = true;
    }
 
 
    // remove invalid connection,
    // unless it has been removed already
    if (remove) {
      modeling.removeConnection(connection);
    }
 
    // replace SequenceFlow <> MessageFlow
 
    if (replacementType) {
      modeling.connect(source, target, {
        type: replacementType,
        waypoints: connection.waypoints.slice()
      });
    }
  }
 
  this.postExecuted('elements.move', function(context) {
 
    var closure = context.closure,
        allConnections = closure.allConnections;
 
    forEach(allConnections, fixConnection);
  }, true);
 
  this.postExecuted([
    'connection.reconnectStart',
    'connection.reconnectEnd'
  ], function(event) {
 
    var connection = event.context.connection;
 
    fixConnection(connection);
  });
 
  this.postExecuted('element.updateProperties', function(event) {
    var context = event.context,
        properties = context.properties,
        element = context.element,
        businessObject = element.businessObject,
        connection;
 
    // remove condition expression when morphing to default flow
    if (properties.default) {
      connection = find(
        element.outgoing,
        matchPattern({ id: element.businessObject.default.id })
      );
 
      Eif (connection) {
        modeling.updateProperties(connection, { conditionExpression: undefined });
      }
    }
 
    // remove default property from source when morphing to conditional flow
    if (properties.conditionExpression && businessObject.sourceRef.default === businessObject) {
      modeling.updateProperties(element.source, { default: undefined });
    }
  });
}
 
inherits(ReplaceConnectionBehavior, CommandInterceptor);
 
ReplaceConnectionBehavior.$inject = [
  'eventBus',
  'modeling',
  'bpmnRules'
];