test.be.fedict.eid.applet.JGraphTest.java Source code

Java tutorial

Introduction

Here is the source code for test.be.fedict.eid.applet.JGraphTest.java

Source

/*
 * eID Applet Project.
 * Copyright (C) 2010 FedICT.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version
 * 3.0 as published by the Free Software Foundation.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, see 
 * http://www.gnu.org/licenses/.
 */

package test.be.fedict.eid.applet;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;

import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.map.HashedMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jgraph.JGraph;
import org.jgraph.graph.DefaultCellViewFactory;
import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.DefaultGraphModel;
import org.jgraph.graph.GraphConstants;
import org.jgraph.graph.GraphLayoutCache;
import org.jgraph.graph.GraphModel;
import org.junit.Test;

import be.fedict.eid.applet.shared.AppletProtocolMessageCatalog;
import be.fedict.eid.applet.shared.annotation.ProtocolStateAllowed;
import be.fedict.eid.applet.shared.annotation.ResponsesAllowed;
import be.fedict.eid.applet.shared.annotation.StartRequestMessage;
import be.fedict.eid.applet.shared.annotation.StateTransition;
import be.fedict.eid.applet.shared.annotation.StopResponseMessage;
import be.fedict.eid.applet.shared.protocol.ProtocolState;
import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseMultigraph;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;

/**
 * Spike for JGraph usage.
 * 
 * @author Frank Cornelis
 * 
 */
public class JGraphTest {

    private static final Log LOG = LogFactory.getLog(JGraphTest.class);

    @Test
    public void testJGraph() throws Exception {
        GraphModel model = new DefaultGraphModel();
        GraphLayoutCache view = new GraphLayoutCache(model, new DefaultCellViewFactory());
        JGraph graph = new JGraph(model, view);

        DefaultGraphCell[] cells = new DefaultGraphCell[3];
        cells[0] = createCell("hello", true);
        cells[1] = createCell("world", false);
        DefaultEdge edge = new DefaultEdge();
        GraphConstants.setLineStyle(edge.getAttributes(), GraphConstants.ARROW_LINE);
        edge.setSource(cells[0].getChildAt(0));
        edge.setTarget(cells[1].getChildAt(0));
        cells[2] = edge;
        graph.getGraphLayoutCache().insert(cells);

        JOptionPane.showMessageDialog(null, new JScrollPane(graph));
    }

    private DefaultGraphCell createCell(String name, boolean raised) {
        DefaultGraphCell cell = new DefaultGraphCell(name);
        cell.addPort();
        GraphConstants.setBorder(cell.getAttributes(), BorderFactory.createRaisedBevelBorder());
        return cell;
    }

