de.d3web.empiricaltesting.casevisualization.jung.JUNGCaseVisualizer.java Source code

Java tutorial

Introduction

Here is the source code for de.d3web.empiricaltesting.casevisualization.jung.JUNGCaseVisualizer.java

Source

/*
 * Copyright (C) 2009 Chair of Artificial Intelligence and Applied Informatics
 * Computer Science VI, University of Wuerzburg
 * 
 * This is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 3 of the License, or (at your option) any
 * later version.
 * 
 * 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, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
 * site: http://www.fsf.org.
 */

package de.d3web.empiricaltesting.casevisualization.jung;

import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import javax.swing.*;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfTemplate;
import com.lowagie.text.pdf.PdfWriter;
import edu.uci.ics.jung.algorithms.layout.TreeLayout;
import edu.uci.ics.jung.visualization.DefaultVisualizationModel;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.VisualizationModel;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.decorators.EdgeShape;
import edu.uci.ics.jung.visualization.renderers.VertexLabelAsShapeRenderer;

import de.d3web.core.knowledge.terminology.Choice;
import de.d3web.core.knowledge.terminology.QuestionChoice;
import de.d3web.empiricaltesting.CaseUtils;
import de.d3web.empiricaltesting.RatedTestCase;
import de.d3web.empiricaltesting.SequentialTestCase;
import de.d3web.empiricaltesting.TestCase;
import de.d3web.empiricaltesting.casevisualization.CaseVisualizer;
import de.d3web.empiricaltesting.casevisualization.ConfigLoader;
import de.d3web.empiricaltesting.casevisualization.Label;
import de.d3web.empiricaltesting.casevisualization.util.Util;

/**
 * This class visualizes the generated graph and offers the ability to save the
 * graph to a PDF file.
 * 
 * @author Sebastian Furth
 * 
 */
@SuppressWarnings("deprecation") // should still work but not important enough to refactor to the new TestCases...
public final class JUNGCaseVisualizer implements CaseVisualizer {

    /**
     * The graph which is visualized.
     */
    private CaseTree<RatedTestCase, EdgeFinding> graph;

    /**
     * The VisualizationViewer which actually is the visualized graph.
     */
    private VisualizationViewer<RatedTestCase, EdgeFinding> vv;

    private static final JUNGCaseVisualizer instance = new JUNGCaseVisualizer();

    /**
     * Private Constructor that ensures noninstantiability.
     */
    private JUNGCaseVisualizer() {
    }

    /**
     * Initializes the graph.
     * 
     * @param cases List<SequentialTestCase> cases which will be visualized.
     */
    private void init(List<SequentialTestCase> cases) {
        this.graph = CaseTreeFactory.getInstance().generateGraph(cases);
        setupVisualizationViewer();
    }

    /**
     * Returns an instance of JUNGCaseVisualizer.
     * 
     * @return JUNGCaseVisualizer.
     */
    public static JUNGCaseVisualizer getInstance() {
        return instance;
    }

    /**
     * Shows the specified testsuite visualized in a simple JFrame
     * 
     * @param testsuite TestSuite which will be visualized.
     */
    public void showInJFrame(TestCase testsuite) {
        showInJFrame(testsuite.getRepository());
    }

