blob: b6183ab51b6bcff02529f55c6c59b93f4f060539 [file] [log] [blame]
/*******************************************************************************
* <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());
}
}