blob: a9179efca0bd5d2443bd7a5d2b41c08d657e5262 [file] [log] [blame]
/**
* 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);
}
}