/***************************************************************************** * Copyright (c) 2009 CEA LIST. * * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.helper; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.Map; 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.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.Transaction; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.workspace.AbstractEMFOperation; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPartViewer; import org.eclipse.gef.commands.Command; import org.eclipse.gmf.runtime.common.core.util.Log; import org.eclipse.gmf.runtime.common.core.util.StringStatics; import org.eclipse.gmf.runtime.common.core.util.Trace; import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand; import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIDebugOptions; import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIPlugin; import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIStatusCodes; import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.DefaultNodeEditPart; import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer; import org.eclipse.gmf.runtime.diagram.ui.util.EditPartUtil; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.common.Activator; import org.eclipse.papyrus.uml.diagram.common.editpolicies.OrphanViewPolicy; @SuppressWarnings("restriction") public class CleanDiagramHelper { protected static CleanDiagramHelper cleanDiagramHelper; /** The view to remove. */ protected ArrayList<View> viewToRemove = new ArrayList<View>(); protected DiagramEditPart selectedElement; public static CleanDiagramHelper getInstance() { if(cleanDiagramHelper == null) { cleanDiagramHelper = new CleanDiagramHelper(); } return cleanDiagramHelper; } /** * {@inheritDoc} */ public void run(DiagramEditPart diagramEditPart) { this.selectedElement = diagramEditPart; OrphanViewPolicy removeOrphanViewPolicy = (OrphanViewPolicy)diagramEditPart.getEditPolicy("RemoveOrphanView"); if(removeOrphanViewPolicy != null) { removeOrphanViewPolicy.forceRefresh(); } scan(diagramEditPart); deleteUnknownViews(); } /** * Delete unknown views. */ protected void deleteUnknownViews() { for(int i = 0; i < viewToRemove.size(); i++) { Activator.getDefault().logInfo("Remove " + viewToRemove.get(i)); executeCommand(getDeleteViewCommand(viewToRemove.get(i))); } } /** * comes from {@link OrphanViewPolicy}. * * @param cmd * the cmd */ @SuppressWarnings("rawtypes") protected void executeCommand(final Command cmd) { Map options = null; EditPart ep = selectedElement; boolean isActivating = true; // use the viewer to determine if we are still initializing the diagram // do not use the DiagramEditPart.isActivating since // ConnectionEditPart's // parent will not be a diagram edit part EditPartViewer viewer = ep.getViewer(); if(viewer instanceof DiagramGraphicalViewer) { isActivating = ((DiagramGraphicalViewer)viewer).isInitializing(); } if(isActivating || !EditPartUtil.isWriteTransactionInProgress((IGraphicalEditPart)selectedElement, false, false)) options = Collections.singletonMap(Transaction.OPTION_UNPROTECTED, Boolean.TRUE); AbstractEMFOperation operation = new AbstractEMFOperation(((IGraphicalEditPart)selectedElement).getEditingDomain(), StringStatics.BLANK, options) { protected IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { cmd.execute(); return Status.OK_STATUS; } }; try { operation.execute(new NullProgressMonitor(), null); } catch (ExecutionException e) { Trace.catching(DiagramUIPlugin.getInstance(), DiagramUIDebugOptions.EXCEPTIONS_CATCHING, getClass(), "executeCommand", e); //$NON-NLS-1$ Log.warning(DiagramUIPlugin.getInstance(), DiagramUIStatusCodes.IGNORED_EXCEPTION_WARNING, "executeCommand", e); //$NON-NLS-1$ } } /** * Try to construct. * * @param parent * the parent * @param child * the child * * @return the edits the part */ protected EditPart tryToConstruct(EditPart parent, View child) { if(selectedElement.getViewer().getEditPartFactory().createEditPart(parent, child) instanceof DefaultNodeEditPart) { viewToRemove.add(child); } else { Object object = selectedElement.getViewer().getEditPartRegistry().get(child); if(object instanceof EditPart) { return ((EditPart)object); } } return null; } /** * gets a {@link Command} to delete the supplied {@link View}. * * @param view * view to use * * @return command */ protected Command getDeleteViewCommand(View view) { TransactionalEditingDomain editingDomain = ((IGraphicalEditPart)selectedElement).getEditingDomain(); return new ICommandProxy(new DeleteCommand(editingDomain, view)); } /** * Scan. * * @param editPart * the edit part */ protected void scan(EditPart editPart) { View parentView = (View)editPart.getModel(); Iterator<EObject> iterator = parentView.eAllContents(); while(iterator.hasNext()) { EObject currentObject = iterator.next(); if(currentObject instanceof View) { tryToConstruct(editPart, (View)currentObject); } } } }