    @Test
    public void testJUNG2() throws Exception {
        Graph<String, String> graph = new SparseMultigraph<String, String>();
        graph.addVertex("state 1");
        graph.addVertex("state 2");
        graph.addVertex("state 3");
        graph.addVertex("state 4");
        graph.addVertex("state 5");
        graph.addVertex("state 6");
        graph.addEdge("edge 1", "state 1", "state 2", EdgeType.DIRECTED);
        graph.addEdge("edge 2", "state 1", "state 3", EdgeType.DIRECTED);
        graph.addEdge("edge 3", "state 1", "state 4", EdgeType.DIRECTED);
        graph.addEdge("edge 4", "state 3", "state 4", EdgeType.DIRECTED);

        CircleLayout<String, String> layout = new CircleLayout<String, String>(graph);
        layout.setSize(new Dimension(300, 300));

        BasicVisualizationServer<String, String> visualization = new BasicVisualizationServer<String, String>(
                layout);
        visualization.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<String>());
        visualization.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<String>());
        visualization.setPreferredSize(new Dimension(350, 350));

        JOptionPane.showMessageDialog(null, visualization);
    }

    @Test
    public void testVisualizeProtocol() throws Exception {
        BasicVisualizationServer<String, String> visualization = createGraph();

        // JOptionPane.showMessageDialog(null, visualization);

        File tmpFile = File.createTempFile("graph-", ".png");
        graphToFile(visualization, tmpFile);
        LOG.debug("tmp file: " + tmpFile.getAbsolutePath());
    }

    private BasicVisualizationServer<String, String> createGraph() {
        AppletProtocolMessageCatalog catalog = new AppletProtocolMessageCatalog();
        List<Class<?>> catalogClasses = catalog.getCatalogClasses();

        Map<ProtocolState, List<String>> allowedProtocolStates = new HashedMap<ProtocolState, List<String>>();
        String startMessage = null;
        List<String> stopMessages = new LinkedList<String>();

        Graph<String, String> graph = new SparseMultigraph<String, String>();
        for (Class<?> messageClass : catalogClasses) {
            StartRequestMessage startRequestMessageAnnotation = messageClass
                    .getAnnotation(StartRequestMessage.class);
            if (null != startRequestMessageAnnotation) {
                if (null != startMessage) {
                    throw new RuntimeException("only one single entry point possible");
                }
                startMessage = messageClass.getSimpleName();
            }
            StopResponseMessage stopResponseMessageAnnotation = messageClass
                    .getAnnotation(StopResponseMessage.class);
            if (null != stopResponseMessageAnnotation) {
                stopMessages.add(messageClass.getSimpleName());
            }
            graph.addVertex(messageClass.getSimpleName());
            ProtocolStateAllowed protocolStateAllowedAnnotation = messageClass
                    .getAnnotation(ProtocolStateAllowed.class);
            if (null != protocolStateAllowedAnnotation) {
                ProtocolState protocolState = protocolStateAllowedAnnotation.value();
                List<String> messages = allowedProtocolStates.get(protocolState);
                if (null == messages) {
                    messages = new LinkedList<String>();
                    allowedProtocolStates.put(protocolState, messages);
                }
                messages.add(messageClass.getSimpleName());
            }
        }

        LOG.debug("allowed protocol states: " + allowedProtocolStates);

        int edgeIdx = 0;
        for (Class<?> messageClass : catalogClasses) {
            ResponsesAllowed responsesAllowedAnnotation = messageClass.getAnnotation(ResponsesAllowed.class);
            if (null != responsesAllowedAnnotation) {
                Class<?>[] responseClasses = responsesAllowedAnnotation.value();
                for (Class<?> responseClass : responseClasses) {
                    graph.addEdge("edge-" + edgeIdx, messageClass.getSimpleName(), responseClass.getSimpleName(),
                            EdgeType.DIRECTED);
                    edgeIdx++;
                }
            }
            StateTransition stateTransitionAnnotation = messageClass.getAnnotation(StateTransition.class);
            if (null != stateTransitionAnnotation) {
                ProtocolState protocolState = stateTransitionAnnotation.value();
                List<String> messages = allowedProtocolStates.get(protocolState);
                for (String message : messages) {
                    graph.addEdge("edge-" + edgeIdx, messageClass.getSimpleName(), message, EdgeType.DIRECTED);
                    edgeIdx++;
                }
            }
        }

        Layout<String, String> layout = new CircleLayout<String, String>(graph);
        layout.setSize(new Dimension(900, 650));

        BasicVisualizationServer<String, String> visualization = new BasicVisualizationServer<String, String>(
                layout);
        visualization.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<String>());
        Transformer<String, Paint> myVertexTransformer = new MyVertexTransformer(startMessage, stopMessages);
        visualization.getRenderContext().setVertexFillPaintTransformer(myVertexTransformer);
        visualization.getRenderer().getVertexLabelRenderer().setPosition(Position.AUTO);
        visualization.setPreferredSize(new Dimension(900, 650));
        visualization.setBackground(Color.WHITE);
        return visualization;
    }

    private void graphToFile(BasicVisualizationServer<String, String> visualization, File file) throws IOException {
        Dimension size = visualization.getSize();
        int width = (int) (size.getWidth() + 1);
        int height = (int) (size.getHeight() + 1);
        LOG.debug("width: " + width);
        LOG.debug("height: " + height);
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics = bufferedImage.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, 900, 650);
        visualization.setBounds(0, 0, 900, 650);
        visualization.paint(graphics);
        graphics.dispose();
        ImageIO.write(bufferedImage, "png", file);
    }

    public static class MyVertexTransformer implements Transformer<String, Paint> {

        private final String startMessage;

        private final List<String> stopMessages;

        public MyVertexTransformer(String startMessage, List<String> stopMessages) {
            this.startMessage = startMessage;
            this.stopMessages = stopMessages;
        }

        @Override
        public Paint transform(String vertexName) {
            if (this.startMessage.equals(vertexName)) {
                return Color.GREEN;
            }
            if (this.stopMessages.contains(vertexName)) {
                return Color.RED;
            }
            return Color.WHITE;
        }
    }
}