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,6 +226,29 @@ public class ConvertBPMNTypeCommand extends AbstractTransactionalCommand {
// reset boundary connections
commands.clear();
handleBoundaries(monitor, editingDomain, parentEditPart, targetElement, targetEditPart);
}
// if (targetElement instanceof ConnectableElement) {
// convertConnectorsAndKPIEvent(editingDomain, (ConnectableElement) targetElement);
// }
// Delete the old node : at this point the old node is already delete,
// that's the cause of the NPE
// diagramEditDomain.getDiagramCommandStack().execute(new
// ICommandProxy(new DeleteCommand(node.getNotationView())));
targetEditPart.getViewer().flush();
targetEditPart.refresh();// need to call refresh in order that it
targetEditPart.getViewer().select(targetEditPart);
targetEditPart.getRoot().refresh();
/* 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);
......@@ -277,24 +300,6 @@ public class ConvertBPMNTypeCommand extends AbstractTransactionalCommand {
}
}
// if (targetElement instanceof ConnectableElement) {
// convertConnectorsAndKPIEvent(editingDomain, (ConnectableElement) targetElement);
// }
// Delete the old node : at this point the old node is already delete,
// that's the cause of the NPE
// diagramEditDomain.getDiagramCommandStack().execute(new
// ICommandProxy(new DeleteCommand(node.getNotationView())));
targetEditPart.getViewer().flush();
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 */
refreshBoundaryElements(editingDomain, targetElement, targetEditPart, childPositions);
return CommandResult.newOKCommandResult(targetEditPart);
}
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");
}
};
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
Supports Markdown
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