package org.eclipse.uml2.diagram.common.async;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.core.services.ViewService;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CanonicalEditPolicy;
import org.eclipse.gmf.runtime.emf.core.GMFEditingDomainFactory;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.uml2.diagram.common.genapi.IDiagramUpdater;
import org.eclipse.uml2.diagram.common.genapi.IVisualIDRegistry;
public class SynchronizeDiagramAction implements IObjectActionDelegate {
private final IVisualIDRegistry myVisualIDRegistry;
private final IDiagramUpdater myDiagramUpdater;
private final ILabelProvider myDiagramSpecificLabelProvider;
private IWorkbenchPart targetPart;
private View myRootDiagramView;
private PreferencesHint myPreferencesHint;
public SynchronizeDiagramAction(IDiagramUpdater diagramUpdater, IVisualIDRegistry visualIDRegistry, ILabelProvider diagramSpecificLabelProvider) {
myDiagramUpdater = diagramUpdater;
myVisualIDRegistry = visualIDRegistry;
myDiagramSpecificLabelProvider = diagramSpecificLabelProvider;
}
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
this.targetPart = targetPart;
}
public void selectionChanged(IAction action, ISelection selection) {
action.setEnabled(false);
if (selection instanceof IStructuredSelection == false || selection.isEmpty()) {
return;
}
Object firstSelected = ((IStructuredSelection) selection).getFirstElement();
myRootDiagramView = null;
myPreferencesHint = null;
if (firstSelected instanceof IGraphicalEditPart) {
IGraphicalEditPart ep = (IGraphicalEditPart) firstSelected;
View view = ep.getNotationView();
int visualId = myVisualIDRegistry.getVisualID(view);
if (visualId > 0) {
if (myVisualIDRegistry.isCompartmentVisualID(visualId)) {
view = (View) view.eContainer();
}
myRootDiagramView = view;
myPreferencesHint = ep.getDiagramPreferencesHint();
}
}
action.setEnabled(myRootDiagramView != null);
}
private Shell getShell() {
return targetPart.getSite().getShell();
}
public void run(IAction action) {
SyncModelContext context = createContext();
try {
SyncModelNode root = createRootNode(context);
SynchronizeDiagramDialog dialog = new SynchronizeDiagramDialog(getShell(), root, myDiagramSpecificLabelProvider);
for (ViewerFilter filter : createViewerFilters()) {
dialog.addFilter(filter);
}
if (dialog.open() == Dialog.OK) {
applySynchronization(dialog.getRootSyncNode());
}
} finally {
context.dispose();
}
}
protected List<ViewerFilter> createViewerFilters() {
return Collections.emptyList();
}
private void applySynchronization(SyncModelNode syncRoot) {
SyncModelContext context = syncRoot.getContext();
ApplySynchronizationCommand applyCommand = new ApplySynchronizationCommand(syncRoot);
context.runCommand(applyCommand);
performCanonicalUpdate(syncRoot.getDiagramView().getDiagram().getElement());
context.dispose();
}
private SyncModelNode createRootNode(SyncModelContext context) {
final Resource syncModelResource = context.getSyncModelResource();
final Diagram syncDiagram = ViewService.createDiagram(myRootDiagramView.getDiagram().getElement(), myVisualIDRegistry.getModelID(myRootDiagramView), myPreferencesHint);
View syncRoot;
if (myRootDiagramView instanceof Diagram) {
syncRoot = syncDiagram;
} else {
syncRoot = ViewService.createNode(syncDiagram, myRootDiagramView.getElement(), myRootDiagramView.getType(), myPreferencesHint);
}
context.runCommand(new Runnable() {
public void run() {
syncModelResource.getContents().add(syncDiagram);
}
});
SyncModelNode result = new SyncModelNode(syncRoot, myRootDiagramView, context);
return result;
}
private SyncModelContext createContext() {
TransactionalEditingDomain editingDomain = GMFEditingDomainFactory.INSTANCE.getEditingDomain(myRootDiagramView.eResource().getResourceSet());
return new SyncModelContext(myDiagramUpdater, myVisualIDRegistry, myPreferencesHint, editingDomain);
}
private static void performCanonicalUpdate(EObject modelElement) {
if (modelElement == null) {
return;
}
List<?> editPolicies = CanonicalEditPolicy.getRegisteredEditPolicies(modelElement);
for (Iterator<?> it = editPolicies.iterator(); it.hasNext();) {
CanonicalEditPolicy nextEditPolicy = (CanonicalEditPolicy) it.next();
nextEditPolicy.refresh();
}
}
}