| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2007 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<ICommandListener> 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<ICommandListener> getCommandListeners() { |
| if (commandListeners == null) { |
| commandListeners = new ArrayList<ICommandListener>(); |
| } |
| |
| 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) { |
| // 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) { |
| |
| } |
| |
| public void postUndo(Command command) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| }); |
| |
| return commandListeners; |
| } |
| } |