| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.oodt.cas.workflow.gui.perspective.view.impl; |
| |
| //JDK imports |
| import java.awt.Color; |
| import java.awt.Font; |
| import java.awt.geom.Rectangle2D; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| |
| import javax.swing.BorderFactory; |
| |
| //OODT imports |
| import org.apache.oodt.cas.workflow.gui.model.ModelNode; |
| |
| //JGraph imports |
| import org.jgraph.event.GraphModelEvent; |
| import org.jgraph.event.GraphModelListener; |
| import org.jgraph.graph.AttributeMap; |
| import org.jgraph.graph.ConnectionSet; |
| import org.jgraph.graph.DefaultEdge; |
| import org.jgraph.graph.DefaultGraphCell; |
| import org.jgraph.graph.DefaultGraphModel; |
| import org.jgraph.graph.DefaultPort; |
| import org.jgraph.graph.GraphConstants; |
| |
| //Jung imports |
| import edu.uci.ics.jung.graph.ObservableGraph; |
| import edu.uci.ics.jung.graph.event.GraphEvent; |
| import edu.uci.ics.jung.graph.event.GraphEventListener; |
| |
| /** |
| * |
| * This class integrates OODT, Jung and JGraph. |
| * |
| * Not necessarily in that order. It acts as a facade, wrapping a Jung graph |
| * (and its modifications) and then using that to update the current state of |
| * the associated JGraph model. |
| * |
| * @author mattmann |
| * |
| */ |
| public class JungJGraphModelAdapter extends DefaultGraphModel { |
| |
| private static final long serialVersionUID = 205647349848965651L; |
| |
| private ObservableGraph<ModelNode, IdentifiableEdge> jungGraph; |
| |
| private Map<String, DefaultGraphCell> cellMap; |
| |
| private static final Logger LOG = Logger |
| .getLogger(JungJGraphModelAdapter.class.getName()); |
| |
| public JungJGraphModelAdapter( |
| final ObservableGraph<ModelNode, IdentifiableEdge> jungGraph) { |
| this.jungGraph = jungGraph; |
| this.jungGraph.addGraphEventListener(new WorkflowChangeListener(this)); |
| this.cellMap = new HashMap<String, DefaultGraphCell>(); |
| this.addGraphModelListener(new GraphModelListener() { |
| |
| @Override |
| public void graphChanged(GraphModelEvent e) { |
| Object[] added = e.getChange().getInserted(); |
| Object[] removed = e.getChange().getRemoved(); |
| Object[] changed = e.getChange().getChanged(); |
| |
| if (added != null && added.length > 0) { |
| for (Object a : added) { |
| LOG.log(Level.FINE, "Jgraph notification of object added: [" |
| + a.getClass().getName() + "]"); |
| |
| if (a instanceof org.jgraph.graph.DefaultEdge) { |
| LOG.log(Level.FINE, "Edge added to jgraph"); |
| org.jgraph.graph.DefaultEdge edge = (org.jgraph.graph.DefaultEdge) a; |
| if (!jungGraph.getEdges().contains(edge.getUserObject())) { |
| jungGraph.addEdge( |
| new IdentifiableEdge((ModelNode) edge.getSource(), |
| (ModelNode) edge.getTarget()), (ModelNode) edge |
| .getSource(), (ModelNode) edge.getTarget()); |
| } |
| } else if (a instanceof org.jgraph.graph.DefaultGraphCell) { |
| LOG.log(Level.FINE, "Vertex added to jgraph"); |
| org.jgraph.graph.DefaultGraphCell cell = (org.jgraph.graph.DefaultGraphCell) a; |
| |
| if (!jungGraph.getVertices().contains(cell.getUserObject())) { |
| jungGraph.addVertex((ModelNode) cell.getUserObject()); |
| } |
| } |
| } |
| } |
| |
| if (removed != null && removed.length > 0) { |
| for (Object r : removed) { |
| LOG.log(Level.FINE, "Jgraph notification of object removed: [" |
| + r.getClass().getName() + "]"); |
| |
| if (r instanceof org.jgraph.graph.DefaultEdge) { |
| LOG.log(Level.FINE, "Edge removed from jgraph"); |
| org.jgraph.graph.DefaultEdge edge = (org.jgraph.graph.DefaultEdge) r; |
| if (jungGraph.getEdges().contains(edge.getUserObject())) { |
| jungGraph.removeEdge((IdentifiableEdge) edge.getUserObject()); |
| } |
| } else if (r instanceof org.jgraph.graph.DefaultGraphCell) { |
| LOG.log(Level.FINE, "Vertex removed from jgraph"); |
| org.jgraph.graph.DefaultGraphCell cell = (org.jgraph.graph.DefaultGraphCell) r; |
| |
| if (jungGraph.getVertices().contains(cell.getUserObject())) { |
| jungGraph.removeVertex((ModelNode) cell.getUserObject()); |
| } |
| } |
| } |
| } |
| |
| } |
| }); |
| |
| } |
| |
| public DefaultGraphCell getVertexCell(ModelNode node) { |
| if (cellMap.get(node.getId()) != null) { |
| return cellMap.get(node.getId()); |
| } |
| |
| DefaultGraphCell cell = new DefaultGraphCell(node); |
| cell.add(new DefaultPort()); |
| return cell; |
| } |
| |
| private AttributeMap getEdgeAttributes(DefaultEdge edge) { |
| AttributeMap eMap = new AttributeMap(); |
| GraphConstants.setLineEnd(eMap, GraphConstants.ARROW_TECHNICAL); |
| GraphConstants.setEndFill(eMap, true); |
| GraphConstants.setEndSize(eMap, 10); |
| GraphConstants.setForeground(eMap, Color.decode("#25507C")); |
| GraphConstants.setFont(eMap, |
| GraphConstants.DEFAULTFONT.deriveFont(Font.BOLD, 12)); |
| GraphConstants.setLineColor(eMap, Color.decode("#7AA1E6")); |
| AttributeMap map = new AttributeMap(); |
| map.put(edge, eMap); |
| return map; |
| } |
| |
| private AttributeMap getVertexAttributes(DefaultGraphCell cell) { |
| AttributeMap vMap = new AttributeMap(); |
| |
| Color c = Color.decode("#FF9900"); |
| GraphConstants.setBounds(vMap, new Rectangle2D.Double(50, 50, 90, 30)); |
| GraphConstants.setBorder(vMap, BorderFactory.createRaisedBevelBorder()); |
| GraphConstants.setBackground(vMap, c); |
| GraphConstants.setForeground(vMap, Color.white); |
| GraphConstants.setFont(vMap, |
| GraphConstants.DEFAULTFONT.deriveFont(Font.BOLD, 12)); |
| GraphConstants.setOpaque(vMap, true); |
| |
| AttributeMap map = new AttributeMap(); |
| map.put(cell, vMap); |
| return map; |
| } |
| |
| private class WorkflowChangeListener implements |
| GraphEventListener<ModelNode, IdentifiableEdge> { |
| |
| private JungJGraphModelAdapter adapter; |
| |
| public WorkflowChangeListener(JungJGraphModelAdapter adapter) { |
| this.adapter = adapter; |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * edu.uci.ics.jung.graph.event.GraphEventListener#handleGraphEvent(edu. |
| * uci.ics.jung.graph.event.GraphEvent) |
| */ |
| @Override |
| public void handleGraphEvent(GraphEvent<ModelNode, IdentifiableEdge> e) { |
| if (e.getType().equals(GraphEvent.Type.EDGE_ADDED)) { |
| LOG.log(Level.FINE, "EDGE ADDED!"); |
| GraphEvent.Edge<ModelNode, IdentifiableEdge> event = (GraphEvent.Edge<ModelNode, IdentifiableEdge>) e; |
| addJGraphEdge(event.getEdge()); |
| } else if (e.getType().equals(GraphEvent.Type.EDGE_REMOVED)) { |
| LOG.log(Level.FINE, "EDGE REMOVED!"); |
| } else if (e.getType().equals(GraphEvent.Type.VERTEX_ADDED)) { |
| LOG.log(Level.FINE, "VERTEX ADDED!"); |
| GraphEvent.Vertex<ModelNode, IdentifiableEdge> event = (GraphEvent.Vertex<ModelNode, IdentifiableEdge>) e; |
| addJGraphVertex(event.getVertex()); |
| } else if (e.getType().equals(GraphEvent.Type.VERTEX_REMOVED)) { |
| LOG.log(Level.FINE, "VERTEX REMOVED!"); |
| } |
| |
| } |
| |
| } |
| |
| private void addJGraphVertex(ModelNode node) { |
| DefaultGraphCell cell = new DefaultGraphCell(node); |
| cell.add(new DefaultPort()); |
| insert(new Object[] { cell }, getVertexAttributes(cell), null, null, null); |
| cellMap.put(node.getId(), cell); |
| } |
| |
| private void addJGraphEdge(IdentifiableEdge e) { |
| ConnectionSet set = new ConnectionSet(); |
| DefaultEdge theEdge = new DefaultEdge(e); |
| DefaultGraphCell from = null; |
| DefaultGraphCell to = null; |
| String fromVertexId = e.getFrom().getId(); |
| String toVertexId = e.getTo().getId(); |
| if (!cellMap.containsKey(fromVertexId)) { |
| addJGraphVertex(e.getFrom()); |
| } |
| from = cellMap.get(fromVertexId); |
| |
| if (!cellMap.containsKey(toVertexId)) { |
| addJGraphVertex(e.getTo()); |
| } |
| |
| to = cellMap.get(toVertexId); |
| |
| set.connect(theEdge, (DefaultPort) from.getChildAt(0), |
| (DefaultPort) to.getChildAt(0)); |
| insert(new Object[] { theEdge }, getEdgeAttributes(theEdge), set, null, |
| null); |
| } |
| |
| } |