    /**
     * Shows the specified List<SequentialTestCase> visualized in a simple
     * JFrame
     * 
     * @param cases List<SequentialTestCase> which will be visualized.
     */
    public void showInJFrame(List<SequentialTestCase> cases) {

        init(cases);

        JFrame frame = new JFrame();
        //noinspection MagicConstant
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container content = frame.getContentPane();
        final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
        content.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    /**
     * Saves the graph visualization to a <b>PDF file</b> which will be created
     * at the committed filepath. Before the graph is saved to the file there is
     * a check if you want to partition the tree.
     * 
     * @param testSuite TestSuite which's cases will be visualized by this
     *        class.
     * @param file String which specifies where the created <b>PDF file</b> will
     *        be stored.
     */
    @Override
    public void writeToFile(TestCase testSuite, File file) throws IOException {
        writeToFile(testSuite, file.getPath());
    }

    private void writeToFile(TestCase testSuite, String filepath) throws IOException {
        String partitionTree = ConfigLoader.getInstance().getProperty("partitionTree");
        if (partitionTree.equals("true")) {
            QuestionChoice firstQuestion = (QuestionChoice) testSuite.getRepository().get(0).getCases().get(0)
                    .getFindings().get(0).getQuestion();
            List<Choice> firstAnswers = firstQuestion.getAllAlternatives();

            for (Choice answerOfFirstQuestion : firstAnswers) {
                TestCase partitioned = Util.getPartiallyAnsweredSuite(answerOfFirstQuestion,
                        testSuite.getRepository());
                if (!partitioned.getRepository().isEmpty()) {
                    writeToFile(partitioned.getRepository(),
                            checkFilePath(filepath, answerOfFirstQuestion.toString()));
                }
            }
        } else {
            writeToFile(testSuite.getRepository(), checkFilePath(filepath, ""));
        }
    }

    /**
     * Saves the graph visualization to a <b>PDF file</b> which will be created
     * at the committed filepath.
     * 
     * @param cases List<SequentialTestCase> which's elements will be visualized
     *        by this class.
     * @param file String which specifies where the created <b>PDF file</b> will
     *        be stored.
     */
    @Override
    public void writeToFile(List<SequentialTestCase> cases, File file) throws IOException {
        writeToFile(cases, file.getPath());
    }

    private void writeToFile(List<SequentialTestCase> cases, String filepath) throws IOException {
        filepath = checkFilePath(filepath, "");
        try (FileOutputStream fileOutputStream = new FileOutputStream(filepath)) {
            writeToStream(cases, fileOutputStream);
        }
    }

    /**
     * Streams the graph to an OutputStream (useful for web requests!)
     * 
     * @param cases List<SequentialTestCase> cases
     * @param outStream OutputStream
     */
    @Override
    public void writeToStream(java.util.List<SequentialTestCase> cases, java.io.OutputStream outStream)
            throws IOException {

        init(cases);

        int w = vv.getGraphLayout().getSize().width;
        int h = vv.getGraphLayout().getSize().height;

        Document document = new Document();

        try {

            PdfWriter writer = PdfWriter.getInstance(document, outStream);
            document.setPageSize(new Rectangle(w, h));
            document.open();

            PdfContentByte cb = writer.getDirectContent();
            PdfTemplate tp = cb.createTemplate(w, h);
            Graphics2D g2 = tp.createGraphics(w, h);
            paintGraph(g2);

            g2.dispose();
            tp.sanityCheck();
            cb.addTemplate(tp, 0, 0);
            cb.sanityCheck();

            document.close();

        } catch (DocumentException e) {
            throw new IOException("Error while writing to file. The file was not created. ", e);
        }
    }

    /**
     * Actually writes the Graph as a Graph2D Object to the PDF file.
     * 
     * @param g2 Graph2D Object to which the graph will be written.
     */
    private void paintGraph(Graphics2D g2) {

        vv.setSize(vv.getGraphLayout().getSize());
        Container c = new Container();
        c.add(vv);
        c.addNotify();
        c.validate();
        c.paintComponents(g2);
    }

    /**
     * Creates and customizes a VisualizationViewer Object which is necessary
     * for displaying the graph / tree.
     */
    private void setupVisualizationViewer() {

        vv = generateVisualizationViewer();

        VertexLabelAsShapeRenderer<RatedTestCase, EdgeFinding> vlasr = new VertexLabelAsShapeRenderer<>(
                vv.getRenderContext());

        // Vertex transformation
        vv.getRenderContext().setVertexLabelTransformer(new VertexTransformer(graph));
        vv.getRenderContext().setVertexShapeTransformer(vlasr);
        vv.getRenderContext().setVertexFillPaintTransformer(new VertexColorTransformer());

        // Edge transformation
        vv.getRenderContext().setEdgeLabelTransformer(new EdgeTransformer(graph));
        vv.getRenderContext().setEdgeDrawPaintTransformer(new EdgeColorTransformer(graph));
        vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line<>());
        vv.getRenderContext().setArrowFillPaintTransformer(new EdgeColorTransformer(graph));
        vv.getRenderContext().setArrowDrawPaintTransformer(new EdgeColorTransformer(graph));
        vv.getRenderContext().setEdgeStrokeTransformer(new EdgeStrokeTransformer(graph));
        vv.getRenderContext().setEdgeArrowStrokeTransformer(new EdgeStrokeTransformer(graph));
        vv.getRenderContext().getEdgeLabelRenderer().setRotateEdgeLabels(false);

        // customize the renderer
        vv.getRenderer().setVertexLabelRenderer(vlasr);
        vv.setBackground(Color.WHITE);

        // final DefaultModalGraphMouse<String, Number> graphMouse =
        // new DefaultModalGraphMouse<String, Number>();

        // vv.setGraphMouse(graphMouse);
        // vv.addKeyListener(graphMouse.getModeKeyListener());
    }

    /**
     * Actually generates the VizualizationViewer Object.
     * 
     * @return VizualizationViewer Object which needs further customization.
     */
    private VisualizationViewer<RatedTestCase, EdgeFinding> generateVisualizationViewer() {

        int distY = DistanceDeterminer.getInstance().determineDistance(graph.getVertices());

        TreeLayout<RatedTestCase, EdgeFinding> treeLayout = new TreeLayout<>(graph, 250, distY);

        Dimension preferredSize = new Dimension(1400, 800);

        final VisualizationModel<RatedTestCase, EdgeFinding> visualizationModel = new DefaultVisualizationModel<>(
                treeLayout, preferredSize);

        return new VisualizationViewer<>(visualizationModel, preferredSize);
    }

    /**
     * Checks the if everything is ok with the output path specified for the PDF
     * File. If there is something wrong it will be corrected.
     * 
     * @param filepath String the specified filepath
     * @param addOn String extra information which should be in the filename
     * @return String correct filepath
     */
    private String checkFilePath(String filepath, String addOn) {

        addOn = CaseUtils.getInstance().removeBadChars(addOn);

        if (filepath.equals("")) {
            return "pdfFile" + addOn + ".pdf";
        } else if (filepath.endsWith("/")) {
            return filepath + addOn + ".pdf";
        } else if (filepath.endsWith(".pdf")) {
            if (!addOn.equals("")) {
                return filepath.substring(0, filepath.length() - 4) + "_" + addOn + ".pdf";
            }
        }

        return filepath;

    }

    @Override
    public void setLabel(Label label) {
        // do nothing. Labels are not implemented yet.
    }

}