blob: f50b7b3c27ba69e70b6e897f818ba997633f0754 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.diagram.model.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.epf.library.edit.ICommandListener;
import org.eclipse.epf.library.edit.process.command.VaryActivityCommand;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.Diagram;
import org.eclipse.epf.uma.GraphConnector;
import org.eclipse.epf.uma.GraphEdge;
import org.eclipse.epf.uma.GraphNode;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.SemanticModelBridge;
import org.eclipse.epf.uma.UMASemanticModelBridge;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.util.UmaUtil;
/**
* Diagram data stored in UMA: SemanticModelBridge .Presentation diagram type,
* its value can be one of following constants defined in GraphicalDataHelper
* DIAGRAM_WORKFLOW, DIAGRAM_WORK_PRODUCT_DEPENDENCY, DIAGRAM_ACTIVITY_DETAIL
*
* UMASemanticModelBridge .Element BreakdownElement that the DiagramElement of
* this SemanticModelBridge represents
*
* SimpleSemanticModelElement .TypeInfo type information for TypedNode, its
* value can be one of the constants defined in GraphicalDataHelper
* wpCompositeType WorkProductComposite type
*
* DiagramElement .Property (list of properties)
*
*
* @author Phong Nguyen Le
* @since 1.0
*/
public final class GraphicalDataManager {
private static final String[] diagramPresentations = new String[] {
GraphicalDataHelper.DIAGRAM_WORKFLOW,
GraphicalDataHelper.DIAGRAM_WORK_PRODUCT_DEPENDENCY,
GraphicalDataHelper.DIAGRAM_ACTIVITY_DETAIL };
private static final Class[] childTypes = new Class[] { Activity.class,
WorkProductDescriptor.class, Descriptor.class };
private static final Class[] diagramChangeListenerClasses = new Class[] {
IActivityDiagramChangeListener.class,
IWPDDiagramChangeListener.class,
IActivityDetailDiagramChangeListener.class };
private static GraphicalDataManager instance = null;
//private Map graphicalDataMap = new HashMap();
private List commandListeners;
private GraphicalDataManager() {
}
public static GraphicalDataManager getInstance() {
if (instance == null) {
synchronized (GraphicalDataManager.class) {
if (instance == null) {
instance = new GraphicalDataManager();
}
}
}
return instance;
}
// public GraphNode getGraphNode(Activity act, int diagramType, Activity
// parent) {
// // ItemProviderAdapter adapter = (ItemProviderAdapter)
// TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory().adapt(act,
// ITreeItemContentProvider.class);
// // Object parent = adapter.getParent(act);
// // if(parent instanceof Activity) {
// if(parent == null) {
// // new Activity
// //
// return createGraphNode(act);
// }
// if(!act.getSuperActivities().contains(parent)) {
// throw new IllegalArgumentException("Invalid super activity for " + act +
// ": " + parent);
// }
// Activity parentAct = (Activity) parent;
// Diagram diagram = getDiagram(parentAct, diagramType).getUMADiagram();
// return getGraphNode(diagram, act);
// }
/**
* Gets the GraphNode of the given method element for the given diagram.
* Create the GraphNode if it does not exist yet.
*
* @param diagram
* @param methodElement
* @return
*/
public GraphNode getGraphNode(Diagram diagram, MethodElement methodElement) {
if (diagram == null) {
// new MethodElement
//
return createGraphNode(methodElement);
}
GraphNode node = findGraphNode(diagram, methodElement);
if (node == null) {
node = createGraphNode(methodElement);
createGraphConnectors(node, diagram);
diagram.getContained().add(node);
}
return node;
}
public static GraphNode findGraphNode(Diagram diagram, Object methodElement) {
for (Iterator iter = diagram.getContained().iterator(); iter.hasNext();) {
GraphNode element = (GraphNode) iter.next();
if (element.getSemanticModel() instanceof UMASemanticModelBridge
&& methodElement == ((UMASemanticModelBridge) element
.getSemanticModel()).getElement()) {
return element;
}
}
return null;
}
// public DiagramElement getDiagramElement(Object object) {
// if(object instanceof Activity) {
// return getGraphNode((Activity) object);
// }
// else if(object instanceof WorkOrder) {
// WorkOrder workOrder = (WorkOrder) object;
// BreakdownElement be = workOrder.getPred();
// if(be instanceof Activity) {
// GraphNode graphNode = getGraphNode((Activity) be);
// List list = graphNode.getContained();
// Polyline polyline = null;
// for(int i = 0; i < list.size(); i++) {
// Object obj = list.get(i);
// if(obj instanceof Polyline) {
// polyline = (Polyline) obj;
// break;
// }
// }
// if(polyline == null) {
// polyline = UmaFactory.eINSTANCE.createPolyline();
// list.add(0, polyline);
// }
// return polyline;
// }
// }
// return null;
// }
/**
* @param object
* @return
*/
private Diagram createDiagram(Activity act, int diagramType) {
// check if this activity contributes/extends other activity and try
// copy
// the existing diagram from the base
//
if (ProcessUtil.isExtendingOrLocallyContributing(act)) {
Diagram baseDiagram = getUMADiagram((Activity) act
.getVariabilityBasedOnElement(), diagramType, false);
if (baseDiagram != null) {
Diagram copy = GraphicalDataHelper.copyDiagram(baseDiagram);
UMASemanticModelBridge modelBridge = (UMASemanticModelBridge) copy
.getSemanticModel();
modelBridge.setElement(act);
return copy;
}
}
Diagram diagram = UmaFactory.eINSTANCE.createDiagram();
UMASemanticModelBridge modelBridge = UmaFactory.eINSTANCE
.createUMASemanticModelBridge();
modelBridge.setElement(act);
modelBridge.setPresentation(diagramPresentations[diagramType]);
diagram.setSemanticModel(modelBridge);
// getDiagram(act, diagramType).setUMADiagram(diagram);
populateDiagram(diagram, act, diagramType);
return diagram;
}
private void populateDiagram(Diagram diagram, Activity act, int diagramType) {
// create GraphNode for each BreakdownElement and add it to the diagram
//
List nodes = new ArrayList();
for (Iterator iter = act.getBreakdownElements().iterator(); iter
.hasNext();) {
Object element = iter.next();
if (childTypes[diagramType].isInstance(element)) {
GraphNode node = createGraphNode((MethodElement) element);
diagram.getContained().add(node);
nodes.add(node);
}
}
// create GraphConnectors for each BreakdownElement
//
for (Iterator iter = nodes.iterator(); iter.hasNext();) {
GraphNode node = (GraphNode) iter.next();
createGraphConnectors(node, diagram, diagramType);
}
}
// private void populateActivityDiagram(Diagram diagram, Activity act) {
// // create GraphNode for each child activity and add it to the diagram
// //
// List nodes = new ArrayList();
// for (Iterator iter = act.getBreakdownElements().iterator(); iter
// .hasNext();) {
// Object element = (Object) iter.next();
// if (element instanceof Activity) {
// Activity childAct = (Activity) element;
// GraphNode node = createGraphNode(childAct);
// diagram.getContained().add(node);
// nodes.add(node);
// }
// }
//
// // create GraphConnectors for each child activity
// //
// for (Iterator iter = nodes.iterator(); iter.hasNext();) {
// GraphNode node = (GraphNode) iter.next();
// createGraphConnectors(node, diagram);
// }
// }
/**
* @param act
* @param diagramType
* @return
*/
public IDiagramChangeListener getDiagramChangeListener(Activity act,
int diagramType) {
for (Iterator iter = act.eAdapters().iterator(); iter.hasNext();) {
Object element = (Object) iter.next();
if (diagramChangeListenerClasses[diagramType].isInstance(element)) {
return (IDiagramChangeListener) element;
}
}
return null;
}
public GraphNode createGraphNode(MethodElement element) {
GraphNode graphNode = UmaFactory.eINSTANCE.createGraphNode();
UMASemanticModelBridge modelBridge = UmaFactory.eINSTANCE
.createUMASemanticModelBridge();
modelBridge.setElement(element);
graphNode.setSemanticModel(modelBridge);
org.eclipse.epf.uma.Point point = UmaFactory.eINSTANCE.createPoint();
point.setX(new Double(-1));
point.setY(new Double(-1));
graphNode.setPosition(point);
org.eclipse.epf.uma.Dimension dim = UmaFactory.eINSTANCE.createDimension();
dim.setWidth(new Double(-1));
dim.setHeight(new Double(-1));
graphNode.setSize(dim);
return graphNode;
}
public GraphEdge addGraphConnectorPair(Diagram diagram,
GraphNode graphNode, WorkOrder element) {
GraphConnector srcConnector = UmaFactory.eINSTANCE
.createGraphConnector();
graphNode.getAnchorage().add(srcConnector);
GraphEdge edge = UmaFactory.eINSTANCE.createGraphEdge();
UMASemanticModelBridge bridge = UmaFactory.eINSTANCE
.createUMASemanticModelBridge();
bridge.setElement(element);
edge.setSemanticModel(bridge);
graphNode.getContained().add(edge);
edge.getAnchor().add(srcConnector);
GraphNode succNode = getGraphNode(diagram, UmaUtil
.getOwningActivity(element));
GraphConnector targetConnector = UmaFactory.eINSTANCE
.createGraphConnector();
succNode.getAnchorage().add(targetConnector);
edge.getAnchor().add(targetConnector);
return edge;
}
public GraphEdge addGraphConnectorPair(GraphNode srcNode,
GraphNode targetNode) {
GraphConnector srcConnector = UmaFactory.eINSTANCE
.createGraphConnector();
srcNode.getAnchorage().add(srcConnector);
GraphEdge edge = UmaFactory.eINSTANCE.createGraphEdge();
srcNode.getContained().add(edge);
edge.getAnchor().add(srcConnector);
GraphConnector targetConnector = UmaFactory.eINSTANCE
.createGraphConnector();
targetNode.getAnchorage().add(targetConnector);
edge.getAnchor().add(targetConnector);
return edge;
}
public void removeGraphEdge(GraphEdge edge) {
EcoreUtil.remove(edge);
for (Iterator iter = edge.getAnchor().iterator(); iter.hasNext();) {
GraphConnector conn = (GraphConnector) iter.next();
EcoreUtil.remove(conn);
}
}
// public void removeGraphConnectorPair(GraphNode srcNode, GraphNode
// targetNode) {
// // find the source GraphConnector and remove it, its GraphEdge, and its
// target GraphConnector
// //
// for (Iterator iter = srcNode.getAnchorage().iterator(); iter.hasNext();)
// {
// GraphConnector connector = (GraphConnector) iter.next();
// for (Iterator iterator = connector.getGraphEdge().iterator(); iterator
// .hasNext();) {
// GraphEdge edge = (GraphEdge) iterator.next();
// Object targetConnector = edge.getAnchor().get(1);
// if(targetNode.getAnchorage().remove(targetConnector)) {
// srcNode.getContained().remove(edge);
// // don't remove the edge from connector to support undo
// //
// // iterator.remove();
// }
// }
// if(connector.getGraphEdge().isEmpty()) {
// iter.remove();
// }
// }
// }
public void removeGraphConnectionPair(GraphNode graphNode,
WorkOrder workOrder) {
for (Iterator iter = graphNode.getAnchorage().iterator(); iter
.hasNext();) {
GraphConnector conn = (GraphConnector) iter.next();
GraphEdge edge = (GraphEdge) conn.getGraphEdge().get(0);
if (edge.eContainer() == graphNode) {
GraphConnector conn2 = (GraphConnector) edge.getAnchor().get(1);
SemanticModelBridge bridge = conn2.getGraphElement()
.getSemanticModel();
if (bridge instanceof UMASemanticModelBridge
&& ((UMASemanticModelBridge) bridge).getElement() == UmaUtil
.getOwningActivity(workOrder)) {
conn2.getGraphElement().getAnchorage().remove(conn2);
iter.remove();
graphNode.getContained().remove(edge);
return;
}
}
}
}
private void createGraphConnectors(GraphNode graphNode, Diagram diagram) {
createGraphConnectors(graphNode, diagram, getDiagramType(diagram));
}
int getDiagramType(Diagram diagram) {
String typeStr = diagram.getSemanticModel().getPresentation();
for (int i = 0; i < diagramPresentations.length; i++) {
if (diagramPresentations[i].equals(typeStr))
return i;
}
return -1;
}
private void createGraphConnectors(GraphNode graphNode, Diagram diagram,
int diagramType) {
MethodElement e = ((UMASemanticModelBridge) graphNode
.getSemanticModel()).getElement();
switch (diagramType) {
case GraphicalDataHelper.ACTIVITY_DIAGRAM:
if (e instanceof Activity) {
Activity act = (Activity) e;
// create connectors
//
// List list = act.getLinkToPredecessor();
// int size = list.size();
//
// Activity parent = (Activity)
// ((UMASemanticModelBridge)diagram.getSemanticModel()).getElement();
// List breakdownElements = parent.getBreakdownElements();
// for(int i = 0; i < size; i++) {
// WorkOrder workOrder = (WorkOrder) list.get(i);
// if(breakdownElements.contains(workOrder.getPred())) {
// addGraphConnectorPair(diagram, graphNode, workOrder);
// }
// }
for (Iterator iter = act.getLinkToPredecessor().iterator(); iter
.hasNext();) {
WorkOrder workOrder = (WorkOrder) iter.next();
GraphNode srcNode = findGraphNode(diagram, workOrder
.getPred());
if (srcNode != null) {
addGraphConnectorPair(srcNode, graphNode);
}
}
}
break;
case GraphicalDataHelper.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
if (e instanceof WorkProductDescriptor) {
WorkProductDescriptor descriptor = (WorkProductDescriptor) e;
for (Iterator iter = descriptor.getImpacts().iterator(); iter
.hasNext();) {
WorkProductDescriptor impactedDescriptor = (WorkProductDescriptor) iter
.next();
GraphNode targetNode = GraphicalDataManager.findGraphNode(
diagram, impactedDescriptor);
if (targetNode != null) {
addGraphConnectorPair(graphNode, targetNode);
}
}
}
break;
}
}
/**
* Gets the UMA diagram from the UMA model for the given activity.
*
* @param e
* @param diagramType
* one of the diagram type constants defined in
* {@link GraphicalDataHelper GraphicalDataHelper }
* @param create
* if true, new UMA diagram will be created if the activity does
* not have one already.
* @return
* @see GraphicalDataHelper#ACTIVITY_DIAGRAM
* @see GraphicalDataHelper#ACTIVITY_DETAIL_DIAGRAM
* @see GraphicalDataHelper#WORK_PRODUCT_DEPENDENCY_DIAGRAM
*/
public Diagram getUMADiagram(Activity e, int diagramType, boolean create) {
Diagram diagram = null;
// // look for IDiagramChangeListener in activity's adapter list first
// IDiagramChangeListener listener = (IDiagramChangeListener)
// UmaUtil.getAdapter(e, diagramListenerType);
// if(listener != null) {
// diagram = listener.getDiagram().getUMADiagram();
// if(diagram != null) return diagram;
// }
Object container = e.eContainer();
if (container != null) {
ProcessPackage pkg = (ProcessPackage) container;
for (Iterator iter = pkg.getDiagrams().iterator(); iter.hasNext();) {
diagram = (Diagram) iter.next();
SemanticModelBridge modelBridge = diagram.getSemanticModel();
if (modelBridge != null
&& modelBridge instanceof UMASemanticModelBridge
&& e == ((UMASemanticModelBridge) modelBridge)
.getElement()
&& diagramPresentations[diagramType]
.equals(((UMASemanticModelBridge) modelBridge)
.getPresentation())) {
return diagram;
}
}
}
if (create) {
// could not find it, create new one
//
diagram = createDiagram(e, diagramType);
if (container != null) {
((ProcessPackage) container).getDiagrams().add(diagram);
}
return diagram;
}
return null;
}
// public Diagram getUMADiagram(Activity act, int diagramType) {
// Diagram diagram = null;
//
// // look for IDiagramChangeListener in activity's adapter list first
// IDiagramChangeListener listener = getDiagramChangeListener(act,
// diagramType);
// if(listener != null) {
// diagram = listener.getDiagram().getUMADiagram();
// if(diagram != null) return diagram;
// }
// Object container = act.eContainer();
// if(container != null) {
// ProcessPackage pkg = (ProcessPackage) container;
// for (Iterator iter = pkg.getDiagrams().iterator(); iter.hasNext();) {
// diagram = (Diagram) iter.next();
// SemanticModelBridge modelBridge = diagram.getSemanticModel();
// if(modelBridge != null && modelBridge instanceof UMASemanticModelBridge
// && act == ((UMASemanticModelBridge)modelBridge).getElement()
// &&
// diagramPresentations[diagramType].equals(((UMASemanticModelBridge)modelBridge).getPresentation()))
// {
// return diagram;
// }
// }
// }
//
// // could not find it, create new one
// //
// return createDiagram(act, diagramType);
// }
/**
* @param act
* @return
*/
public org.eclipse.epf.diagram.model.Diagram getDiagram(Activity act,
int diagramType) {
IDiagramChangeListener listener = getDiagramChangeListener(act,
diagramType);
return listener == null ? null : listener.getDiagram();
}
/**
* Gets list of command listeners that will handle the diagram related changes of the commands of interesses
*
* @return
* @see ICommandListener
*/
public List getCommandListeners() {
if (commandListeners == null) {
commandListeners = new ArrayList();
}
commandListeners.add(new ICommandListener() {
public void notifyExecuted(Command command) {
// get contributor/replacer of the activity
//
Activity act = (Activity) command.getResult().iterator().next();
Activity base = (Activity) act.getVariabilityBasedOnElement();
if (base != null) {
Activity parentAct = act.getSuperActivities();
Diagram diagram = getUMADiagram(parentAct,
GraphicalDataHelper.ACTIVITY_DIAGRAM, false);
if (diagram != null) {
// find existing node for base and link it to the
// contributore/replacer of the activity
//
GraphNode graphNode = findGraphNode(diagram, base);
if (graphNode != null) {
UMASemanticModelBridge bridge = (UMASemanticModelBridge) graphNode
.getSemanticModel();
if (bridge.getElement() != act) {
bridge.setElement(act);
}
}
}
if(act.getVariabilityType() == VariabilityType.LOCAL_CONTRIBUTION_LITERAL) {
// copy diagrams and their publishing options
//
for (int i = 0; i < GraphicalDataHelper.DIAGRAM_TYPES.length; i++) {
int diagramType = GraphicalDataHelper.DIAGRAM_TYPES[i];
diagram = getUMADiagram(base, diagramType, false);
if (diagram != null) {
Diagram copy = getUMADiagram(act, diagramType, true);
copy.setSuppressed(diagram.getSuppressed());
}
}
}
}
}
public Class getCommandType() {
return VaryActivityCommand.class;
}
public void preUndo(Command command) {
// get old contributor/replacer of the activity
//
Activity act = (Activity) command.getResult().iterator().next();
// VaryActivityCommand cmd = (VaryActivityCommand) command;
// BreakdownElementWrapperItemProvider adapter = cmd.getWrapper();
VariabilityElement baseAct = act.getVariabilityBasedOnElement();
if (baseAct != null) {
Activity parentAct = act.getSuperActivities();
Diagram diagram = getUMADiagram(parentAct,
GraphicalDataHelper.ACTIVITY_DIAGRAM, false);
if (diagram != null) {
// find existing node for the old contributore/replacer
// old and relink it to the base activity
//
GraphNode graphNode = findGraphNode(diagram, act);
if (graphNode != null) {
UMASemanticModelBridge bridge = (UMASemanticModelBridge) graphNode
.getSemanticModel();
if (bridge.getElement() != baseAct) {
bridge.setElement(baseAct);
}
}
}
}
}
public void preExecute(Command command) {
}
});
return commandListeners;
}
}