package org.eclipse.uml2.diagram.common.async;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.core.services.ViewService;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.uml2.diagram.common.Messages;
public class ApplySynchronizationCommand extends AbstractTransactionalCommand {
private final SyncModelNode mySyncRoot;
private final ArrayList<View> myAddedTopLevelViews = new ArrayList<View>();
public ApplySynchronizationCommand(SyncModelNode syncRoot) {
super(syncRoot.getContext().getDomain(), Messages.ApplySynchronizationCommand_command_apply_synchronization, getWorkspaceFiles(syncRoot.getDiagramView()));
assert (syncRoot.getDiagramView() != null);
mySyncRoot = syncRoot;
}
public ArrayList<View> getAddedTopLevelViews() {
return myAddedTopLevelViews;
}
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
LinkedList<SyncModelNode> queue = new LinkedList<SyncModelNode>();
queue.add(mySyncRoot);
while (!queue.isEmpty()) {
SyncModelNode next = queue.removeFirst();
syncNode(next, queue);
}
return CommandResult.newOKCommandResult(myAddedTopLevelViews);
}
private void syncNode(SyncModelNode node, List<SyncModelNode> queue) {
View diagramView = node.getDiagramView();
assert (diagramView != null);
if (!node.isRoot() && !node.isChecked()) {
removeView(diagramView);
return;
}
node.applyCanonicalStyle();
for (SyncModelNode nextSyncChild : node.getChildren()) {
if (nextSyncChild.isChecked()) {
forceHasDiagramView(nextSyncChild);
queue.add(nextSyncChild);
} else {
if (nextSyncChild.getDiagramView() != null) {
queue.add(nextSyncChild); //diagram view will be removed at next step
}
}
}
}
private void forceHasDiagramView(SyncModelNode node) {
if (node.getDiagramView() != null && node.getDiagramView().getType().equals(node.getSyncModelView().getType())) {
return;
}
if (node.getDiagramView() != null && !node.getDiagramView().getType().equals(node.getSyncModelView().getType())) {
removeView(node.getDiagramView());
}
SyncModelNode parent = node.getParent();
View diagramParent = parent.getDiagramView();
if (node.isInCompartment()) {
View syncCompartment = node.getSyncModelCompartment();
View diagramCompartment = SyncModelNode.findCounterpart(syncCompartment, node.getParent().getDiagramView());
if (diagramCompartment == null) {
throw new IllegalStateException(//
"Can't find diagram compartment for sync-model compartment: " + syncCompartment + // //$NON-NLS-1$
", sync-model parent: " + node.getSyncModelView() + // //$NON-NLS-1$
", diagram parent: " + node.getDiagramView()); //$NON-NLS-1$
}
diagramParent = diagramCompartment;
}
View copy = ViewService.createNode(diagramParent, node.getSyncModelView().getElement(), node.getSyncModelView().getType(), mySyncRoot.getContext().getPreferencesHint());
assert copy != null;
if (diagramParent instanceof Diagram) {
myAddedTopLevelViews.add(copy);
}
node.associateWithDiagramView(copy);
node.applyCanonicalStyle();
}
private void removeView(View view) {
ViewUtil.destroy(view);
}
}