/**
  * Returns the value to assign to the otherEnd variable.
  *
  * @return the end of the Edge before reconnection that is not represented by the SourceView
  *     variable
  */
 protected Object getOtherEndValue() {
   // If the reconnectionSource is equals to the sourceNode of the edge
   if (edge.getSourceNode().equals(reconnectionSource)) {
     // The other end will be the target node
     return edge.getTargetNode();
   } else {
     return edge.getSourceNode();
   }
 }
 private boolean isEdgeActualMappingUsingDomainElement() {
   boolean isEdgeActualMappingUsingDomainElement = false;
   if (edge.getActualMapping() instanceof EdgeMapping) {
     isEdgeActualMappingUsingDomainElement =
         !((EdgeMapping) edge.getActualMapping()).isUseDomainElement();
   } else if (edge.getActualMapping() instanceof EdgeMappingImport) {
     isEdgeActualMappingUsingDomainElement =
         !(getImportedMapping((EdgeMappingImport) edge.getActualMapping())).isUseDomainElement();
   }
   return isEdgeActualMappingUsingDomainElement;
 }
 private List<ArrangeConstraint> getArrangeConstraints(final EObject diagramElement) {
   List<ArrangeConstraint> constraints = null;
   if (diagramElement instanceof AbstractDNode) {
     final AbstractDNode node = (AbstractDNode) diagramElement;
     constraints = node.getArrangeConstraints();
   } else if (diagramElement instanceof DEdge) {
     final DEdge edge = (DEdge) diagramElement;
     constraints = edge.getArrangeConstraints();
   }
   return constraints;
 }
 /**
  * Construct a new Reconnection command builder.
  *
  * @param tool the reconnection tool
  * @param edge the edge which is reconnected
  * @param source the source of the reconnection
  * @param target the target of the reconnection
  */
 public ReconnectionCommandBuilder(
     final ReconnectEdgeDescription tool,
     final DEdge edge,
     final EdgeTarget source,
     final EdgeTarget target) {
   this.tool = tool;
   this.edge = edge;
   this.reconnectionSource = source;
   this.reconnectionTarget = target;
   this.oldTarget = edge.getTargetNode();
   this.oldSource = edge.getSourceNode();
 }
  /**
   * test the edge creation on auto refresh
   *
   * @throws Exception
   */
  public void testEdgeCreationAutoRefresh() throws Exception {
    changeSiriusPreference(SiriusPreferencesKeys.PREF_AUTO_REFRESH.name(), true);

    Model model = (Model) semanticModel;
    final Activity activity = (Activity) model.getPackagedElements().get(0);
    List<ActivityNode> ownedNodes = getActivityOwnedNodes(activity);
    OpaqueAction source = (OpaqueAction) ownedNodes.get(0);
    OpaqueAction target = (OpaqueAction) ownedNodes.get(1);

    applyEdgeCreationTool(
        "Control Flow",
        diagram,
        (EdgeTarget) getFirstDiagramElement(diagram, source),
        (EdgeTarget) getFirstDiagramElement(diagram, target));

    ActivityEdge edge = activity.getEdges().get(0);
    assertNotNull(edge);
    DEdge edgeElement = getFirstEdgeElement(diagram, edge);
    assertNotNull(edgeElement);

    assertEquals(
        "Wrong EdgeSourceArrow for Edge.",
        EdgeArrows.INPUT_ARROW_LITERAL,
        ((EdgeStyle) edgeElement.getStyle()).getSourceArrow());
    assertEquals(
        "Wrong EdgeTargetArrow for Edge.",
        EdgeArrows.NO_DECORATION_LITERAL,
        ((EdgeStyle) edgeElement.getStyle()).getTargetArrow());

    IDiagramEdgeEditPart gmfEP = (IDiagramEdgeEditPart) getEditPart(edgeElement, editorPart);
    assertNotNull(gmfEP);
    assertNotNull(gmfEP.getPolylineConnectionFigure());

    assertEquals(
        "Wrong Edge target",
        getFirstDiagramElement(diagram, target),
        ((Edge) gmfEP.getModel()).getSource().getElement());
    assertEquals(
        "Wrong Edge source",
        getFirstDiagramElement(diagram, source),
        ((Edge) gmfEP.getModel()).getTarget().getElement());

    doTestUndoRedoAutoRefresh(activity, edge);

    doTestCloseOpen();
  }
  private EdgeMapping getEdgeMappingReconnector() {
    EdgeMapping bestMapping = null;
    DiagramElementMapping sourceMapping = null;
    DiagramElementMapping targetMapping = null;

    if (tool.getReconnectionKind() == ReconnectionKind.RECONNECT_BOTH_LITERAL) {
      if (edge.getTargetNode() == reconnectionSource) {
        sourceMapping = getMapping(reconnectionTarget);
        targetMapping = getMapping(oldTarget);
      } else {
        sourceMapping = getMapping(oldSource);
        targetMapping = getMapping(reconnectionTarget);
      }
    } else if (tool.getReconnectionKind() == ReconnectionKind.RECONNECT_SOURCE_LITERAL) {
      sourceMapping = getMapping(reconnectionTarget);
      targetMapping = getMapping(oldTarget);
    } else if (tool.getReconnectionKind() == ReconnectionKind.RECONNECT_TARGET_LITERAL) {
      sourceMapping = getMapping(oldSource);
      targetMapping = getMapping(reconnectionTarget);
    }
    if (sourceMapping != null && targetMapping != null) {
      final Iterator<EdgeMapping> iterMappings = tool.getMappings().iterator();
      while (iterMappings.hasNext()) {
        final EdgeMapping currentMapping = iterMappings.next();
        if (currentMapping.getTargetMapping().contains(targetMapping)
            && currentMapping.getSourceMapping().contains(sourceMapping)) {
          bestMapping = currentMapping;
          if (currentMapping.equals(edge.getActualMapping())) {
            break;
          }
        }
      }
    }

    return bestMapping;
  }
  /**
   * Generic service used to process treatments on a reconnect. The processing has to be defined by
   * overriding the corresponding caseXXX.
   *
   * @param context Element attached to the existing edge
   * @param edgeView Represents the graphical new edge
   * @param sourceView Represents the graphical element pointed by the edge before reconnecting
   * @param targetView Represents the graphical element pointed by the edge after reconnecting
   * @param source Represents the semantic element pointed by the edge before reconnecting
   * @param target Represents the semantic element pointed by the edge after reconnecting
   * @return the Element attached to the edge once it has been modified
   */
  public Element reconnectEdge(
      Element context,
      DEdge edgeView,
      EdgeTarget sourceView,
      EdgeTarget targetView,
      Element source,
      Element target) {
    final ReconnectSwitch reconnectService = new ReconnectSwitch();

    // The edge view represents the new graphical edge
    // with testing of its source and target nodes we can
    // know if the user reconnected the source or the target of the edge
    if (edgeView.getSourceNode().equals(sourceView)) {
      reconnectService.setReconnectKind(ReconnectSwitch.RECONNECT_SOURCE);
    } else {
      reconnectService.setReconnectKind(ReconnectSwitch.RECONNECT_TARGET);
    }
    reconnectService.setOldPointedElement(source);
    reconnectService.setNewPointedElement(target);
    reconnectService.setEdgeToReconnect(edgeView);
    return reconnectService.doSwitch(context);
  }
  /**
   * {@inheritDoc}
   *
   * @see org.eclipse.sirius.tools.internal.command.builders.CommandBuilder#buildCommand()
   */
  @Override
  public Command buildCommand() {

    Command result = UnexecutableCommand.INSTANCE;

    if (permissionAuthority.canEditInstance(reconnectionSource)
        && permissionAuthority.canEditInstance(reconnectionTarget)
        && permissionAuthority.canEditInstance(edge)
        // Layouting mode on diagrams
        // if the ddiagram is in LayoutingMode, we do not allow reconnection
        && !isInLayoutingModeDiagram(edge)) {

      final EObject semanticSource =
          SiriusUtil.getNearestDecorateSemanticElement(reconnectionSource).getTarget();
      final EObject semanticTarget =
          SiriusUtil.getNearestDecorateSemanticElement(reconnectionTarget).getTarget();

      final Map<AbstractVariable, Object> variables = new HashMap<AbstractVariable, Object>();
      variables.put(tool.getElement(), edge.getTarget());
      variables.put(tool.getSource(), semanticSource);
      variables.put(tool.getSourceView(), reconnectionSource);
      variables.put(tool.getTarget(), semanticTarget);
      variables.put(tool.getTargetView(), reconnectionTarget);
      variables.put(tool.getEdgeView(), edge);

      // we create an hidden variable that will be used to
      // correct reconnection issues
      ICommandTask createOtherEndVariableTask = getOtherEndVariableCreationTask(variables);

      final DCommand cmd = createEnclosingCommand();
      cmd.getTasks().add(createOtherEndVariableTask);
      cmd.getTasks()
          .add(
              new InitInterpreterVariablesTask(
                  variables, InterpreterUtil.getInterpreter(reconnectionSource), uiCallback));
      Option<DDiagram> parentDiagram = getDDiagram();
      if (tool.getInitialOperation() != null
          && tool.getInitialOperation().getFirstModelOperations() != null) {
        cmd.getTasks()
            .add(
                taskHelper.buildTaskFromModelOperation(
                    parentDiagram.get(),
                    edge.getTarget(),
                    tool.getInitialOperation().getFirstModelOperations()));
      }
      final SetObject setObject = ToolFactory.eINSTANCE.createSetObject();
      final String featureName = getReconnectionKindFeatureName();
      setObject.setFeatureName(featureName);
      setObject.setObject(reconnectionTarget);

      Option<DRepresentation> representation = new EObjectQuery(edge).getRepresentation();
      final CommandContext edgeContext = new CommandContext(edge, representation.get());
      cmd.getTasks()
          .add(
              new SetValueTask(
                  edgeContext,
                  this.modelAccessor,
                  setObject,
                  new EObjectQuery(edge).getSession().getInterpreter()));

      final EdgeMapping newEdgeMapping = getEdgeMappingReconnector();
      addRefreshTask(edge, cmd, tool);
      final CompoundCommand cc = new CompoundCommand();
      if (newEdgeMapping != null && !newEdgeMapping.equals(edge.getActualMapping())) {
        cc.append(new SetEdgeActualMappingCommand(editingDomain, edge, newEdgeMapping));
      }
      if (reconnectionSource.equals(oldSource)
          && (newEdgeMapping != null && !newEdgeMapping.isUseDomainElement()
              || isEdgeActualMappingUsingDomainElement())) {
        cc.append(
            new ReconnectSourceNodeCommand(
                editingDomain, edge, reconnectionTarget, semanticTarget));
      }
      cc.append(cmd);
      result = cc;
    }
    return result;
  }