Commit 1fb5357f authored by Aurelien Pupier's avatar Aurelien Pupier
Browse files

BS-14246: take care of Exception Flow on activity type switch when

boundaries are no more valid
parent f5638635
/**
* Copyright (C) 2015 Bonitasoft S.A.
* Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2.0 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.studio.common.gmf.tools.convert;
import org.assertj.core.api.Assertions;
import org.bonitasoft.studio.model.process.Activity;
import org.bonitasoft.studio.model.process.BoundaryEvent;
import org.bonitasoft.studio.model.process.Pool;
import org.bonitasoft.studio.model.process.ProcessFactory;
import org.bonitasoft.studio.model.process.builders.PoolBuilder;
import org.bonitasoft.studio.model.process.builders.SequenceFlowBuilder;
import org.bonitasoft.studio.model.process.builders.TaskBuilder;
import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class RemoveBoundaryWithItsFlowsTest {
@Mock
private InternalTransactionalEditingDomain domain;
@Test
public void testBoundaryRemovedWithItsUniqueExceptionFlow() throws Exception {
final TaskBuilder taskTargetOfExceptionFlow = TaskBuilder.aTask().withName("Targeted Task of exception flow");
final TaskBuilder taskWithABoundary = TaskBuilder.aTask().withName("Task with Boundary");
final Pool pool = PoolBuilder.aPool().havingElements(taskWithABoundary, taskTargetOfExceptionFlow).build();
final Activity boundaryHolder = (Activity) pool.getElements().get(0);
final Activity boundaryTarget = (Activity) pool.getElements().get(1);
final BoundaryEvent boundaryToRemove = ProcessFactory.eINSTANCE.createBoundaryEvent();
boundaryHolder.getBoundaryIntermediateEvents().add(boundaryToRemove);
pool.getConnections().add(SequenceFlowBuilder.aSequenceFlow().havingSource(boundaryToRemove).havingTarget(boundaryTarget).build());
new RemoveBoundaryWithItsFlows(domain, boundaryToRemove, boundaryHolder).doExecute(null, null);
Assertions.assertThat(pool.getConnections()).isEmpty();
Assertions.assertThat(boundaryTarget.getIncoming()).isEmpty();
}
@Test
public void testBoundaryRemovedWithSeveralExceptionFlow() throws Exception {
final TaskBuilder firsTaskTargetOfExceptionFlow = TaskBuilder.aTask().withName("First Targeted Task of exception flow");
final TaskBuilder secondTargetOfExceptionFlow = TaskBuilder.aTask().withName("Second Targeted Task of exception flow");
final TaskBuilder taskWithABoundary = TaskBuilder.aTask().withName("Task with Boundary");
final Pool pool = PoolBuilder.aPool().havingElements(taskWithABoundary, firsTaskTargetOfExceptionFlow, secondTargetOfExceptionFlow).build();
final Activity boundaryHolder = (Activity) pool.getElements().get(0);
final Activity firstBoundaryTarget = (Activity) pool.getElements().get(1);
final Activity secondBoundaryTarget = (Activity) pool.getElements().get(2);
final BoundaryEvent boundaryToRemove = ProcessFactory.eINSTANCE.createBoundaryEvent();
boundaryHolder.getBoundaryIntermediateEvents().add(boundaryToRemove);
pool.getConnections().add(SequenceFlowBuilder.aSequenceFlow().havingSource(boundaryToRemove).havingTarget(firstBoundaryTarget).build());
pool.getConnections().add(SequenceFlowBuilder.aSequenceFlow().havingSource(boundaryToRemove).havingTarget(secondBoundaryTarget).build());
new RemoveBoundaryWithItsFlows(domain, boundaryToRemove, boundaryHolder).doExecute(null, null);
Assertions.assertThat(pool.getConnections()).isEmpty();
Assertions.assertThat(firstBoundaryTarget.getIncoming()).isEmpty();
Assertions.assertThat(secondBoundaryTarget.getIncoming()).isEmpty();
}
}
......@@ -226,55 +226,7 @@ public class ConvertBPMNTypeCommand extends AbstractTransactionalCommand {
// reset boundary connections
commands.clear();
for (final BoundaryEvent boundaryEvent : ((Activity) targetElement).getBoundaryIntermediateEvents()) {
final GraphicalEditPart boundaryEp = (GraphicalEditPart) targetEditPart.findEditPart(targetEditPart, boundaryEvent);
if (boundaryEp != null) {
for (int i = 0; i < boundaryEvent.getOutgoing().size(); i++) {
final Connection outgoing = boundaryEvent.getOutgoing().get(i);
final GraphicalEditPart boundaryTargetEP = (GraphicalEditPart) parentEditPart.findEditPart(parentEditPart.getRoot(),outgoing.getTarget());
if(boundaryTargetEP != null){
final ConnectionEditPart ep = (ConnectionEditPart) GMFTools.findEditPart((EditPart) parentEditPart.getRoot().getChildren().get(0),outgoing) ;
if(ep != null){
try {
new DeleteCommand(ep.getNotationView()).execute(null, null);
} catch (final ExecutionException e) {
BonitaStudioLog.error(e) ;
}
}
final AbstractEMFOperation recreateExceptionFlowsOperation = new AbstractEMFOperation(editingDomain, "Recreate Exception flow") {
@Override
protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
final IElementType elementType = ElementTypeRegistry.getInstance().getType("org.bonitasoft.studio.diagram.SequenceFlow_4001");
final Edge edge = ViewService.getInstance().createEdge(elementType,
ModelHelper.getDiagramFor(ModelHelper.getMainProcess(targetElement),editingDomain),
((IHintedType) elementType).getSemanticHint(), -1, true, targetEditPart.getDiagramPreferencesHint());
edge.setElement(outgoing);
edge.setSource(boundaryEp.getNotationView());
edge.setTarget(boundaryTargetEP.getNotationView());
edge.setVisible(true);
return new Status(IStatus.OK, "org.bonitasoft.studio.diagram.common", "Recreate Exception flow succeeded");
}
};
try {
recreateExceptionFlowsOperation.execute(monitor, null);
} catch (final ExecutionException e) {
BonitaStudioLog.error(e);
}
} else {
// TODO: remove target from list because it has been
// removed? for now this done at the end, in
// refreshBoundaryElements
}
}
}
}
handleBoundaries(monitor, editingDomain, parentEditPart, targetElement, targetEditPart);
}
// if (targetElement instanceof ConnectableElement) {
......@@ -290,11 +242,64 @@ public class ConvertBPMNTypeCommand extends AbstractTransactionalCommand {
targetEditPart.refresh();// need to call refresh in order that it
targetEditPart.getViewer().select(targetEditPart);
targetEditPart.getRoot().refresh();
/* Need to refresh the boundaries elment at the end of the conversion */
/* Need to refresh the boundaries element at the end of the conversion */
refreshBoundaryElements(editingDomain, targetElement, targetEditPart, childPositions);
return CommandResult.newOKCommandResult(targetEditPart);
}
protected void handleBoundaries(final IProgressMonitor monitor, final TransactionalEditingDomain editingDomain, final GraphicalEditPart parentEditPart,
final EObject targetElement, final GraphicalEditPart targetEditPart) {
for (final BoundaryEvent boundaryEvent : ((Activity) targetElement).getBoundaryIntermediateEvents()) {
final GraphicalEditPart boundaryEp = (GraphicalEditPart) targetEditPart.findEditPart(targetEditPart, boundaryEvent);
if (boundaryEp != null) {
for (int i = 0; i < boundaryEvent.getOutgoing().size(); i++) {
final Connection outgoing = boundaryEvent.getOutgoing().get(i);
final GraphicalEditPart boundaryTargetEP = (GraphicalEditPart) parentEditPart.findEditPart(parentEditPart.getRoot(),outgoing.getTarget());
if(boundaryTargetEP != null){
final ConnectionEditPart ep = (ConnectionEditPart) GMFTools.findEditPart((EditPart) parentEditPart.getRoot().getChildren().get(0),outgoing) ;
if(ep != null){
try {
new DeleteCommand(ep.getNotationView()).execute(null, null);
} catch (final ExecutionException e) {
BonitaStudioLog.error(e) ;
}
}
final AbstractEMFOperation recreateExceptionFlowsOperation = new AbstractEMFOperation(editingDomain, "Recreate Exception flow") {
@Override
protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
final IElementType elementType = ElementTypeRegistry.getInstance().getType("org.bonitasoft.studio.diagram.SequenceFlow_4001");
final Edge edge = ViewService.getInstance().createEdge(elementType,
ModelHelper.getDiagramFor(ModelHelper.getMainProcess(targetElement),editingDomain),
((IHintedType) elementType).getSemanticHint(), -1, true, targetEditPart.getDiagramPreferencesHint());
edge.setElement(outgoing);
edge.setSource(boundaryEp.getNotationView());
edge.setTarget(boundaryTargetEP.getNotationView());
edge.setVisible(true);
return new Status(IStatus.OK, "org.bonitasoft.studio.diagram.common", "Recreate Exception flow succeeded");
}
};
try {
recreateExceptionFlowsOperation.execute(monitor, null);
} catch (final ExecutionException e) {
BonitaStudioLog.error(e);
}
} else {
// TODO: remove target from list because it has been
// removed? for now this done at the end, in
// refreshBoundaryElements
}
}
}
}
}
protected static void refreshBoundaryElements(final TransactionalEditingDomain editingDomain, final EObject targetElement,
final GraphicalEditPart targetEditPart, final List<Pair<EObject, Point>> childPositions) {
for (final Pair<EObject, Point> pair : childPositions) {
......@@ -315,22 +320,12 @@ public class ConvertBPMNTypeCommand extends AbstractTransactionalCommand {
* can't be set on this kind of Element
*/
if (targetElement instanceof Activity) {
final AbstractEMFOperation operation = new AbstractEMFOperation(editingDomain, "Remove boundary child") {
@Override
protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
/*
* Remove the BoundaryEvent from the list and
* its outgoing transition
*/
((Activity) targetElement).getBoundaryIntermediateEvents().remove(childToResetPosition);
if (childToResetPosition instanceof BoundaryEvent) {
((BoundaryEvent) childToResetPosition).getOutgoing().clear();
}
return new Status(IStatus.OK, "org.bonitasoft.studio.diagram.common", "Remove boundary child succeeded");
}
};
/*
* Remove the BoundaryEvent from the list and
* its outgoing transition
*/
final AbstractEMFOperation operation = new RemoveBoundaryWithItsFlows(editingDomain, (BoundaryEvent) childToResetPosition,
(Activity) targetElement);
try {
operation.execute(new NullProgressMonitor(), null);
} catch (final ExecutionException e) {
......
/**
* Copyright (C) 2015 Bonitasoft S.A.
* Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2.0 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.studio.common.gmf.tools.convert;
import org.bonitasoft.studio.model.process.Activity;
import org.bonitasoft.studio.model.process.BoundaryEvent;
import org.bonitasoft.studio.model.process.Connection;
import org.bonitasoft.studio.model.process.TargetElement;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.workspace.AbstractEMFOperation;
public final class RemoveBoundaryWithItsFlows extends AbstractEMFOperation {
private final BoundaryEvent boundaryToRemove;
private final Activity boundaryHolder;
public RemoveBoundaryWithItsFlows(final TransactionalEditingDomain domain, final BoundaryEvent boundaryToRemove, final Activity boundaryHolder) {
super(domain, "Remove boundary child");
this.boundaryToRemove = boundaryToRemove;
this.boundaryHolder = boundaryHolder;
}
@Override
protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
/*
* Remove the BoundaryEvent from the list and
* its incoming and outgoing transition
*/
boundaryHolder.getBoundaryIntermediateEvents().remove(boundaryToRemove);
cleanExceptionFlow();
return new Status(IStatus.OK, "org.bonitasoft.studio.diagram.common", "Remove boundary child succeeded");
}
protected void cleanExceptionFlow() {
final EList<Connection> exceptionFlowsToDelete = boundaryToRemove.getOutgoing();
for (final Connection exceptionFlowToDelete : exceptionFlowsToDelete) {
EcoreUtil.remove(exceptionFlowToDelete);
final TargetElement target = exceptionFlowToDelete.getTarget();
if (target != null) {
target.getIncoming().remove(exceptionFlowToDelete);
}
}
exceptionFlowsToDelete.clear();
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment