Package org.activiti.designer.features

Source Code of org.activiti.designer.features.MoveActivityFeature

package org.activiti.designer.features;

import java.util.List;

import org.activiti.bpmn.model.Activity;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Lane;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.designer.util.editor.Bpmn2MemoryModel;
import org.activiti.designer.util.editor.ModelHandler;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.graphiti.datatypes.ILocation;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.IMoveShapeContext;
import org.eclipse.graphiti.features.impl.DefaultMoveShapeFeature;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.services.IGaService;

/**
* This move feature takes care, that for all activity types, attached boundary events will move
* when the activity itself is moved.
*
* @author bardioc
*/
public class MoveActivityFeature extends DefaultMoveShapeFeature {

  protected ILocation shapeLocationBeforeMove;
 
  /** Creates the feature */
  public MoveActivityFeature(IFeatureProvider fp) {
    super(fp);
  }
 
  @Override
  public boolean canMoveShape(IMoveShapeContext context) {
    Object parentObject = getBusinessObjectForPictogramElement(context.getTargetContainer());
    return (context.getTargetContainer() instanceof Diagram ||
            parentObject instanceof SubProcess || parentObject instanceof Lane);
  }

 
 
  @Override
  protected void preMoveShape(IMoveShapeContext context) {
    final Shape shape = context.getShape();
    shapeLocationBeforeMove = Graphiti.getLayoutService().getLocationRelativeToDiagram(shape);
    super.preMoveShape(context);
  }

  /**
   * Makes sure attached boundary events will be moved too, in case the shape itself is moved.
   * Determines the amount of pixels the shape moved, finds out all boundary events of the shape
   * and moves them the same delta.
   *
   * @param context the context of the move
   */
  @Override
  protected void postMoveShape(IMoveShapeContext context) {
    final Shape shape = context.getShape();

    // get the activity itself to determine its boundary events
    final Activity activity = (Activity) getBusinessObjectForPictogramElement(shape);
    ILocation shapeLocationAfterMove = Graphiti.getLayoutService().getLocationRelativeToDiagram(shape);
    moveActivityChilds(activity, shapeLocationAfterMove);
   
    Bpmn2MemoryModel model = ModelHandler.getModel(EcoreUtil.getURI(getDiagram()));
   
    if (context.getSourceContainer() != context.getTargetContainer()) {
      if (context.getSourceContainer() instanceof Diagram == false) {
        Object containerBo = getFeatureProvider().getBusinessObjectForPictogramElement(context.getSourceContainer());
        if (containerBo instanceof SubProcess) {
          SubProcess subProcess = (SubProcess) containerBo;
          subProcess.removeFlowElement(activity.getId());
          for (SequenceFlow flow : activity.getOutgoingFlows()) {
            subProcess.removeFlowElement(flow.getId());
          }
          for (BoundaryEvent event : activity.getBoundaryEvents()) {
            subProcess.removeFlowElement(event.getId());
          }
        } else if (containerBo instanceof Lane) {
          Lane lane = (Lane) containerBo;
          lane.getFlowReferences().remove(activity.getId());
          lane.getParentProcess().removeFlowElement(activity.getId());
          for (SequenceFlow flow : activity.getOutgoingFlows()) {
            lane.getParentProcess().removeFlowElement(flow.getId());
          }
          for (BoundaryEvent event : activity.getBoundaryEvents()) {
            lane.getParentProcess().removeFlowElement(event.getId());
          }
        }
      } else {
        if (model.getBpmnModel().getMainProcess() != null) {
          model.getBpmnModel().getMainProcess().removeFlowElement(activity.getId());
          for (SequenceFlow flow : activity.getOutgoingFlows()) {
            model.getBpmnModel().getMainProcess().removeFlowElement(flow.getId());
          }
          for (BoundaryEvent event : activity.getBoundaryEvents()) {
            model.getBpmnModel().getMainProcess().removeFlowElement(event.getId());
          }
        }
      }
     
      if (context.getTargetContainer() instanceof Diagram == false) {
        Object containerBo = getFeatureProvider().getBusinessObjectForPictogramElement(context.getTargetContainer());
        if (containerBo instanceof SubProcess) {
          SubProcess subProcess = (SubProcess) containerBo;
          subProcess.addFlowElement(activity);
          for (SequenceFlow flow : activity.getOutgoingFlows()) {
            subProcess.addFlowElement(flow);
          }
          for (BoundaryEvent event : activity.getBoundaryEvents()) {
            subProcess.addFlowElement(event);
          }
        } else if (containerBo instanceof Lane) {
          Lane lane = (Lane) containerBo;
          lane.getFlowReferences().add(activity.getId());
          lane.getParentProcess().addFlowElement(activity);
          for (SequenceFlow flow : activity.getOutgoingFlows()) {
            lane.getParentProcess().addFlowElement(flow);
          }
          for (BoundaryEvent event : activity.getBoundaryEvents()) {
            lane.getParentProcess().addFlowElement(event);
          }
        }
      } else {
        if (model.getBpmnModel().getMainProcess() == null) {
          model.addMainProcess();
        }
        model.getBpmnModel().getMainProcess().addFlowElement(activity);
        for (SequenceFlow flow : activity.getOutgoingFlows()) {
          model.getBpmnModel().getMainProcess().addFlowElement(flow);
        }
        for (BoundaryEvent event : activity.getBoundaryEvents()) {
          model.getBpmnModel().getMainProcess().addFlowElement(event);
        }
      }
    }
  }
 
  private void moveActivityChilds(Activity activity, ILocation shapeLocationAfterMove) {
    // get all boundary events of the activity
    final List<BoundaryEvent> boundaryEvents = activity.getBoundaryEvents();
    moveBoundaryEvents(boundaryEvents, shapeLocationAfterMove);
   
    // also move all boundary events in the sub process
    if(activity instanceof SubProcess) {
      for (FlowElement subElement : ((SubProcess) activity).getFlowElements()) {
        if(subElement instanceof Activity) {
          moveActivityChilds((Activity) subElement, shapeLocationAfterMove);
        }
      }
    }
  }
 
  private void moveBoundaryEvents(final List<BoundaryEvent> boundaryEvents, ILocation shapeLocationAfterMove) {
    final IGaService gaService = Graphiti.getGaService();
    for (final BoundaryEvent boundaryEvent : boundaryEvents) {
     
      // get all pictogram elements. Actually this should be only a single element, however
      // Graphiti allows multiple elements. The loop itself will not really harm in this case
      final PictogramElement picto = getFeatureProvider().getPictogramElementForBusinessObject(boundaryEvent);
     
      // get the current position of the boundary event
      int x = picto.getGraphicsAlgorithm().getX();
      int y = picto.getGraphicsAlgorithm().getY();
     
      int deltaX = shapeLocationAfterMove.getX() - shapeLocationBeforeMove.getX();
      int deltaY = shapeLocationAfterMove.getY() - shapeLocationBeforeMove.getY();

      // move it the same delta in both directions, the activity itself has been moved
      gaService.setLocation(picto.getGraphicsAlgorithm(), x + deltaX, y + deltaY);
      Graphiti.getPeService().sendToFront((Shape) picto);
    }
  }
}
TOP

Related Classes of org.activiti.designer.features.MoveActivityFeature

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.