/******************************************************************************* | |
* <copyright> | |
* | |
* Copyright (c) 2013, 2013 SAP AG. | |
* 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: | |
* SAP AG - initial API, implementation and documentation | |
* | |
* </copyright> | |
* | |
*******************************************************************************/ | |
package org.eclipse.fmc.blockdiagram.editor.features.add; | |
import org.eclipse.emf.ecore.EAttribute; | |
import org.eclipse.emf.ecore.EObject; | |
import org.eclipse.fmc.blockdiagram.editor.algorithm.connection.FMCConnectionAlgorithm; | |
import org.eclipse.fmc.blockdiagram.editor.algorithm.connection.FMCConnectionAlgorithmFactory; | |
import org.eclipse.fmc.blockdiagram.editor.model.ConnectionStyle; | |
import org.eclipse.fmc.blockdiagram.editor.model.FMCType; | |
import org.eclipse.fmc.blockdiagram.editor.model.FMCTypeChecker; | |
import org.eclipse.fmc.blockdiagram.editor.model.FMCTypeCheckerFactory; | |
import org.eclipse.fmc.blockdiagram.editor.util.StyleUtil; | |
import org.eclipse.fmc.mm.RequestDirection; | |
import org.eclipse.graphiti.features.IFeatureProvider; | |
import org.eclipse.graphiti.features.context.IAddConnectionContext; | |
import org.eclipse.graphiti.features.context.IAddContext; | |
import org.eclipse.graphiti.mm.algorithms.Polygon; | |
import org.eclipse.graphiti.mm.algorithms.Polyline; | |
import org.eclipse.graphiti.mm.algorithms.Text; | |
import org.eclipse.graphiti.mm.pictograms.Connection; | |
import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator; | |
import org.eclipse.graphiti.mm.pictograms.Diagram; | |
import org.eclipse.graphiti.mm.pictograms.PictogramElement; | |
import org.eclipse.graphiti.services.Graphiti; | |
import org.eclipse.graphiti.services.IGaService; | |
import org.eclipse.graphiti.services.IPeService; | |
/** | |
* This class is a specialization of the {@link ConnectionAddFeature} and | |
* responsible for adding access via channels. Both bidirectional and | |
* unidirectional as well as request response are supported. | |
* | |
* @author Benjamin Schmeling | |
* | |
*/ | |
public class CommunicationChannelAddFeature extends ConnectionAddFeature { | |
private FMCTypeChecker checker = FMCTypeCheckerFactory.getInstance(); | |
private FMCConnectionAlgorithmFactory factory = FMCConnectionAlgorithmFactory | |
.getInstance(); | |
/** | |
* The position of the decorator. It is not the center because manhattan | |
* connections tend to reroute at this position. | |
*/ | |
private static final float decoPosX = 0.4f; | |
/** | |
* The default channel text if not specified. | |
*/ | |
protected static final String defaultChannelText = "Channel"; | |
/** | |
* | |
* @param fp | |
* The feature provider. | |
* @param type | |
* The type of the connection. | |
*/ | |
public CommunicationChannelAddFeature(IFeatureProvider fp, | |
ConnectionStyle type) { | |
super(fp, type); | |
} | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.eclipse.graphiti.func.IAdd#canAdd(org.eclipse.graphiti.features.context | |
* .IAddContext) | |
*/ | |
public boolean canAdd(IAddContext context) { | |
return true; | |
} | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.eclipse.graphiti.func.IAdd#add(org.eclipse.graphiti.features.context | |
* .IAddContext) | |
*/ | |
public PictogramElement add(IAddContext context) { | |
IPeService pe = Graphiti.getPeService(); | |
IGaService ga = Graphiti.getGaService(); | |
IAddConnectionContext cContext = (IAddConnectionContext) context; | |
Connection cShape = super.createConnection(); | |
Polyline line = ga.createPolyline(cShape); | |
cShape.setStart(cContext.getSourceAnchor()); | |
cShape.setEnd(cContext.getTargetAnchor()); | |
line.setForeground(manageColor(0, 0, 0)); | |
FMCConnectionAlgorithm connectionAlgorithm = factory.getAlgorithm(cShape); | |
connectionAlgorithm.createChannelSymbol(cShape, getDiagram()); | |
if (checker.isUnidirectionalCommunicationChannel(context.getNewObject())) { | |
createCenterArrow(getDiagram(), cShape, true); | |
createArrowDecorator(getDiagram(), cShape, true); | |
} | |
if (checker.isReqRespCommunicationChannel((context.getNewObject()))) { | |
connectionAlgorithm.setRequestDirection(cShape, | |
RequestDirection.REQUEST, (getDiagram())); | |
} | |
linkModel(cShape, cContext); | |
ConnectionDecorator textDecorator = pe.createConnectionDecorator( | |
cShape, true, decoPosX, true); | |
Text text = ga.createText(textDecorator); | |
text.setForeground(manageColor(0, 0, 0)); | |
ga.setLocation(text, 0, 15); | |
// set reference name in the text decorator | |
text.setValue(getNameFromObject(context.getNewObject())); | |
text.setStyle(StyleUtil.getStyle(getDiagram(), StyleUtil.CONNECTION)); | |
linkTextWithModel(textDecorator, context.getNewObject()); | |
return cShape; | |
} | |
protected void linkTextWithModel(PictogramElement element, Object obj) { | |
if (obj instanceof FMCType) | |
link(element, FMCType.Text); | |
else { | |
link(element, obj); | |
Graphiti.getLinkService().setLinkProperty(element, "name"); | |
} | |
} | |
/** | |
* Returns the value of the name attribute of the object. | |
* | |
* @param obj | |
* The object to get the name from. | |
* | |
* @return The value of the name attribute of the eobject, if not an eobject | |
* return default text. | |
*/ | |
protected String getNameFromObject(Object obj) { | |
if (obj instanceof EObject) { | |
String name = null; | |
EObject eobj = ((EObject) obj); | |
for (EAttribute attr : eobj.eClass().getEAllAttributes()) { | |
if ("name".equals(attr.getName())) { | |
name = (String) eobj.eGet(attr); | |
if (name != null) | |
return name; | |
else { | |
eobj.eSet(attr, defaultChannelText); | |
return defaultChannelText; | |
} | |
} | |
} | |
} | |
return defaultChannelText; | |
} | |
/** | |
* Creates the graphical representation of the arrow located near the | |
* channel oval decorator. | |
* | |
* @param diagram | |
* The diagram to create the arrow for. | |
* @param connection | |
* The connection to be decorated with the arrow. | |
* @param defaultDirection | |
* True if the default direction should be used (from source to | |
* target), false otherwise. | |
*/ | |
public static void createCenterArrow(Diagram diagram, Connection connection, | |
boolean defaultDirection) { | |
ConnectionDecorator arrow1 = Graphiti.getPeService() | |
.createConnectionDecorator(connection, false, decoPosX, true); | |
Polygon p1 = null; | |
if (defaultDirection) | |
p1 = Graphiti.getGaService().createPolygon(arrow1, | |
new int[] { 23, -6, 8, 0, 23, 6, 20, 0 }); | |
else | |
p1 = Graphiti.getGaService().createPolygon(arrow1, | |
new int[] { -21, -6, -6, 0, -21, 6, -18, 0 }); | |
p1.setBackground(Graphiti.getGaService().manageColor(diagram, 0, 0, 0)); | |
} | |
/** | |
* Links the domain model object from the context with the connection. | |
* | |
* @param con | |
* The connection to be linked with. | |
* @param context | |
* The add context containing the domain object. | |
*/ | |
protected void linkModel(Connection con, IAddContext context) { | |
link(con, context.getNewObject()); | |
} | |
} |