blob: c31092bc5f5dff75ec5c17f117d95030f34cda47 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2004, 2010 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.editpolicies;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.diagram.ui.commands.DeferredLayoutCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.SetViewMutabilityCommand;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.INodeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.figures.ICanonicalShapeCompartmentLayout;
import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIPlugin;
import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest.ConnectionViewDescriptor;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
import org.eclipse.gmf.runtime.emf.core.util.PackageUtil;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.osgi.util.NLS;
/**
* A specialized implementation of <code>CanonicalEditPolicy</code>.
* This implementation will manage connections owned by the semantic host.
*
* @author mhanner / sshaw
*/
public abstract class CanonicalConnectionEditPolicy
extends CanonicalEditPolicy {
/**
* Return a list of semantic relationships contained inside this
* compartment.
* @return EObject list
*
*/
abstract protected List<EObject> getSemanticConnectionsList();
/**
* Return the supplied relationship's source element
* @param relationship semantic connection
* @return EObject the source EObject
*/
abstract protected EObject getSourceElement(EObject relationship);
/**
* Return the supplied relationship's target element.
*
* @param relationship semantic connection
* @return EObject the target EObject
*/
abstract protected EObject getTargetElement(EObject relationship);
/** Return an empty list. */
protected List<EObject> getSemanticChildrenList() {
return Collections.emptyList();
}
/*
* Override to ensure that all owned editparts are activated before the editpolicy refresh
* is invoked that will try to canonically create connections and shapes.
*/
protected void refreshOnActivate() {
// need to activate editpart children before invoking the canonical refresh
List<EditPart> c = getHost().getChildren();
for (int i = 0; i < c.size(); i++) {
c.get(i).activate();
}
refresh();
}
/**
* Return <tt>true</tt> if the connection should be drawn between the
* supplied endpoints; otherwise return <tt>false</tt>.
*
* @param a
* connection's source element
* @param a
* connection's target element
* @return <tt>true</tt> if both parameters are not <tt>null</tt>;
* otherwise <tt>false</tt>
*/
protected boolean canCreateConnection(EditPart sep, EditPart tep,
EObject connection) {
if (sep != null && sep.isActive() && tep != null && tep.isActive()) {
View src = (View) sep.getAdapter(View.class);
View tgt = (View) tep.getAdapter(View.class);
if (src != null && tgt != null) {
EditPart sourceParent = sep.getParent();
while (sourceParent instanceof GroupEditPart) {
sourceParent = sourceParent.getParent();
}
EditPart targetParent = tep.getParent();
while (targetParent instanceof GroupEditPart) {
targetParent = targetParent.getParent();
}
return sourceParent.getEditPolicy(
EditPolicyRoles.CANONICAL_ROLE) != null
&& targetParent.getEditPolicy(
EditPolicyRoles.CANONICAL_ROLE) != null;
}
}
return false;
}
/**
* Return the editpart mapped to the object. The editpart is retrieved from
* a [view,semantic] mapping. {@link #getView(IElement)}is called if the
* mapping cannot be found inside this manager.
*
* @param element
* an <tt>View</tt> or <tt>EObject</tt> instance.
* @param context
* an <code>EObject</code> that is the context for the element. Typically,
* this will be either <code>null</code> or it will the <code>Edge</code>
* that is connected to the <code>element</code> to find the <code>EditPart</code> of.
* @return an editpart; <tt>null</tt> if non could be found.
*/
private EditPart getEditPartFor(EObject element, EObject context) {
if (element != null && !(element instanceof View)) {
EditPartViewer viewer = getHost().getViewer();
if (viewer instanceof IDiagramGraphicalViewer) {
List<EditPart> parts = ((IDiagramGraphicalViewer) viewer)
.findEditPartsForElement(EMFCoreUtil.getProxyID(element),
INodeEditPart.class);
if (parts.isEmpty()) {
// reach for the container's editpart instead and force it
// to refresh
EObject container = element.eContainer();
EditPart containerEP = getEditPartFor(container, null);
if (containerEP != null) {
containerEP.refresh();
parts = ((IDiagramGraphicalViewer) viewer)
.findEditPartsForElement(EMFCoreUtil.getProxyID(element),
INodeEditPart.class);
}
}
// Check if the part is contained with-in the host EditPart
// since we are canonically updated the host.
return findEditPartForElement(element, context, parts);
}
}
return (EditPart) host().getViewer().getEditPartRegistry().get(element);
}
/**
* Finds the specific <code>EditPart</code> from a <code>List</code> of editparts
* that is the exact representation of the given <code>element</code> in the
* host context.
*
* @param element
* an <tt>View</tt> or <tt>EObject</tt> instance.
* @param context
* an <code>EObject</code> that is the context for the element. Typically,
* this will be either <code>null</code> or it will the <code>Edge</code>
* that is connected to the <code>element</code> to find the <code>EditPart</code> of.
* @param parts
* a <code>List</code> of <code>EditPart</codes> to search for a specific
* instance that is the exact representation of <code>element</code>
* in the host context.
* @return an editpart; <tt>null</tt> if non could be found.
*/
protected EditPart findEditPartForElement(EObject element, EObject context, List<EditPart> parts) {
EditPart ancestor = getHost();
while (ancestor != null) {
EditPart ep = reachForEditPartWithAncestor(parts, ancestor);
if (ep != null) {
return ep;
}
ancestor = ancestor.getParent();
}
return null;
}
/**
* Walks up the container tree and tries to find the EditPart that has the
* given <code>EditPart</code> as an ancestor.
*
* @param results
* <code>List</code> of <code>EditPart</code> objects
* @param ancestor
* <code>EditPart</code> to check against.
* @return <code>EditPart</code> that contains the <code>ancestor</code>
* in it's containment hierarchy
*/
private EditPart reachForEditPartWithAncestor(List<EditPart> results,
EditPart ancestor) {
ListIterator<EditPart> li = results.listIterator();
while (li.hasNext()) {
EditPart ep = (EditPart) li.next();
EditPart walker = ep.getParent();
while (walker != null) {
if (walker.equals(ancestor))
return ep;
walker = walker.getParent();
}
}
return null;
}
/**
* Returns the default factory hint.
*
* @return an empty string
*/
protected String getDefaultFactoryHint() {
return "";//$NON-NLS-1$
}
/**
* Creates a connection view facde element for the supplied semantic element.
* An empty string is used as the default factory hint.
*
* @param element
* the semantic element
* @param the
* connections source editpart
* @param the
* connections target editpart
* @param index
* semantic elements position
*/
protected final Edge createConnectionView(EObject connection, int index) {
EditPart sep = getSourceEditPartFor(connection);
EditPart tep = getTargetEditPartFor(connection);
if (!canCreateConnection(sep, tep, connection)) {
return null;
}
View sView = (View) sep.getModel();
View tView = (View) tep.getModel();
Edge model = null;
String factoryHint = getDefaultFactoryHint();
IAdaptable elementAdapter = new CanonicalElementAdapter(connection,
factoryHint);
CreateConnectionViewRequest ccr = getCreateConnectionViewRequest(
elementAdapter, getFactoryHint(elementAdapter, factoryHint), index);
ccr.setType(RequestConstants.REQ_CONNECTION_START);
ccr.setSourceEditPart(sep);
getCreateViewCommand(ccr); // sep.getCommand(ccr); //prime the command
ccr.setTargetEditPart(tep);
ccr.setType(RequestConstants.REQ_CONNECTION_END);
Command cmd = getCreateViewCommand(ccr); // tep.getCommand(ccr);
if (cmd != null && cmd.canExecute()) {
List<EObjectAdapter> viewAdapters = new ArrayList<EObjectAdapter>();
viewAdapters.add(new EObjectAdapter(((View) host().getModel())
.getDiagram()));
viewAdapters.add(new EObjectAdapter(sView));
viewAdapters.add(new EObjectAdapter(tView));
SetViewMutabilityCommand.makeMutable(viewAdapters).execute();
executeCommand(cmd);
IAdaptable adapter = (IAdaptable) ccr.getNewObject();
SetViewMutabilityCommand.makeMutable(adapter).execute();
model = (Edge) adapter.getAdapter(Edge.class);
if (model == null) {
String eMsg = NLS
.bind(
DiagramUIMessages.CanonicalEditPolicy_create_view_failed_ERROR_,
connection);
IllegalStateException ise = new IllegalStateException(eMsg);
Log.error(DiagramUIPlugin.getInstance(), IStatus.ERROR, eMsg,
ise);
throw ise;
}
}
return model;
}
/**
* Calculates the <code>EditPart</code> that this connection element is
* connected to at it's target.
*
* @param connection
* the <code>EObject</code> element that we are canonical
* trying to create a view for.
* @return the <code>EditPart</code> that is the source of the
* <code>View</code> we want to create
*/
protected EditPart getTargetEditPartFor(EObject connection) {
EObject tel;
EditPart tep;
tel = getTargetElement(connection);
tep = getEditPartFor(tel, connection);
return tep;
}
/**
* Calculates the <code>EditPart</code> that this connection element is
* connected to at it's source.
*
* @param connection
* the <code>EObject</code> element that we are canonical
* trying to create a view for.
* @return the <code>EditPart</code> that is the target of the
* <code>View</code> we want to create
*/
protected EditPart getSourceEditPartFor(EObject connection) {
EObject sel;
EditPart sep;
sel = getSourceElement(connection);
sep = getEditPartFor(sel, connection);
return sep;
}
/**
* Forwards the supplied request to its source if the target is
* <tt>null</tt>; otherwise it is forwarded to the target. Forwards the
* supplied request to the editpart's <code>host</code>.
*
* @param request
* a <code>CreareConnecgtorViewRequest</code>
* @return Command to create the views in the request
*/
protected Command getCreateViewCommand(CreateRequest request) {
if (request instanceof CreateConnectionViewRequest) {
CreateConnectionViewRequest ccr = (CreateConnectionViewRequest) request;
EditPart ep = ccr.getTargetEditPart() == null ? ccr
.getSourceEditPart()
: ccr.getTargetEditPart();
return ep.getCommand(request);
}
return super.getCreateViewCommand(request);
}
/**
* Return a create view request.
*
* @param descriptor
* a {@link CreateViewRequest.ViewDescriptor}.
* @return a create request
*/
protected CreateViewRequest getCreateViewRequest(
CreateViewRequest.ViewDescriptor descriptor) {
return getCreateViewRequest(Collections.singletonList(descriptor));
}
/**
* Return a create view request. The request's location is set to
* {@link ICanonicalShapeCompartmentLayout#UNDEFINED}.
*
* @param descriptors
* a {@link CreateViewRequest.ViewDescriptor} list.
* @return a create request
*/
protected CreateViewRequest getCreateViewRequest(List<ViewDescriptor> descriptors) {
CreateViewRequest cvr = super.getCreateViewRequest(descriptors);
Point loc = ICanonicalShapeCompartmentLayout.UNDEFINED.getLocation();
cvr.setLocation(loc);
return cvr;
}
/**
* Return a create connection view request.
*
* @param elementAdapter
* semantic element
* @param viewKind
* type of view to create
* @param hint
* factory hint
* @param index
* index
* @return a create <i>non-persisted </i> view request
*/
private CreateConnectionViewRequest getCreateConnectionViewRequest(
IAdaptable elementAdapter, String hint, int index) {
return new CreateConnectionViewRequest(getConnectionViewDescriptor(
elementAdapter, hint, index));
}
/**
* Return a connection view descriptor.
*
* @param elementAdapter
* semantic element
* @param hint
* factory hint
* @param index
* index
* @return a create <i>non-persisted </i> connection view descriptor
*/
private ConnectionViewDescriptor getConnectionViewDescriptor(
IAdaptable elementAdapter, String hint, int index) {
return new ConnectionViewDescriptor(elementAdapter, hint, index, false,
((IGraphicalEditPart) getHost()).getDiagramPreferencesHint());
}
/**
* Updates the set of connection views so that it is in sync with the
* semantic connections. This method is called in response to notification
* from the model.
* <P>
* The update is performed by comparing the existing connection views with the
* set of semantic connections returned from {@link #getSemanticConnections()}.
* Views whose semantic connection no longer exists or whose semantic
* connection ends are <tt>null</tt> are
* {@link org.eclipse.gmf.runtime.diagram.ui.editpolicies.CanonicalEditPolicy#deleteViews(Iterator) removed}.
* New semantic children have their View
* {@link #createEdge(IElement, EditPart, EditPart, int, String)
* created}. Subclasses must override <code>getSemanticConnections()</code>.
* <P>
* This refresh routine will not reorder the view list to ensure both it and
* the semantic children are in the same order since it is possible that
* this editpolicy will only handle a specific subset of the host's views.
*
* This method should <em>not</em> be overridden.
*
* @return <code>List</code> of new <code>IAdaptable</code> objects that
* adapt to <code>View</code> objects that were created as a
* result of the synchronization
*/
protected List<IAdaptable> refreshSemanticConnections() {
Edge viewChild;
// current connection views
Collection<Edge> viewChildren = getConnectionViews();
Collection<EObject> semanticChildren = new HashSet<EObject>();
semanticChildren.addAll(getSemanticConnectionsList());
List<View> orphaned = cleanCanonicalSemanticChildren(viewChildren,
semanticChildren);
// delete all the remaining views
deleteViews(orphaned.iterator());
// create a view for each remaining semantic element.
List<IAdaptable> viewDescriptors = new ArrayList<IAdaptable>();
for(EObject semanticChild : semanticChildren) {
viewChild = createConnectionView(semanticChild, ViewUtil.APPEND);
if (viewChild != null) {
viewDescriptors.add(new EObjectAdapter(viewChild));
}
}
makeViewsMutable(viewDescriptors);
// now refresh all the connection containers to update the editparts
HashSet<EditPart> ends = new HashSet<EditPart>();
ListIterator<IAdaptable> li = viewDescriptors.listIterator();
while (li.hasNext()) {
IAdaptable adaptable = li.next();
Edge edge = (Edge)adaptable.getAdapter(Edge.class);
EditPart sourceEP = getEditPartFor(edge.getSource(), edge);
if (sourceEP != null) {
ends.add(sourceEP);
}
EditPart targetEP = getEditPartFor(edge.getTarget(), edge);
if (targetEP != null) {
ends.add(targetEP);
}
}
for(EditPart end : ends) {
end.refresh();
}
return viewDescriptors;
}
@Override
protected boolean isOrphaned(Collection<EObject> semanticChildren, View view) {
EObject element = view.getElement();
if (semanticChildren.contains(element)) {
if (view instanceof Edge) {
Edge edge = (Edge) view;
if ((edge.getSource() == null || (edge.getSource().getElement() != getSourceElement(element)))
|| (edge.getTarget() == null || (edge.getTarget()
.getElement() != getTargetElement(element)))) {
return true;
}
}
} else {
return true;
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.CanonicalEditPolicy#refreshSemantic()
*/
protected void refreshSemantic() {
List<IAdaptable> createdViews = super.refreshSemanticChildren();
List<IAdaptable> createdConnectionViews = refreshSemanticConnections();
// perform a layout of the container
DeferredLayoutCommand layoutCmd = new DeferredLayoutCommand(host()
.getEditingDomain(), createdViews, host());
if (!createdViews.isEmpty() && layoutCmd.canExecute()) {
executeCommand(new ICommandProxy(layoutCmd));
}
List<IAdaptable> allViews = new ArrayList<IAdaptable>(
createdConnectionViews.size() + createdViews.size());
allViews.addAll(createdViews);
allViews.addAll(createdConnectionViews);
makeViewsImmutable(allViews);
}
/**
* Return <tt>true</tt> if this editpolicy should try and delete the
* supplied view; otherwise <tt>false<tt>.
* The default behaviour is to return <tt>true</tt> if the view's semantic element is <tt>null</tt>.
* <P>
* Subclasses should override this method to ensure the correct behaviour.
* @return <code>view.resolveSemanticElement() == null</code>
*/
protected boolean shouldDeleteView(View view) {
return ViewUtil.resolveSemanticElement(view) == null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.CanonicalEditPolicy#postProcessRefreshSemantic(java.util.List)
*/
protected void postProcessRefreshSemantic(List<IAdaptable> viewDescriptors) {
makeViewsMutable(viewDescriptors);
super.postProcessRefreshSemantic(viewDescriptors);
}
/**
* Return the list of connections between elements contained within the host
* compartment.
*
* @return list of <code>Edge</code>s.
*/
protected Collection<Edge> getConnectionViews() {
Collection<View> children = getViewChildren();
Set<Edge> connections = new HashSet<Edge>();
if (getHost() instanceof IGraphicalEditPart) {
IGraphicalEditPart gep = (IGraphicalEditPart)getHost();
getConnectionViews(connections, gep.getNotationView(), children);
}
return connections;
}
/**
* Add all connections that are attached to the given node and any of it's
* children.
*
* @param connections
* @param node
*/
private void getConnectionViews(Set<Edge> connections, View view, Collection<View> viewChildren ) {
IGraphicalEditPart gep = (IGraphicalEditPart)getHost();
View hostView = gep.getNotationView();
if (hostView != view) {
if (!shouldCheckForConnections(view, viewChildren)) {
return;
}
}
for (Edge sourceEdge : (List<Edge>) ViewUtil.getSourceConnections(view)) {
if (shouldIncludeConnection(sourceEdge, viewChildren)) {
connections.add(sourceEdge);
}
}
for (Edge targetEdge : (List<Edge>) ViewUtil.getTargetConnections(view)) {
if (shouldIncludeConnection(targetEdge, viewChildren)) {
connections.add(targetEdge);
}
}
for(View viewChild : (List<View>)view.getChildren()){
if (viewChild instanceof Node) {
getConnectionViews(connections, viewChild, viewChildren );
}
}
}
/**
* Determines if a given view should be checked to see if any attached connections should be considered
* by the canonical synchronization routine. By default it will consider views that are 2 levels deep from the
* container in order to allow for connections that are attached to border items on children views in the
* container.
*
* @param view a <code>View</code> to check to see if attached connections should be considered.
* @param viewChildren a <code>Collection</code> of view children of the host notation view, that can be used
* as a context to determine if the given view's attached connections should be considered.
* @return a <code>boolean</code> <code>true</code> if connections on the view are used as part of the
* canonical synchronization. <code>false</code> if the view's attached connections are to be ignored.
*/
protected boolean shouldCheckForConnections(View view, Collection<View> viewChildren) {
return (view != null &&
(viewChildren.contains(view) || viewChildren.contains(view.eContainer())));
}
/**
* Called by {@link #getConnectionViews()} to determine if the underlying
* shape compartment is responsible for the supplied connection. By default,
* the following condition must be met for the connection to be accepted:
* <UL>
* <LI> its source must not be null.
* <LI> its target must not be null.
* <LI> the shape compartment contains the source (or the source's container
* view).
* <LI> the shape compartment contains the target (or the target's container
* view). </LI>
*
* @param connection
* the connection view
* @param children
* underlying shape compartment's children.
* @return <tt>false</tt> if supplied connection should be ignored;
* otherwise <tt>true</tt>.
*/
protected boolean shouldIncludeConnection(Edge connection, Collection<View> children) {
return shouldCheckForConnections(connection.getSource(), children) ||
shouldCheckForConnections(connection.getTarget(), children);
}
/**
* Return {@link UnexecutableCommand} if the editpolicy is enabled and a
* {@link DropObjectsRequest} is passed as an argument and its objects are
* contained in the list of semantic children.
*/
public Command getCommand(Request request) {
if (understandsRequest(request)) {
if (isEnabled() && request instanceof DropObjectsRequest) {
return getDropCommand((DropObjectsRequest) request);
}
}
return super.getCommand(request);
}
/**
* gets an <code>UnexecutableCommand</code> if the droprequest cannot be
* supported; the semantic host cannot contain the element being dropped or
* this editpolicy is enabled and it already contains of view for the
* elements being dropped.
*
* @param request
* the request to use
* @return <code>Command</code>
*/
protected Command getDropCommand(DropObjectsRequest request) {
boolean enabled = isEnabled();
List children = getSemanticChildrenList();
for(Object dropElement : request.getObjects()) {
// Allow diagram links on Canonical shapes compartments
if (allowDropElement(dropElement)) {
continue;
}
if (dropElement instanceof EObject
&& preventDropElement(dropElement)) {
return UnexecutableCommand.INSTANCE;
}
boolean containsElement = children.contains(dropElement);
if (enabled) {
if (containsElement || preventDropElement(dropElement)) {
return UnexecutableCommand.INSTANCE;
}
}
}
return null;
}
/**
* Return <tt>false</tt> if the supplied element should be prevented from
* being dropped into this editpolicy's host; otherwise <tt>true</tt>.
* This method is called by {@link #getDropCommand(DropObjectsRequest)} if
* this editpolicy is enabled.
*
* @param dropElement
* object being dropped.
* @return <code>PackageUtil.canContain(getSemanticHost().eClass(), ((EObject)dropElement).eClass(), false)</code>
* if the supplied element is an <code>EObject</code>; otherwise
* <tt>false</tt>
*/
protected boolean preventDropElement(Object dropElement) {
return dropElement instanceof EObject ? !PackageUtil.canContain(
getSemanticHost().eClass(), ((EObject) dropElement).eClass(), false)
: false;
}
/**
* Return <tt>true</tt> if the supplied element should be able to be
* dropped into this editpolicy's host; otherwise <tt>false</tt>. This
* method is called by {@link #getDropCommand(DropObjectsRequest)} if this
* editpolicy is enabled. Returning false will necessarily prevent the
* element from being dropped; the <code>getDropCommand</code> method will
* also invoke <code>preventDropElement</code>.
*
* @param dropElement
* object being dropped.
* @return true if dropping the supplied element is supported, false
* otherwise.
*/
protected boolean allowDropElement(Object dropElement) {
return dropElement instanceof Diagram;
}
/**
* Understands the following:
* <UL>
* <LI>{@link DropObjectsRequest}
* <LI>{@link RequestConstants#REQ_DROP_OBJECTS}
* <LI>{@link org.eclipse.gef.RequestConstants#REQ_CREATE}
* </UL>
*/
public boolean understandsRequest(Request req) {
return (RequestConstants.REQ_DROP_OBJECTS.equals(req.getType())
|| req instanceof DropObjectsRequest || RequestConstants.REQ_CREATE
.equals(req.getType())) ? true
: super.understandsRequest(req);
}
/**
* Determines if this editpolicy would create a view for the supplied
* semantic element. The default implementation will return <tt>true</tt>
* if the supplied <tt>eObject</tt> is contained in {@link #getSemanticConnectionsList()}.
* @param eObject a semantic element
* @return <tt>true</tt> if this policy would create a view;
* <tt>false</tt> otherwise.
*/
public boolean canCreate( EObject eObject ) {
return super.canCreate(eObject) || getSemanticConnectionsList().contains(eObject);
}
}