| /******************************************************************************* |
| * Copyright 2005, CHISEL Group, University of Victoria, Victoria, BC, Canada. |
| * 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: The Chisel Group, University of Victoria |
| ******************************************************************************/ |
| package org.eclipse.zest.core.viewers.internal; |
| |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.zest.core.viewers.EntityConnectionData; |
| import org.eclipse.zest.core.viewers.IFigureProvider; |
| import org.eclipse.zest.core.viewers.IGraphEntityContentProvider; |
| import org.eclipse.zest.core.widgets.Graph; |
| import org.eclipse.zest.core.widgets.GraphConnection; |
| import org.eclipse.zest.core.widgets.GraphItem; |
| import org.eclipse.zest.core.widgets.GraphNode; |
| |
| /** |
| * |
| * @author Ian Bull |
| */ |
| public class GraphModelEntityFactory extends AbstractStylingModelFactory { |
| |
| AbstractStructuredGraphViewer viewer = null; |
| |
| public GraphModelEntityFactory(AbstractStructuredGraphViewer viewer) { |
| super(viewer); |
| this.viewer = viewer; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.zest.core.internal.graphmodel.IStylingGraphModelFactory# |
| * createGraphModel() |
| */ |
| public Graph createGraphModel(Graph model) { |
| doBuildGraph(model); |
| return model; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.zest.core.internal.graphmodel.AbstractStylingModelFactory |
| * #doBuildGraph(org.eclipse.zest.core.internal.graphmodel.GraphModel) |
| */ |
| protected void doBuildGraph(Graph model) { |
| super.doBuildGraph(model); |
| Object inputElement = getViewer().getInput(); |
| Object entities[] = getContentProvider().getElements(inputElement); |
| if (entities == null) { |
| return; |
| } |
| for (int i = 0; i < entities.length; i++) { |
| Object data = entities[i]; |
| IFigureProvider figureProvider = null; |
| if (getLabelProvider() instanceof IFigureProvider) { |
| figureProvider = (IFigureProvider) getLabelProvider(); |
| } |
| if (!filterElement(inputElement, data)) { |
| if (figureProvider != null) { |
| createNode(model, data, figureProvider.getFigure(data)); |
| } else { |
| createNode(model, data); |
| } |
| } |
| } |
| |
| // We may have other entities (such as children of containers) |
| Set keySet = ((AbstractStructuredGraphViewer) getViewer()) |
| .getNodesMap().keySet(); |
| entities = keySet.toArray(); |
| |
| for (int i = 0; i < entities.length; i++) { |
| Object data = entities[i]; |
| |
| // If this element is filtered, continue to the next one. |
| if (filterElement(inputElement, data)) { |
| continue; |
| } |
| Object[] related = ((IGraphEntityContentProvider) getContentProvider()) |
| .getConnectedTo(data); |
| |
| if (related != null) { |
| for (int j = 0; j < related.length; j++) { |
| // if the node this node is connected to is filtered, |
| // don't display this edge |
| if (filterElement(inputElement, related[j])) { |
| continue; |
| } |
| EntityConnectionData connectionData = new EntityConnectionData( |
| data, related[j]); |
| if (filterElement(inputElement, connectionData)) { |
| continue; |
| } |
| createConnection(model, connectionData, data, related[j]); |
| } |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.zest.core.internal.graphmodel.IStylingGraphModelFactory#refresh |
| * (org.eclipse.zest.core.internal.graphmodel.GraphModel, java.lang.Object) |
| */ |
| public void refresh(Graph graph, Object element, boolean refreshLabels) { |
| if (element == null) { |
| return; |
| } |
| GraphNode node = viewer.getGraphModelNode(element); |
| if (node == null) { |
| // check to make sure that the user didn't send us an edge. |
| GraphConnection conn = viewer.getGraphModelConnection(element); |
| if (conn != null) { |
| // refresh on the connected nodes. |
| refresh(graph, conn.getSource().getData(), refreshLabels); |
| refresh(graph, conn.getDestination().getData(), refreshLabels); |
| return; |
| } |
| } |
| // can only refresh on nodes in this kind of factory. |
| if (node == null) { |
| // do nothing |
| return; |
| } |
| reconnect(graph, element, refreshLabels); |
| |
| if (refreshLabels) { |
| update(node); |
| for (Iterator it = node.getSourceConnections().iterator(); it |
| .hasNext();) { |
| update((GraphItem) it.next()); |
| } |
| for (Iterator it = node.getTargetConnections().iterator(); it |
| .hasNext();) { |
| update((GraphItem) it.next()); |
| } |
| } |
| } |
| |
| /** |
| * @param graph |
| * @param element |
| * @param refreshLabels |
| */ |
| private void reconnect(Graph graph, Object element, boolean refreshLabels) { |
| GraphNode node = viewer.getGraphModelNode(element); |
| Object[] related = ((IGraphEntityContentProvider) getContentProvider()) |
| .getConnectedTo(element); |
| List connections = node.getSourceConnections(); |
| LinkedList toAdd = new LinkedList(); |
| LinkedList toDelete = new LinkedList(); |
| LinkedList toKeep = new LinkedList(); |
| HashSet oldExternalConnections = new HashSet(); |
| HashSet newExternalConnections = new HashSet(); |
| for (Iterator it = connections.iterator(); it.hasNext();) { |
| oldExternalConnections.add(((GraphConnection) it.next()) |
| .getExternalConnection()); |
| } |
| for (int i = 0; i < related.length; i++) { |
| newExternalConnections.add(new EntityConnectionData(element, |
| related[i])); |
| } |
| for (Iterator it = oldExternalConnections.iterator(); it.hasNext();) { |
| Object next = it.next(); |
| if (!newExternalConnections.contains(next)) { |
| toDelete.add(next); |
| } else { |
| toKeep.add(next); |
| } |
| } |
| for (Iterator it = newExternalConnections.iterator(); it.hasNext();) { |
| Object next = it.next(); |
| if (!oldExternalConnections.contains(next)) { |
| toAdd.add(next); |
| } |
| } |
| for (Iterator it = toDelete.iterator(); it.hasNext();) { |
| viewer.removeGraphModelConnection(it.next()); |
| } |
| toDelete.clear(); |
| LinkedList newNodeList = new LinkedList(); |
| for (Iterator it = toAdd.iterator(); it.hasNext();) { |
| EntityConnectionData data = (EntityConnectionData) it.next(); |
| GraphNode dest = viewer.getGraphModelNode(data.dest); |
| if (dest == null) { |
| newNodeList.add(data.dest); |
| } |
| createConnection(graph, data, data.source, data.dest); |
| } |
| toAdd.clear(); |
| if (refreshLabels) { |
| for (Iterator i = toKeep.iterator(); i.hasNext();) { |
| styleItem(viewer.getGraphModelConnection(i.next())); |
| } |
| } |
| for (Iterator it = newNodeList.iterator(); it.hasNext();) { |
| // refresh the new nodes so that we get a fully-up-to-date graph. |
| refresh(graph, it.next()); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.zest.core.internal.graphmodel.IStylingGraphModelFactory#refresh |
| * (org.eclipse.zest.core.internal.graphmodel.GraphModel, java.lang.Object, |
| * boolean) |
| */ |
| public void refresh(Graph graph, Object element) { |
| refresh(graph, element, false); |
| } |
| |
| } |