blob: 7e402e7d44446285ac011dba81a618c66b21562f [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2005, 2009 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.diagram.ui.util;
import java.util.Iterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.impl.InternalTransaction;
import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles;
import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
import org.eclipse.gmf.runtime.emf.core.util.PackageUtil;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
/**
* provides different utility functions for the EditPart
* @author mmostafa
*/
public class EditPartUtil {
/**
* gets the <code>Editpart</code>'s semantic element Class Id, this could be used to
* check the semantic element type
* @param editpart the owner of the semantic element
* @return the semantic element class Id
*/
public static String getSemanticEClassName(IGraphicalEditPart editPart) {
if (editPart.getModel() instanceof View){
View view = (View)editPart.getModel();
EObject element = view.getElement();
return element == null ? null : PackageUtil.getID(EMFCoreUtil.getProxyClass(element));
}
return null;
}
/**
* remove all the canonical edit policies on the passed edit part, if the considerChildren
* flag is ON, it will remove the canonical editpolicies on every edit part in the
* passed edit part hirarchy
* @param editPart the edit part to remove the edit policy from
* @param considerChildren determine the the canonical edit policies will be removed from
* children as well or not
*/
public static void removeCanonicalEditPolicies(EditPart editPart, boolean considerChildren) {
EditPolicy ep = editPart.getEditPolicy(EditPolicyRoles.CANONICAL_ROLE);
if (ep!=null){
editPart.removeEditPolicy(ep);
}
if (considerChildren){
Iterator childrenIterator = editPart.getChildren().iterator();
removeCanonicalEditPolicies(childrenIterator);
if (editPart instanceof AbstractGraphicalEditPart){
AbstractGraphicalEditPart gEP = (AbstractGraphicalEditPart)editPart;
Iterator sourceConnectionsIterator = gEP.getSourceConnections().iterator();
removeCanonicalEditPolicies(sourceConnectionsIterator);
Iterator targetConnectionsIterator = gEP.getTargetConnections().iterator();
removeCanonicalEditPolicies(targetConnectionsIterator);
}
}
}
private static void removeCanonicalEditPolicies(Iterator childrenIterator) {
while (childrenIterator.hasNext()) {
EditPart child = (EditPart)childrenIterator.next();
removeCanonicalEditPolicies(child,true);
}
}
/**
* Used as general utility usually in the context of handling notifications to ensure that a runnable will
* be run in the appropriate thread context so that SWT or other reservered resources can be accessed. Should be only
* be used when the client is sure that in the stack of execution SWT resources will be accessed directly. Otherwise,
* this could incur a performance penalty when handling notifications. Also, it may spawn the runnable asynchronously
* to the main thread which may break assumptions on ordering when the events are handled.
*
* @param editPart the <code>EditPart</code> that is receiving notification or is being accessed potentially
* on a worker thread that needs to ensure safe access to SWT or other resources reserved for the main thread.
* @param runThreadSafe the <code>Runnable</code> that is to be executed in a thread safe manner.
*/
public static void synchronizeRunnableToMainThread(IGraphicalEditPart editPart, Runnable runThreadSafe) {
InternalTransactionalEditingDomain editingDomain = (InternalTransactionalEditingDomain)editPart.getEditingDomain();
if (Display.getCurrent() == null && editingDomain != null && editingDomain.getActiveTransaction() != null) {
Display display = PlatformUI.isWorkbenchRunning() ? PlatformUI.getWorkbench().getDisplay() : Display.getDefault();
if (editingDomain != null) {
display.syncExec(editingDomain.createPrivilegedRunnable(runThreadSafe));
}
else {
display.asyncExec(runThreadSafe);
}
}
else {
runThreadSafe.run();
}
}
/**
* Checks if the current active transaction is a Write transaction or not
* unprotected transaction are not considered write transaction
*
* @param editPart the <code>IGraphicalEditPart</code> that is used as a context to find the currently
* running transaction if any.
* @param includeUnprotected <code>boolean</code> value that if <code>true</code> will consider unprotected
* transactions when determining if a write transaction is in progress.
* @param otherThread <code>boolean</code> value that if <code>true</code>, will verify whether there is
* an active transaction only when on a different thread then the caller. This is useful to determine if a
* deadlock scenario will occur.
* @return <code>true</code> if the current active transaction is a write transaction
*/
public static boolean isWriteTransactionInProgress(IGraphicalEditPart editPart, boolean includeUnprotected, boolean otherThread) {
TransactionalEditingDomain theEditingDomain = editPart.getEditingDomain();
if (theEditingDomain instanceof InternalTransactionalEditingDomain){
InternalTransactionalEditingDomain internalEditingDomain =
(InternalTransactionalEditingDomain)theEditingDomain;
InternalTransaction transaction = internalEditingDomain.getActiveTransaction();
if (transaction!=null && !transaction.isReadOnly()) {
if (!includeUnprotected) {
Object unprotectedMode = transaction.getOptions().get(Transaction.OPTION_UNPROTECTED);
if (Boolean.TRUE.equals(unprotectedMode)) {
return false;
}
}
if (otherThread && Thread.currentThread() != transaction.getOwner())
return true;
else if (!otherThread)
return true;
}
}
return false;
}
}