/******************************************************************************* * Copyright (c) 2005, 2012 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.bpel.ui.editparts; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.bpel.common.ui.markers.IModelMarkerConstants; import org.eclipse.bpel.model.Activity; import org.eclipse.bpel.model.Link; import org.eclipse.bpel.model.Source; import org.eclipse.bpel.model.Sources; import org.eclipse.bpel.model.Target; import org.eclipse.bpel.model.Targets; import org.eclipse.bpel.ui.BPELUIPlugin; import org.eclipse.bpel.ui.GraphicalBPELRootEditPart; import org.eclipse.bpel.ui.IBPELUIConstants; import org.eclipse.bpel.ui.IHoverHelper; import org.eclipse.bpel.ui.adapters.IMarkerHolder; import org.eclipse.bpel.ui.editparts.borders.DrawerBorder; import org.eclipse.bpel.ui.editparts.policies.BPELGraphicalEditPolicy; import org.eclipse.bpel.ui.extensions.BPELUIRegistry; import org.eclipse.bpel.ui.figures.CenteredConnectionAnchor; import org.eclipse.bpel.ui.util.BPELUtil; import org.eclipse.bpel.ui.util.ModelHelper; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.Label; import org.eclipse.draw2d.MouseEvent; import org.eclipse.draw2d.MouseMotionListener; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.NodeEditPart; import org.eclipse.gef.Request; /** * ActivityEditPart is the graphical GEF edit part representing a BPEL Activity. * It implements NodeEditPart because activities can be the source and the target of * connections in the graph. These connections include flow links as well as implicit * control flow connections, often determined by the node's parent. */ public abstract class ActivityEditPart extends BPELEditPart implements NodeEditPart { private MouseMotionListener mouseMotionListener; /** * Brand new shiny ActivityEditPart. */ public ActivityEditPart() { super(); } @Override protected void addAllAdapters() { super.addAllAdapters(); Sources sources = getActivity().getSources(); if (sources != null) { adapter.addToObject(sources); for(Source source : sources.getChildren()) { adapter.addToObject(source); } // // for (Iterator it = sources.getChildren().iterator(); it.hasNext(); ) { // Source source = (Source)it.next(); // // also include the link, if there is one (since we indirectly // // control the activation of the LinkEditPart) // if (source.getLink() != null) adapter.addToObject(source.getLink()); // // // Okay--the real problem here, is that the Activity might be // // referred to by a Source object, but the Activity is not going // // to find out about the creation of a new Sources that references // // it. Therefore, our model listeners don't know what to do! // // // TODO: temporarily hacked around in FlowEditPart.FlowContentAdapter. // // // TODO: also include any parent flows, and the Links object of // // any parent flows that have one. ! // // TODO: in future, use a global listener to handle refreshing the // // correct source editpart. // } } Targets targets = getActivity().getTargets(); if (targets != null) { adapter.addToObject(targets); for( Target target : targets.getChildren()) { adapter.addToObject(target); } } } /** * Install the BPELGraphicalEditPolicy as GRAPHICAL_NODE_ROLE. This policy allows * the graphical creation of flow links between activities. */ @Override protected void createEditPolicies() { super.createEditPolicies(); installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new BPELGraphicalEditPolicy()); } /** * The model is the source of the following connections: * - Any flow links that the model is the source of * - Any other connections that the model's parent determines the model is the source of */ @Override protected List<Link> getModelSourceConnections() { Sources sources = getActivity().getSources(); if (sources == null) { return Collections.emptyList(); } List<Link> result = new ArrayList<Link>(); for(Source source : sources.getChildren()) { if (source.getLink() != null) { result.add(source.getLink()); } } return result; } /** * The model is the target of the following connections: * - Any flow links that the model is the target of * - Any other connections that the model's parent determines the model is the target of */ @Override protected List<Link> getModelTargetConnections() { Targets targets = getActivity().getTargets(); if (targets == null) { return Collections.emptyList(); } List<Link> result = new ArrayList<Link>(); for(Target target : targets.getChildren()) { if (target.getLink() != null) { result.add(target.getLink()); } } return result; } /** * Returns the connection anchor of a source connection which * is at the given point. * * @return ConnectionAnchor. */ public ConnectionAnchor getSourceConnectionAnchor(Request request) { // TODO: Translate point to figure, call other method return getSourceConnectionAnchor((ConnectionEditPart)null); } /** * Returns the connection anchor of a target connection which * is at the given point. * * @return ConnectionAnchor. */ public ConnectionAnchor getTargetConnectionAnchor(Request request) { // TODO: Translate point to figure, call other method return getTargetConnectionAnchor((ConnectionEditPart)null); } /** * Because ActivityEditPart implements NodeEditPart, there may be connections * to or from this node that are affected by model changes. Refresh the * connections now. * * If the model change involves the addition of an ActivityExtension, add an adapter * to that extension. */ @Override protected void handleModelChanged() { super.handleModelChanged(); refreshSourceConnections(); refreshTargetConnections(); } /** * Convenience method to get the model as a BPEL Activity * @return the model as a BPEL activity */ public Activity getActivity() { return (Activity) getModel(); } /** * Override so we can set the constraint for every XY placed object */ @Override public void refreshVisuals() { Rectangle r = null; if (this.getParent() instanceof FlowEditPart) { EditPart root = getRoot(); if (root instanceof GraphicalBPELRootEditPart) { Point p = ModelHelper.getLocation(getActivity()); if (p.x == Integer.MIN_VALUE) { // HACK: We don't know its position, pretend it's at 0, 0. This should only // be necessary during brief edge-case situations (like during startup before // we've done auto-layout on flows without metadata).. p = new Point(0, 0); } Dimension s = new Dimension(-1, -1); r = new Rectangle(p, s); } } if (r != null) { ((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), r); } super.refreshVisuals(); } public ConnectionAnchor getTargetConnectionAnchorForTargetChild(ConnectionEditPart connEditPart) { return null; } protected void refreshDrawerHoverHelp() { IHoverHelper helper = null; try { helper = BPELUIRegistry.getInstance().getHoverHelper(); if (helper == null) { return ; } } catch (CoreException ce) { getFigure().setToolTip(null); BPELUIPlugin.log(ce); return ; } // Get the marker and pass it to the hover helper ArrayList<IMarker> listOfMarkers = new ArrayList<IMarker>(); IMarkerHolder holder = BPELUtil.adapt(getActivity(), IMarkerHolder.class); for (IMarker m : holder.getMarkers(getActivity()) ) { // if we can't see it, then we will not look at it if (m.getAttribute(IModelMarkerConstants.DECORATION_MARKER_VISIBLE_ATTR, true) == false) { continue; } String where = m.getAttribute(IModelMarkerConstants.DECORATION_GRAPHICAL_MARKER_ANCHOR_POINT_ATTR,EMPTY_STRING); if (mouseLocation == 1) { // Top drawer if (where.equals( IBPELUIConstants.MARKER_ANCHORPOINT_DRAWER_TOP )) { listOfMarkers.add(m); } } else { // bottom drawer if (where.equals( IBPELUIConstants.MARKER_ANCHORPOINT_DRAWER_BOTTOM )) { listOfMarkers.add(m); } } } if (listOfMarkers.size() == 0) { return; } String text = null; if (listOfMarkers.size() == 1) { text = helper.getHoverHelp( listOfMarkers.get(0) ); } else { StringBuilder sb = new StringBuilder(); sb.append("There are ").append(listOfMarkers.size()).append(" issues here:\n"); for(IMarker m : listOfMarkers) { String t = helper.getHoverHelp (m) ; sb.append("o ").append(t).append("\n"); } text = sb.toString(); } if (text == null || text.length() < 1) { getFigure().setToolTip(null); } else { getFigure().setToolTip(new Label(text)); } } protected MouseMotionListener getMouseMotionListener() { if (mouseMotionListener == null) { this.mouseMotionListener = new MouseMotionListener() { public void mouseDragged(MouseEvent me) { } public void mouseEntered(MouseEvent me) { } public void mouseExited(MouseEvent me) { } public void mouseHover(MouseEvent me) { } public void mouseMoved(MouseEvent me) { DrawerBorder border = getDrawerBorder(); if (border == null) return; int inTop = border.isPointInTopDrawer(me.x, me.y) ? 1 : 0; int inBottom = border.isPointInBottomDrawer(me.x, me.y) ? 2 : 0; // If mouse stayed in the same place it was in last time, do nothing int newLocation = inTop | inBottom; if (newLocation == mouseLocation) return; mouseLocation = newLocation; refreshHoverHelp(); } }; } return mouseMotionListener; } protected abstract DrawerBorder getDrawerBorder(); /** * Override the refreshHoverHelp method from BPELEditPart. This method * will refresh either the regular hover help, or the drawer hover help * if that is what is currently being displayed. */ @Override public void refreshHoverHelp() { switch (mouseLocation) { case 1: refreshDrawerHoverHelp(); return; case 2: refreshDrawerHoverHelp(); return; } super.refreshHoverHelp(); } public IFigure getMainActivityFigure() { return getFigure(); } public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connEditPart) { // Provide default anchor for Links. if (connEditPart == null || connEditPart instanceof LinkEditPart) { if(ModelHelper.isHorizontalLayout(getModel())){ return new CenteredConnectionAnchor(getMainActivityFigure(), CenteredConnectionAnchor.RIGHT_INNER, 0); }else return new CenteredConnectionAnchor(getMainActivityFigure(), CenteredConnectionAnchor.BOTTOM, 0); } return null; } public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connEditPart) { // Provide default anchor for Links. if (connEditPart == null || connEditPart instanceof LinkEditPart) { if(ModelHelper.isHorizontalLayout(getModel())){ return new CenteredConnectionAnchor(getMainActivityFigure(), CenteredConnectionAnchor.LEFT_INNER, 0); }else return new CenteredConnectionAnchor(getMainActivityFigure(), CenteredConnectionAnchor.TOP, 0); } return null; } }