nz.ac.massey.cs.gql4jung.browser.queryviews.GraphBasedQueryView.java Source code

Java tutorial

Introduction

Here is the source code for nz.ac.massey.cs.gql4jung.browser.queryviews.GraphBasedQueryView.java

Source

/**
 * Copyright 2009 Jens Dietrich Licensed 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 nz.ac.massey.cs.gql4jung.browser.queryviews;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GridLayout;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import org.apache.commons.collections15.Transformer;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;
import nz.ac.massey.cs.gql4jung.Constraint;
import nz.ac.massey.cs.gql4jung.GroupByClause;
import nz.ac.massey.cs.gql4jung.Motif;
import nz.ac.massey.cs.gql4jung.PathConstraint;
import nz.ac.massey.cs.gql4jung.PropertyConstraint;
import nz.ac.massey.cs.gql4jung.browser.PropertyBean;
import nz.ac.massey.cs.gql4jung.browser.QueryView;
import nz.ac.massey.cs.gql4jung.browser.RankedVertex;

/**
 * Viewer for queries.
 * @author Jens Dietrich
 */
public class GraphBasedQueryView extends QueryView {

    final static Stroke EDGE_STROKE = new BasicStroke(1.0f);
    final static Stroke PATH_STROKE = new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f,
            new float[] { 2.0f }, 0.0f);
    final static Stroke CONSTRAINT_STROKE = new BasicStroke(0.5f);
    final static Stroke TYPE_VERTEX_STROKE = new BasicStroke(2);
    final static Stroke CONSTRAINT_VERTEX_STROKE = new BasicStroke(0.2f);

    /*
    public static void main(String[] args) throws Exception {
       String query = "cd.xml";
       InputStream in = new FileInputStream("queries/"+query);
       Motif motif = new XMLMotifReader().read(in);
       in.close();
       show(null,motif,"Query Viewer");
    }
    */

    abstract class VisualVertex implements RankedVertex {
    }

    class VisualEdge {

    }

    class TypeVertex extends VisualVertex {
        String role = null;

        @Override
        public int getDegree() {
            return 0;
        }
    }

    class ConstraintVertex extends VisualVertex {
        String constraint = null;

        @Override
        public int getDegree() {
            return 1;
        }
    }

    class GroupByVertex extends VisualVertex {
        String def = null;

        @Override
        public int getDegree() {
            return 1;
        }
    }

    class DepEdge extends VisualEdge {
        String role = null;
        int minLength = -1;
        int maxLength = -1;
    }

    class ConstraintEdge extends VisualEdge {
    }

    class GroupByEdge extends VisualEdge {
    }

    private Motif model = null;
    private JPanel graphPane = new JPanel(new GridLayout(1, 1));
    private GraphBasedQueryViewSettings settings = GraphBasedQueryViewSettings.DEFAULT_INSTANCE;

    public Motif getModel() {
        return model;
    }

    public void display(Motif model, String source) {
        this.model = model;
        DirectedGraph<VisualVertex, VisualEdge> g = asGraph(model);
        Layout layout = settings.getLayout(g);
        layout.setSize(graphPane.getSize());
        VisualizationViewer<VisualVertex, VisualEdge> vv = new VisualizationViewer<VisualVertex, VisualEdge>(
                layout);
        configureRenderer(vv.getRenderContext());
        vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);
        vv.setPreferredSize(graphPane.getSize()); //Sets the viewing area size
        vv.setBackground(settings.getBackground());

        graphPane.removeAll();
        graphPane.add(vv);
        graphPane.revalidate();

        DefaultModalGraphMouse gm = new DefaultModalGraphMouse();
        gm.setMode(edu.uci.ics.jung.visualization.control.ModalGraphMouse.Mode.PICKING);
        vv.setGraphMouse(gm);
        /*
        vv.setVertexToolTipTransformer(new Transformer<VisualVertex,String>(){
           @Override
           public String transform(VisualVertex v) {
        return v.role;
           }
        });
        */

    }

    private void configureRenderer(
            RenderContext<nz.ac.massey.cs.gql4jung.browser.queryviews.GraphBasedQueryView.VisualVertex, nz.ac.massey.cs.gql4jung.browser.queryviews.GraphBasedQueryView.VisualEdge> context) {
        context.setVertexLabelTransformer(new Transformer<VisualVertex, String>() {
            @Override
            public String transform(VisualVertex v) {
                if (v instanceof TypeVertex) {
                    TypeVertex tv = (TypeVertex) v;
                    return tv.role;
                } else if (v instanceof ConstraintVertex) {
                    ConstraintVertex cv = (ConstraintVertex) v;
                    return cv.constraint;
                } else if (v instanceof GroupByVertex) {
                    GroupByVertex cv = (GroupByVertex) v;
                    return "group by " + cv.def;
                } else
                    return "";
            }
        });
        context.setEdgeLabelTransformer(new Transformer<VisualEdge, String>() {
            @Override
            public String transform(VisualEdge e) {
                if (e instanceof DepEdge) {
                    DepEdge de = (DepEdge) e;
                    StringBuffer b = new StringBuffer();
                    if (de.minLength == de.maxLength) {
                        b.append(de.maxLength);
                    } else {
                        b.append(de.minLength).append("-").append(de.maxLength == -1 ? "many" : de.maxLength);
                    }
                    return b.toString();
                } else
                    return null;
            }
        });

        context.setEdgeStrokeTransformer(new Transformer<VisualEdge, Stroke>() {
            @Override
            public Stroke transform(nz.ac.massey.cs.gql4jung.browser.queryviews.GraphBasedQueryView.VisualEdge e) {
                if (e instanceof DepEdge) {
                    DepEdge de = (DepEdge) e;
                    return de.maxLength == 1 ? EDGE_STROKE : PATH_STROKE;
                } else if (e instanceof ConstraintEdge) {
                    return CONSTRAINT_STROKE;
                } else if (e instanceof GroupByEdge) {
                    return CONSTRAINT_STROKE;
                } else
                    return EDGE_STROKE;
            }
        });
        context.setVertexStrokeTransformer(new Transformer<VisualVertex, Stroke>() {
            @Override
            public Stroke transform(
                    nz.ac.massey.cs.gql4jung.browser.queryviews.GraphBasedQueryView.VisualVertex v) {
                return v instanceof TypeVertex ? TYPE_VERTEX_STROKE : CONSTRAINT_VERTEX_STROKE;
            }
        });
        context.setVertexShapeTransformer(new Transformer<VisualVertex, Shape>() {
            @Override
            public Shape transform(VisualVertex v) {
                Font f = v instanceof TypeVertex ? settings.getRoleFont() : settings.getConstraintFont();
                FontMetrics FM = GraphBasedQueryView.this.getGraphics().getFontMetrics(f);
                int W = Math.max(settings.getMinBoxWidth(), FM.stringWidth(getLongLabel(v)) + 10);
                int H = v instanceof TypeVertex ? 30 : 22;
                if (v instanceof TypeVertex)
                    return new RoundRectangle2D.Float(-W / 2, -H / 2, W, H, 5, 5);
                else
                    return new Ellipse2D.Float(-W / 2, -H / 2, W, H);
            }

        });
        context.setVertexFillPaintTransformer(new Transformer<VisualVertex, Paint>() {
            @Override
            public Paint transform(VisualVertex v) {
                if (v instanceof TypeVertex)
                    return makeTransparent(settings.getRoleFillColor());
                else if (v instanceof ConstraintVertex)
                    return makeTransparent(settings.getConstraintFillColor());
                else if (v instanceof GroupByVertex)
                    return makeTransparent(settings.getGroupByFillColor());
                return Color.WHITE;
            }
        });
        context.setVertexDrawPaintTransformer(new Transformer<VisualVertex, Paint>() {
            @Override
            public Paint transform(VisualVertex v) {
                if (v instanceof TypeVertex)
                    return settings.getRoleFrameColor();
                else if (v instanceof ConstraintVertex)
                    return settings.getConstraintFrameColor();
                else if (v instanceof GroupByVertex)
                    return settings.getGroupByFrameColor();
                else
                    return Color.BLACK;
            }
        });
        context.setEdgeDrawPaintTransformer(new Transformer<VisualEdge, Paint>() {
            @Override
            public Paint transform(VisualEdge v) {
                if (v instanceof DepEdge)
                    return settings.getRoleFrameColor();
                else if (v instanceof ConstraintEdge)
                    return settings.getConstraintFrameColor();
                else if (v instanceof GroupByEdge)
                    return settings.getGroupByFrameColor();
                else
                    return Color.BLACK;
            }
        });
        context.setVertexFontTransformer(new Transformer<VisualVertex, Font>() {
            @Override
            public Font transform(VisualVertex v) {
                return v instanceof TypeVertex ? settings.getRoleFont() : settings.getConstraintFont();
            }
        });
        context.setEdgeFontTransformer(new Transformer<VisualEdge, Font>() {
            @Override
            public Font transform(VisualEdge e) {
                return settings.getEdgeFont();
            }
        });
        context.setArrowDrawPaintTransformer(new Transformer<VisualEdge, Paint>() {
            @Override
            public Paint transform(VisualEdge v) {
                return v instanceof DepEdge ? settings.getRoleFrameColor()
                        : makeTransparent(settings.getBackground(), 255);
            }
        });
        context.setArrowFillPaintTransformer(new Transformer<VisualEdge, Paint>() {
            @Override
            public Paint transform(VisualEdge v) {
                return v instanceof DepEdge ? settings.getRoleFrameColor()
                        : makeTransparent(settings.getBackground(), 255);
            }
        });
    }

    private String getLongLabel(VisualVertex v) {
        if (v instanceof TypeVertex) {
            return ((TypeVertex) v).role;
        } else if (v instanceof ConstraintVertex) {
            return ((ConstraintVertex) v).constraint;
        } else if (v instanceof GroupByVertex) {
            return "group by " + ((GroupByVertex) v).def;
        } else
            return "";
    }

    public GraphBasedQueryView() {
        super();
        initialize();
    }

    public static void show(JFrame parent, Motif motif, String title) {
        JDialog dlg = new JDialog(parent, title, false);
        GraphBasedQueryView qv = new GraphBasedQueryView();
        qv.display(motif, null);
        dlg.add(qv);
        dlg.setTitle(title);
        dlg.setSize(900, 600);
        dlg.setLocation(100, 100);
        dlg.setVisible(true);
    }

    private void initialize() {
        this.setLayout(new GridLayout(1, 1));
        graphPane.setLayout(new GridLayout(1, 1));
        this.add(new JScrollPane(graphPane));

    }

    private DirectedGraph<VisualVertex, VisualEdge> asGraph(Motif motif) {
        DirectedGraph<VisualVertex, VisualEdge> g = new DirectedSparseGraph<VisualVertex, VisualEdge>();
        Map<String, TypeVertex> verticesByRole = new HashMap<String, TypeVertex>();
        for (String r : model.getRoles()) {
            TypeVertex v = new TypeVertex();
            v.role = r;
            g.addVertex(v);
            verticesByRole.put(r, v);
        }
        for (Constraint c : model.getConstraints()) {
            if (c instanceof PathConstraint) {
                PathConstraint pc = (PathConstraint) c;
                DepEdge e = new DepEdge();
                e.role = pc.getRole();
                e.maxLength = pc.getMaxLength();
                e.minLength = pc.getMinLength();
                TypeVertex v1 = verticesByRole.get(pc.getSource());
                TypeVertex v2 = verticesByRole.get(pc.getTarget());
                g.addEdge(e, v1, v2);
            }
            if (c instanceof PropertyConstraint && settings.isShowConstraints()) {
                PropertyConstraint pc = (PropertyConstraint) c;
                ConstraintVertex cv = new ConstraintVertex();
                cv.constraint = pc.getExpression();
                g.addVertex(cv);
                List<TypeVertex> participants = new ArrayList<TypeVertex>();
                for (String role : pc.getRoles()) {
                    TypeVertex v = verticesByRole.get(role);
                    if (v != null)
                        participants.add(v);
                }
                // otherwise, referenced roles might be path roles - TODO
                if (participants.size() == pc.getRoles().size()) {
                    for (TypeVertex v : participants) {
                        ConstraintEdge e = new ConstraintEdge();
                        g.addEdge(e, v, cv);
                    }
                }
            }
        }
        if (settings.isShowGroupByClauses()) {
            for (GroupByClause gb : model.getGroupByClauses()) {
                GroupByVertex gbv = new GroupByVertex();
                gbv.def = gb.getExpression();
                g.addVertex(gbv);
                String role = gb.getRole();
                TypeVertex v = verticesByRole.get(role);
                if (v != null) {
                    GroupByEdge e = new GroupByEdge();
                    g.addEdge(e, gbv, v);
                }
            }
        }
        return g;
    }

    public String getName() {
        return "motif as graph";
    }

    public PropertyBean getSettings() {
        return settings;
    }

    private Color makeTransparent(Color c) {
        return makeTransparent(c, settings.getVertexTransparency());
    }

    private Color makeTransparent(Color c, int alpha) {
        return new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);
    }

}