/******************************************************************************* * Copyright (c) 2012 Google, Inc. * 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: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.runtime.gef.internal.finder; import java.util.HashSet; import java.util.Set; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.NodeEditPart; import org.eclipse.gef.requests.CreateConnectionRequest; import org.eclipse.gef.requests.ReconnectRequest; /** * Gets anchors from a given part. */ public class AnchorRequester { private static final ConnectionAnchor[] NONE = new ConnectionAnchor[]{}; private static final int NUM_ATTEMPTS_PER_REQUEST = 2; public ConnectionAnchor[] requestAnchorsForFigureWithNodePart( IFigure figure, NodeEditPart part) throws MultipleAnchorsForLocationException { Rectangle bounds = figure.getBounds(); Set anchors = new HashSet(); for (int y = 0; y < bounds.height; ++y) { for (int x = 0; x < bounds.width; ++x) { addAnchorsForPoint(part, anchors, new Point(bounds.x + x, bounds.y + y)); } } return (ConnectionAnchor[]) anchors.toArray(NONE); } public ConnectionAnchor[] requestAnchorsForPointOnNode(Point point, NodeEditPart part) throws MultipleAnchorsForLocationException { Set anchors = new HashSet(); addAnchorsForPoint(part, anchors, point); return (ConnectionAnchor[]) anchors.toArray(NONE); } private void addAnchorsForPoint(NodeEditPart part, Set anchors, Point point) throws MultipleAnchorsForLocationException { checkForAndAddSourceConnectAnchors(part, anchors, point); checkForAndAddTargetConnectAnchors(part, anchors, point); checkForAndAddSourceReconnectionAnchors(part, anchors, point); checkForAndAddTargetReconnectionAnchors(part, anchors, point); } private static void checkForAndAddSourceConnectAnchors(NodeEditPart part, Set anchors, Point point) throws MultipleAnchorsForLocationException { for (int i=0; i < NUM_ATTEMPTS_PER_REQUEST; ++i) { addIfNotNull(anchors, getSourceConnectionAnchor(part, point)); } assertContains(anchors, getSourceConnectionAnchor(part, point), point); } private static void checkForAndAddTargetConnectAnchors(NodeEditPart part, Set anchors, Point point) throws MultipleAnchorsForLocationException { for (int i=0; i < NUM_ATTEMPTS_PER_REQUEST; ++i) { addIfNotNull(anchors, getTargetConnectionAnchor(part, point)); } assertContains(anchors, getTargetConnectionAnchor(part, point), point); } private static void checkForAndAddTargetReconnectionAnchors( NodeEditPart part, Set anchors, Point point) throws MultipleAnchorsForLocationException { for (int i=0; i < NUM_ATTEMPTS_PER_REQUEST; ++i) { addIfNotNull(anchors, getReconnectionTargetAnchor(part, point)); } assertContains(anchors, getReconnectionTargetAnchor(part, point), point); } private static void checkForAndAddSourceReconnectionAnchors( NodeEditPart part, Set anchors, Point point) throws MultipleAnchorsForLocationException { for (int i=0; i < NUM_ATTEMPTS_PER_REQUEST; ++i) { addIfNotNull(anchors, getReconnectionSourceAnchor(part, point)); } assertContains(anchors, getReconnectionSourceAnchor(part, point), point); } private static void assertContains(Set anchors, ConnectionAnchor anchor, Point point) throws MultipleAnchorsForLocationException { if (!anchors.contains(anchor)) throw new MultipleAnchorsForLocationException(anchor.getOwner(), point); } private static ConnectionAnchor getSourceConnectionAnchor(NodeEditPart part, Point point) { try { return part.getSourceConnectionAnchor(createConnectRequestForLocation(point)); } catch (Throwable th) { return null; //since we're peeking behind the covers here, we might ask for a connection where it is not //expected, causing exceptions... to be safe we catch and ignore } } private static ConnectionAnchor getTargetConnectionAnchor(NodeEditPart part, Point point) { try { return part.getTargetConnectionAnchor(createConnectRequestForLocation(point)); } catch (Throwable th) { return null; //since we're peeking behind the covers here, we might ask for a connection where it is not //expected, causing exceptions... to be safe we catch and ignore } } private static ConnectionAnchor getReconnectionTargetAnchor(NodeEditPart part, Point point) { try { return part.getTargetConnectionAnchor(createReconnectRequestForLocation(point)); } catch (Throwable th) { return null; //since we're peeking behind the covers here, we might ask for a connection where it is not //expected, causing exceptions... to be safe we catch and ignore } } private static ConnectionAnchor getReconnectionSourceAnchor(NodeEditPart part, Point point) { try { return part.getSourceConnectionAnchor(createReconnectRequestForLocation(point)); } catch (Throwable th) { return null; //since we're peeking behind the covers here, we might ask for a connection where it is not //expected, causing exceptions... to be safe we catch and ignore } } private static void addIfNotNull(Set anchors, ConnectionAnchor connectAnchor) { if (connectAnchor != null) anchors.add(connectAnchor); } private static CreateConnectionRequest createConnectRequestForLocation(Point location) { CreateConnectionRequest req = new CreateConnectionRequest(); req.setLocation(location); return req; } private static ReconnectRequest createReconnectRequestForLocation(Point location) { ReconnectRequest req = new ReconnectRequest(); req.setLocation(location); return req; } }