blob: 1e04192572d01308835b71081d7005b9d4f9c143 [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.meta.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.fmc.blockdiagram.editor.meta.BlockDiagramMetaFeatureProvider;
import org.eclipse.fmc.blockdiagram.editor.meta.features.add.AccessAddMetaFeature;
import org.eclipse.graphiti.features.IFeature;
import org.eclipse.graphiti.features.context.IContext;
import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
import org.eclipse.graphiti.mm.pictograms.Anchor;
import org.eclipse.graphiti.mm.pictograms.AnchorContainer;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.fmc.blockdiagram.editor.BlockDiagramConstants;
import org.eclipse.fmc.blockdiagram.editor.features.CompositeFeature;
import org.eclipse.fmc.blockdiagram.editor.features.add.CommunicationChannelAddFeature;
import org.eclipse.fmc.blockdiagram.editor.model.ConnectionStyle;
import org.eclipse.fmc.blockdiagram.editor.util.FMCUtil;
import org.eclipse.fmc.mm.Access;
import org.eclipse.fmc.mm.AccessType;
import org.eclipse.fmc.mm.Agent;
import org.eclipse.fmc.mm.Channel;
import org.eclipse.fmc.mm.Storage;
import org.eclipse.fmc.mm.impl.AgentImpl;
import org.eclipse.fmc.mm.impl.StorageImpl;
/**
* The AddConnectionHelper for the Blockdiagram Meta Editor.
*
* @author Patrick Jahnke
*
*/
public class AddConnectionHelper {
/** The CompositeFeature. */
CompositeFeature cf = null;
/**
* Adds all connections from the meta model to the graphical representation.
*
* @param picEl
* the PictogramElement
* @param fmcFP
* the FMCMetaFeatureProvider
* @param diargam
* the diargam
*/
public void addAgentConnections(PictogramElement picEl,
BlockDiagramMetaFeatureProvider fmcFP, Diagram diargam) {
HashMap<EObject, List<PictogramElement>> diagramEObj = new HashMap<EObject, List<PictogramElement>>();
GetAllEObjectOfDiagram(diargam, diagramEObj);
AgentImpl agent = (AgentImpl) FMCUtil.getBO(picEl);
if (agent.getAccessConnections().size() == 0
&& agent.getSourceChannels().size() == 0
&& agent.getTargetChannels().size() == 0)
return;
// Manage CompositeFeature
ArrayList<IFeature> cFList = new ArrayList<IFeature>();
List<Channel> sourceChanels = getSourceChanels(agent, diagramEObj);
for (Channel chl : sourceChanels) {
for (PictogramElement pe : diagramEObj.get(chl.getTarget())) {
AddConnectionContext context = createContext(picEl, pe, chl,
ConnectionStyle.MANHATTAN);
CommunicationChannelAddFeature addFeature = (CommunicationChannelAddFeature) fmcFP
.getAddFeature(context);
addFeature.execute(context);
cFList.add(addFeature);
}
}
List<Channel> targetChanels = getTargetChanels(agent, diagramEObj);
for (Channel chl : targetChanels) {
for (PictogramElement pe : diagramEObj.get(chl.getSource())) {
AddConnectionContext context = createContext(pe, picEl, chl,
ConnectionStyle.MANHATTAN);
CommunicationChannelAddFeature addFeature = (CommunicationChannelAddFeature) fmcFP
.getAddFeature(context);
addFeature.execute(context);
cFList.add(addFeature);
}
}
List<Access> storageConn = getStorageConnections(agent, diagramEObj);
for (Access access : storageConn) {
for (PictogramElement pe : diagramEObj.get(access.getTarget())) {
AddConnectionContext context = null;
if (access.getType() == AccessType.READ)
context = createContext(pe, picEl, access,
ConnectionStyle.MANHATTAN);
else if (access.getType() == AccessType.WRITE)
context = createContext(picEl, pe, access,
ConnectionStyle.MANHATTAN);
else
context = createContext(picEl, pe, access,
ConnectionStyle.COMPOSITE);
AccessAddMetaFeature addFeature = (AccessAddMetaFeature) fmcFP
.getAddFeature(context);
addFeature.execute(context);
cFList.add(addFeature);
}
}
// Manage CompositeFeature
IFeature[] featureList = new IFeature[cFList.size()];
cf = new CompositeFeature(cFList.toArray(featureList));
}
/**
* Adds all connections from the meta model to the graphical representation.
*
* @param picEl
* the PictogramElement
* @param fmcFP
* the FMCMetaFeatureProvider
* @param diargam
* the diargam
*/
public void addStorageConnections(PictogramElement picEl,
BlockDiagramMetaFeatureProvider fmcFP, Diagram diargam) {
HashMap<EObject, List<PictogramElement>> diagramEObj = new HashMap<EObject, List<PictogramElement>>();
GetAllEObjectOfDiagram(diargam, diagramEObj);
StorageImpl storage = (StorageImpl) FMCUtil.getBO(picEl);
if (storage.getConnections().size() == 0)
return;
// Manage CompositeFeature
ArrayList<IFeature> cFList = new ArrayList<IFeature>();
List<Access> storageConn = getStorageConnections(storage, diagramEObj);
for (Access access : storageConn) {
for (PictogramElement pe : diagramEObj.get(access.getAgent())) {
AddConnectionContext context = null;
if (access.getType() == AccessType.READ)
context = createContext(picEl, pe, access,
ConnectionStyle.MANHATTAN);
else if (access.getType() == AccessType.WRITE)
context = createContext(pe, picEl, access,
ConnectionStyle.MANHATTAN);
else
context = createContext(pe, picEl, access,
ConnectionStyle.COMPOSITE);
AccessAddMetaFeature addFeature = (AccessAddMetaFeature) fmcFP
.getAddFeature(context);
addFeature.execute(context);
cFList.add(addFeature);
}
}
// Manage CompositeFeature
IFeature[] featureList = new IFeature[cFList.size()];
cf = new CompositeFeature(cFList.toArray(featureList));
}
/**
* Get all EObject of a diagram.
*
* @param cShape
* ContainerShape (diagram)
* @param map
* the map with the EObject as key and a list of
* PictogramElements.
*/
private void GetAllEObjectOfDiagram(ContainerShape cShape,
Map<EObject, List<PictogramElement>> map) {
for (Shape shape : cShape.getChildren()) {
if (shape instanceof ContainerShape)
GetAllEObjectOfDiagram((ContainerShape) shape, map);
if (!shape.isActive())
continue;
EObject obj = FMCUtil.getBO(shape);
if (map.containsKey(obj))
map.get(obj).add(shape);
else {
ArrayList<PictogramElement> lst = new ArrayList<PictogramElement>();
lst.add(shape);
map.put(obj, lst);
}
}
}
/**
* Gets the storage connections.
*
* @param storage
* the storage
* @param diagramEObj
* the diagram e obj
* @return the storage connections
*/
private List<Access> getStorageConnections(Storage storage,
Map<EObject, List<PictogramElement>> diagramEObj) {
ArrayList<Access> returnList = new ArrayList<Access>();
for (Access access : storage.getConnections()) {
if (diagramEObj.containsKey(access.getAgent()))
returnList.add(access);
}
return returnList;
}
/**
* Gets the storage connections.
*
* @param agent
* the agent
* @param diagramEObj
* the diagram e obj
* @return the storage connections
*/
private List<Access> getStorageConnections(Agent agent,
Map<EObject, List<PictogramElement>> diagramEObj) {
ArrayList<Access> returnList = new ArrayList<Access>();
for (Access access : agent.getAccessConnections()) {
if (diagramEObj.containsKey(access.getTarget()))
returnList.add(access);
}
return returnList;
}
/**
* Gets the source chanels.
*
* @param agent
* the agent
* @param diagramEObj
* the diagram e obj
* @return the source chanels
*/
private List<Channel> getSourceChanels(Agent agent,
Map<EObject, List<PictogramElement>> diagramEObj) {
ArrayList<Channel> returnList = new ArrayList<Channel>();
for (Channel chl : agent.getSourceChannels()) {
if (diagramEObj.containsKey(chl.getTarget()))
returnList.add(chl);
}
return returnList;
}
/**
* Gets the target chanels.
*
* @param agent
* the agent
* @param diagramEObj
* the diagram e obj
* @return the target chanels
*/
private List<Channel> getTargetChanels(Agent agent,
Map<EObject, List<PictogramElement>> diagramEObj) {
ArrayList<Channel> returnList = new ArrayList<Channel>();
for (Channel chl : agent.getTargetChannels()) {
if (diagramEObj.containsKey(chl.getSource()))
returnList.add(chl);
}
return returnList;
}
/**
* Gets the anchor.
*
* @param pe
* the pe
* @return the anchor
*/
private Anchor getAnchor(PictogramElement pe) {
Anchor ret = null;
if (pe instanceof Anchor) {
ret = (Anchor) pe;
} else if (pe instanceof AnchorContainer) {
ret = Graphiti.getPeService()
.getChopboxAnchor((AnchorContainer) pe);
}
return ret;
}
/**
* Creates the context.
*
* @param sourceObject
* the source object
* @param targetObject
* the target object
* @param obj
* the obj
* @param connStyle
* the conn style
* @return the adds the connection context
*/
private AddConnectionContext createContext(PictogramElement sourceObject,
PictogramElement targetObject, Object obj, ConnectionStyle connStyle) {
AddConnectionContext connectionContext = new AddConnectionContext(
getAnchor(sourceObject), getAnchor(targetObject));
connectionContext.setNewObject(obj);
connectionContext.putProperty(
BlockDiagramConstants.GRAPHICAL_TYPE_KEY, connStyle);
return connectionContext;
}
/**
* Checks if is available.
*
* @param context
* the context
* @return true, if is available
*/
public boolean isAvailable(IContext context) {
if (cf != null)
return cf.isAvailable(context);
return true;
}
/**
* Can execute.
*
* @param context
* the context
* @return true, if successful
*/
public boolean canExecute(IContext context) {
if (cf != null)
return cf.canExecute(context);
return true;
}
/**
* Execute.
*
* @param context
* the context
*/
public void execute(IContext context) {
if (cf != null)
cf.execute(context);
}
/**
* Can undo.
*
* @param context
* the context
* @return true, if successful
*/
public boolean canUndo(IContext context) {
if (cf != null)
return cf.canUndo(context);
return true;
}
/**
* Checks for done changes.
*
* @return true, if successful
*/
public boolean hasDoneChanges() {
if (cf != null)
return cf.hasDoneChanges();
return true;
}
}