package catdata.aql.gui; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Paint; import java.awt.Stroke; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.function.BiFunction; import java.util.stream.Collectors; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; import com.google.common.base.Function; import catdata.Chc; import catdata.Pair; import catdata.Triple; import catdata.Unit; import catdata.Util; import catdata.apg.ApgInstance; import catdata.apg.ApgMapping; import catdata.apg.ApgSchema; import catdata.apg.ApgTerm; import catdata.apg.ApgTransform; import catdata.apg.ApgTy; import catdata.apg.ApgTypeside; import catdata.aql.Algebra; import catdata.aql.AqlJs; import catdata.aql.ColimitSchema; import catdata.aql.Collage; import catdata.aql.Comment; import catdata.aql.Constraints; import catdata.aql.DP; import catdata.aql.Instance; import catdata.aql.Mapping; import catdata.aql.Mor; import catdata.aql.Pragma; import catdata.aql.Query; import catdata.aql.RawTerm; import catdata.aql.Schema; import catdata.aql.Semantics; import catdata.aql.SemanticsVisitor; import catdata.aql.Term; import catdata.aql.Transform; import catdata.aql.TypeSide; import catdata.aql.Var; import catdata.aql.exp.AqlEnv; import catdata.aql.exp.AqlParserFactory; import catdata.aql.exp.Att; import catdata.aql.exp.En; import catdata.aql.exp.Exp; import catdata.aql.exp.Fk; import catdata.aql.exp.Gen; import catdata.aql.exp.Sk; import catdata.aql.exp.Sym; import catdata.aql.exp.Ty; import catdata.graph.DMG; import catdata.ide.CodeTextPanel; import catdata.ide.GuiUtil; import catdata.ide.Split; import edu.uci.ics.jung.algorithms.layout.FRLayout; import edu.uci.ics.jung.algorithms.layout.Layout; import edu.uci.ics.jung.graph.DirectedSparseMultigraph; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.visualization.GraphZoomScrollPane; import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; import edu.uci.ics.jung.visualization.control.ModalGraphMouse.Mode; import edu.uci.ics.jung.visualization.renderers.VertexLabelRenderer; import gnu.trove.map.hash.THashMap; import gnu.trove.set.hash.THashSet; public final class AqlViewer implements SemanticsVisitor<Unit, JTabbedPane, RuntimeException> { private int maxrows; private AqlEnv env; private boolean showAtts; public AqlViewer(int maxrows, @SuppressWarnings("unused") AqlEnv env, boolean showAtts) { this.maxrows = maxrows; this.showAtts = showAtts; this.env = env; } public static String html(Object obj) { return obj.toString().replace("\n", "<br>").replace("\t", " "); } public static JComponent view(String k, Semantics s, int maxrows, Exp<?> exp, AqlEnv env, boolean showAtts) { JTabbedPane ret = new JTabbedPane(); new AqlViewer(maxrows, env, showAtts).visit(k, ret, s); String l = "Compute time: " + env.performance.get(k) + " s.\n\nSize: " + s.size(); if (s.size() < 1024) { ret.addTab("Text", new CodeTextPanel("", s.toString())); } else { ret.addTab("Text", new CodeTextPanel("", "Suppressed, size " + s.size() + ".")); } ret.addTab("Expression", new CodeTextPanel("", l + "\n\n" + exp.toString())); // System.out.println(exp.getClass() + " " + env.performance.get(k)); return ret; } private static <N, E> JComponent viewGraph(DMG<N, E> g) { Graph<N, E> sgv = new DirectedSparseMultigraph<>(); for (N n : g.nodes) { sgv.addVertex(n); } for (E e : g.edges.keySet()) { sgv.addEdge(e, g.edges.get(e).first, g.edges.get(e).second); } if (sgv.getVertexCount() == 0) { return new JPanel(); } Layout<N, E> layout = new FRLayout<>(sgv); layout.setSize(new Dimension(600, 400)); VisualizationViewer<N, E> vv = new VisualizationViewer<>(layout); Function<N, Paint> vertexPaint = x -> Color.black; DefaultModalGraphMouse<N, E> gm = new DefaultModalGraphMouse<>(); gm.setMode(Mode.TRANSFORMING); vv.setGraphMouse(gm); gm.setMode(Mode.PICKING); vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint); Function<E, String> et = Object::toString; Function<N, String> vt = Object::toString; vv.getRenderContext().setEdgeLabelTransformer(et); vv.getRenderContext().setVertexLabelTransformer(vt); GraphZoomScrollPane zzz = new GraphZoomScrollPane(vv); JPanel ret = new JPanel(new GridLayout(1, 1)); ret.add(zzz); ret.setBorder(BorderFactory.createEtchedBorder()); vv.getRenderContext().setLabelOffset(16); vv.setBackground(Color.white); return ret; } /* * private <Ty, En, Sym, Fk, Att> JComponent viewSchemaAlt(Schema<Ty, En, Sym, * Fk, Att> schema) { * * mxGraph graph = new mxGraph(); graph.setAllowLoops(true); * graph.setCellsBendable(true); graph.setCellsDisconnectable(false); * graph.setHtmlLabels(true); graph.setAutoSizeCells(true); * graph.setMultigraph(true); graph.setEdgeLabelsMovable(false); * graph.setAllowNegativeCoordinates(true); graph.setDisconnectOnMove(false); * graph.setPortsEnabled(true); graph.setCellsEditable(false); // graph.set * Object parent = graph.getDefaultParent(); * * graph.getModel().beginUpdate(); try { Map<En, Object> m = new THashMap<>(); * int j = 0; for (En en : schema.ens) { StringBuffer sb = new StringBuffer(); * sb.append("<center>"); sb.append(en.toString()); sb.append("</center><hr/>"); * int i = 0; int l = 0; for (Att att : Util.alphabetical(schema.attsFrom(en))) * { if (i != 0) { sb.append("<br/>"); } sb.append(att.toString()); i++; l = * Math.max(l, att.toString().length()); } //sb.append("</html>"); Object v1 = * graph.insertVertex(parent, null, sb.toString(), 20 + j, 20 + j, 6*l, 8+18*i, * "ROUNDED;align=left;strokeColor=white;fillColor=white"); m.put(en, v1); j += * 20; } for (Entry<Fk, Pair<En, En>> fk : schema.fks.entrySet()) { * graph.insertEdge(parent, null, fk.getKey().toString(), * m.get(fk.getValue().first), m.get(fk.getValue().second)); } } finally { * graph.getModel().endUpdate(); } var layout = new mxFastOrganicLayout(graph); * layout.execute(graph.getDefaultParent()); var layout2 = new * mxParallelEdgeLayout(graph); layout2.execute(graph.getDefaultParent()); * * mxGraphComponent graphComponent = new mxGraphComponent(graph); return * graphComponent; } */ private <Ty, En, Sym, Fk, Att> JComponent viewSchema(Schema<Ty, En, Sym, Fk, Att> schema) { Graph<Chc<Ty, En>, Chc<Fk, Att>> sgv = new DirectedSparseMultigraph<>(); int i = 0; boolean triggered = false; for (En en : schema.ens) { sgv.addVertex(Chc.inRight(en)); i++; if (i >= maxrows) { triggered = true; break; } } if (showAtts) { i = 0; for (Ty ty : schema.typeSide.tys) { sgv.addVertex(Chc.inLeft(ty)); i++; if (i >= maxrows * maxrows) { triggered = true; break; } } for (Att att : schema.atts.keySet()) { sgv.addEdge(Chc.inRight(att), Chc.inRight(schema.atts.get(att).first), Chc.inLeft(schema.atts.get(att).second)); i++; if (i >= maxrows * maxrows) { triggered = true; break; } } } for (Fk fk : schema.fks.keySet()) { sgv.addEdge(Chc.inLeft(fk), Chc.inRight(schema.fks.get(fk).first), Chc.inRight(schema.fks.get(fk).second)); i++; if (i >= maxrows * maxrows) { triggered = true; break; } } // } if (sgv.getVertexCount() == 0) { return new JPanel(); } // Layout<Chc<Ty, En>, Chc<Fk, Att>> layout = new KKLayout<>(sgv); Layout<Chc<Ty, En>, Chc<Fk, Att>> layout = new FRLayout<>(sgv); layout.setSize(new Dimension(600, 400)); VisualizationViewer<Chc<Ty, En>, Chc<Fk, Att>> vv = new VisualizationViewer<>(layout); Function<Chc<Ty, En>, Paint> vertexPaint = x -> x.left ? Color.gray : Color.black; DefaultModalGraphMouse<Chc<Ty, En>, Chc<Fk, Att>> gm = new DefaultModalGraphMouse<>(); gm.setMode(Mode.TRANSFORMING); vv.setGraphMouse(gm); gm.setMode(Mode.PICKING); vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint); Function<Chc<Fk, Att>, String> et = Chc::toStringMash; Function<Chc<Ty, En>, String> vt = x -> { if (x.left) { return x.l.toString(); } En en = x.r; //if (!showAtts) { // return en.toString(); //} StringBuffer sb = new StringBuffer(); sb.append("<html><center>"); sb.append(en.toString()); sb.append("</center><hr/>"); // int i = 0; int l = 0; for (Att att : Util.alphabetical(schema.attsFrom(en))) { if (l != 0) { sb.append("<br/>"); } sb.append(att.toString()); l++; // l = Math.max(l, att.toString().length()); } sb.append("</html>"); return sb.toString(); }; vv.getRenderContext().setEdgeLabelTransformer(et); vv.getRenderContext().setVertexLabelTransformer(vt); vv.getRenderContext().setVertexLabelRenderer(new VertexLabelRenderer() { @Override public <V> Component getVertexLabelRendererComponent(JComponent arg0, Object arg1, Font arg2, boolean arg3, V arg4) { return new JLabel(arg1.toString()); } }); GraphZoomScrollPane zzz = new GraphZoomScrollPane(vv); JPanel ret = new JPanel(new GridLayout(1, 1)); ret.add(zzz); ret.setBorder(BorderFactory.createEtchedBorder()); vv.getRenderContext().setLabelOffset(16); // vv.getRenderContext().set vv.setBackground(Color.white); if (triggered) { ret.setBorder(BorderFactory.createTitledBorder("Partial")); } return ret; } @SuppressWarnings("unused") private static class Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> { public En1 en1; public En2 en2; public Att1 att1; public Att2 att2; public Fk1 fk1; public Fk2 fk2; public Ty ty; /* * public static <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Node<Ty, En1, Sym, * Fk1, Att1, En2, Fk2, Att2> Ty(Ty ty) { Node<Ty, En1, Sym, Fk1, Att1, En2, * Fk2, Att2> n = new Node<>(); n.ty = ty; return n; } */ public static <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> En1( En1 en1) { Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> n = new Node<>(); n.en1 = en1; return n; } public static <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> En2( En2 en2) { Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> n = new Node<>(); n.en2 = en2; return n; } public static <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Att1( Att1 att1) { Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> n = new Node<>(); n.att1 = att1; return n; } public static <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Att2( Att2 att2) { Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> n = new Node<>(); n.att2 = att2; return n; } public static <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Fk1( Fk1 fk1) { Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> n = new Node<>(); n.fk1 = fk1; return n; } public static <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Fk2( Fk2 fk2) { Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> n = new Node<>(); n.fk2 = fk2; return n; } public String toString() { if (en1 != null) { return en1.toString(); } else if (en2 != null) { return en2.toString(); } if (att1 != null) { return att1.toString(); } else if (att2 != null) { return att2.toString(); } if (fk1 != null) { return fk1.toString(); } else if (fk2 != null) { return fk2.toString(); } else if (ty != null) { return ty.toString(); } return Util.anomaly(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((att1 == null) ? 0 : att1.hashCode()); result = prime * result + ((att2 == null) ? 0 : att2.hashCode()); result = prime * result + ((en1 == null) ? 0 : en1.hashCode()); result = prime * result + ((en2 == null) ? 0 : en2.hashCode()); result = prime * result + ((fk1 == null) ? 0 : fk1.hashCode()); result = prime * result + ((fk2 == null) ? 0 : fk2.hashCode()); result = prime * result + ((ty == null) ? 0 : ty.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Node<?, ?, ?, ?, ?, ?, ?, ?> other = (Node<?, ?, ?, ?, ?, ?, ?, ?>) obj; if (att1 == null) { if (other.att1 != null) return false; } else if (!att1.equals(other.att1)) return false; if (att2 == null) { if (other.att2 != null) return false; } else if (!att2.equals(other.att2)) return false; if (en1 == null) { if (other.en1 != null) return false; } else if (!en1.equals(other.en1)) return false; if (en2 == null) { if (other.en2 != null) return false; } else if (!en2.equals(other.en2)) return false; if (fk1 == null) { if (other.fk1 != null) return false; } else if (!fk1.equals(other.fk1)) return false; if (fk2 == null) { if (other.fk2 != null) return false; } else if (!fk2.equals(other.fk2)) return false; if (ty == null) { if (other.ty != null) return false; } else if (!ty.equals(other.ty)) return false; return true; } public Paint color() { if (en1 != null) { return Color.BLACK; } else if (en2 != null) { return Color.GRAY; } if (att1 != null) { return Color.BLUE; } else if (att2 != null) { return Color.CYAN; } if (fk1 != null) { return Color.red; } else if (fk2 != null) { return Color.magenta; } else if (ty != null) { return Color.white; } return Util.anomaly(); } } private <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> JComponent viewMappingGraph( Mapping<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> M) { Graph<Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2>, Chc<Integer, Integer>> sgv = new DirectedSparseMultigraph<>(); if (M.src.size() > maxrows) { JLabel ppp = new JLabel("Size too large, set max_rows"); return ppp; } int i = 0; for (En1 en1 : M.src.ens) { sgv.addVertex(Node.En1(en1)); sgv.addEdge(Chc.inRight(i++), Node.En1(en1), Node.En2(M.ens.get(en1))); } for (En2 en2 : M.dst.ens) { sgv.addVertex(Node.En2(en2)); } // for (Ty ty : M.dst.typeSide.tys) { // sgv.addVertex(Node.Ty(ty)); // } for (Fk1 fk1 : M.src.fks.keySet()) { Pair<En2, List<Fk2>> l = M.fks.get(fk1); sgv.addEdge(Chc.inLeft(i++), Node.En1(M.src.fks.get(fk1).first), Node.Fk1(fk1)); sgv.addEdge(Chc.inLeft(i++), Node.Fk1(fk1), Node.En1(M.src.fks.get(fk1).second)); if (l.second.isEmpty()) { sgv.addEdge(Chc.inRight(i++), Node.Fk1(fk1), Node.En2(l.first)); } else { for (Fk2 fk2 : l.second) { sgv.addEdge(Chc.inRight(i++), Node.Fk1(fk1), Node.Fk2(fk2)); } } } if (showAtts) { for (Att1 att1 : M.src.atts.keySet()) { Triple<Var, En2, Term<Ty, En2, Sym, Fk2, Att2, Void, Void>> l = M.atts.get(att1); sgv.addEdge(Chc.inLeft(i++), Node.En1(M.src.atts.get(att1).first), Node.Att1(att1)); // sgv.addEdge(Chc.inLeft(i++), Node.Att1(att1), // Node.Ty(M.src.atts.get(att1).second)); for (Att2 x : l.third.atts()) { sgv.addEdge(Chc.inRight(i++), Node.Att1(att1), Node.Att2(x)); } // for (Fk2 x : l.third.fks()) { // sgv.addEdge(Chc.inRight(i++), Node.Att1(att1), Node.Fk2(x)); // } /* * boolean b = false; for (Sym x : l.third.syms()) { * sgv.addEdge(Chc.inRight(i++), Node.Att1(att1), * Node.Ty(M.dst.typeSide.syms.get(x).second)); b = true; break; } if (!b) { for * (Pair<Object, Ty> x : l.third.objs()) { sgv.addEdge(Chc.inRight(i++), * Node.Att1(att1), Node.Ty(x.second)); b = true; break; } } */ } } for (Fk2 fk2 : M.dst.fks.keySet()) { sgv.addEdge(Chc.inLeft(i++), Node.En2(M.dst.fks.get(fk2).first), Node.Fk2(fk2)); sgv.addEdge(Chc.inLeft(i++), Node.Fk2(fk2), Node.En2(M.dst.fks.get(fk2).second)); } if (showAtts) { for (Att2 att2 : M.dst.atts.keySet()) { sgv.addEdge(Chc.inLeft(i++), Node.En2(M.dst.atts.get(att2).first), Node.Att2(att2)); // sgv.addEdge(Chc.inLeft(i++), Node.Att2(att2), // Node.Ty(M.dst.atts.get(att2).second)); } } if (sgv.getVertexCount() == 0) { return new JPanel(); } FRLayout<Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2>, Chc<Integer, Integer>> layout = new FRLayout<>(sgv); layout.setSize(new Dimension(600, 400)); VisualizationViewer<Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2>, Chc<Integer, Integer>> vv = new VisualizationViewer<>( layout); Function<Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2>, Paint> vertexPaint = x -> x.color(); DefaultModalGraphMouse<Chc<Ty, En>, Chc<Fk, Att>> gm = new DefaultModalGraphMouse<>(); gm.setMode(Mode.TRANSFORMING); vv.setGraphMouse(gm); gm.setMode(Mode.PICKING); vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint); // vv.getRenderContext().setVert vv.getRenderContext().setEdgeStrokeTransformer(x -> { if (!x.left) { Stroke dashed = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 4 }, 0); return dashed; } return new BasicStroke(); }); Function<Chc<Integer, Integer>, String> et = x -> ""; Function<Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2>, String> vt = x -> x.toString(); vv.getRenderContext().setEdgeLabelTransformer(et); vv.getRenderContext().setVertexLabelTransformer(vt); GraphZoomScrollPane zzz = new GraphZoomScrollPane(vv); JPanel ret = new JPanel(new GridLayout(1, 1)); ret.add(zzz); ret.setBorder(BorderFactory.createEtchedBorder()); vv.getRenderContext().setLabelOffset(16); vv.setBackground(Color.white); return ret; } @SuppressWarnings("rawtypes") private static <Ty, En, Sym, Fk, Att, Gen, Sk> JComponent viewDP(DP<Ty, En, Sym, Fk, Att, Gen, Sk> dp, Function<Unit,Collage> col, AqlJs /* <Ty, Sym> */ js) { CodeTextPanel input = new CodeTextPanel("Input (either equation-in-ctx or term-in-ctx)", ""); CodeTextPanel output = new CodeTextPanel("Output", ""); JButton eq = new JButton("Decide Equation-in-ctx"); //JButton nf = new JButton("Normalize Term-in-ctx"); JButton print = new JButton("Show Info"); JPanel buttonPanel = new JPanel(new GridLayout(1, 2)); buttonPanel.add(eq); //buttonPanel.add(nf); buttonPanel.add(print); Split split = new Split(.5, JSplitPane.VERTICAL_SPLIT); // TODO: aql does not position correctly split.add(input); split.add(output); JPanel main = new JPanel(new BorderLayout()); main.add(split, BorderLayout.CENTER); main.add(buttonPanel, BorderLayout.NORTH); print.addActionListener(x -> output.setText(dp.toStringProver())); eq.addActionListener(x -> { try { if (!input.getText().contains("=")) { return; } final Triple<List<Pair<String, String>>, RawTerm, RawTerm> y = AqlParserFactory.getParser() .parseEq(input.getText()); @SuppressWarnings("unchecked") final Triple<Map<Var, Chc<Ty, En>>, Term<Ty, En, Sym, Fk, Att, Gen, Sk>, Term<Ty, En, Sym, Fk, Att, Gen, Sk>> z = RawTerm .infer2(y.first, y.second, y.third, col.apply(Unit.unit), js); boolean isEq = dp.eq(z.first, z.second, z.third); output.setText(Boolean.toString(isEq)); } catch (Exception ex) { ex.printStackTrace(); output.setText(ex.getMessage()); } }); return main; } private static <Ty, En, Sym, Fk, Att, Gen1, Sk1, Gen2, Sk2, X1, Y1, X2, Y2> JComponent viewTransform( Transform<Ty, En, Sym, Fk, Att, Gen1, Sk1, Gen2, Sk2, X1, Y1, X2, Y2> t) { List<JComponent> list = new LinkedList<>(); List<En> ens = Util.alphabetical(t.src().schema().ens); List<Ty> tys = Util.alphabetical(t.src().schema().typeSide.tys); for (En en : ens) { List<String> header = new LinkedList<>(); header.add("Input"); header.add("Output"); int n = t.src().algebra().size(en); Object[][] data = new Object[n][2]; int i = 0; for (X1 x1 : t.src().algebra().en(en)) { Object[] row = new Object[2]; row[0] = t.src().algebra().printX(en, x1); X2 x2 = t.repr(en, x1); row[1] = t.dst().algebra().printX(en, x2); data[i] = row; i++; } list.add(GuiUtil.makeTable(BorderFactory.createEmptyBorder(), en + " (" + n + ")", data, header.toArray())); } Map<Ty, List<Sk1>> z = Util.newListsFor(t.src().schema().typeSide.tys); t.src().sks().entrySet((sk,ty)-> { z.get(ty).add(sk); }); for (Ty ty : tys) { List<String> header = new LinkedList<>(); header.add("Input"); header.add("Output"); if (!z.containsKey(ty)) { continue; } int n = z.get(ty).size(); Object[][] data = new Object[n][2]; int i = 0; for (Sk1 y1 : z.get(ty)) { Object[] row = new Object[2]; Term<Ty, En, Sym, Fk, Att, Gen1, Sk1> a = Term.Sk(y1); row[0] = a.toString(); // a.toString(t.src().algebra().p, gen_printer) Term<Ty, En, Sym, Fk, Att, Gen2, Sk2> y0 = t.trans(a); row[1] = y0.toString(); data[i] = row; i++; } list.add(GuiUtil.makeTable(BorderFactory.createEmptyBorder(), ty + " (" + n + ")", data, header.toArray())); } return GuiUtil.makeGrid(list); } private <Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> Map<Ty, Object[][]> makeTyTables(Map<Ty, Set<Y>> m, Algebra<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> alg) { Map<Ty, Object[][]> ret = new LinkedHashMap<>(); List<Ty> tys = Util.alphabetical(alg.schema().typeSide.tys); for (Ty ty : tys) { if (!m.containsKey(ty)) { continue; } int n = Integer.min(maxrows, m.get(ty).size()); Object[][] data = new Object[n][1]; int i = 0; for (Y y : Util.alphabetical(m.get(ty))) { Object[] row = new Object[1]; row[0] = alg.printY(ty, y); data[i] = row; i++; if (i == n) { break; } } ret.put(ty, data); } return ret; } public static <Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> Map<En, Pair<List<String>, Object[][]>> makeEnTables( Algebra<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> alg, boolean simplify, int limit, Map<En, Set<Pair<Integer, Integer>>> nulls) { Map<En, Pair<List<String>, Object[][]>> ret = new LinkedHashMap<>(); List<En> ens = Util.alphabetical(alg.schema().ens); if (ens.size() > 32) { ens = ens.subList(0, 31); } Map<X, Integer> referredTo = new THashMap<>(); Map<Y, Integer> referredTo2 = new THashMap<>(); Set<X> set = new LinkedHashSet<>(); Map<En, List<X>> all = new LinkedHashMap<>(); int fresh = 0; for (En en : ens) { // System.out.println(en + "--"); int n = Integer.min(limit, alg.size(en)); List<X> lll = new ArrayList<>(n); int p = 0; for (X xx : alg.en(en)) { // System.out.println(xx); if (p == n) { break; } lll.add(xx); p++; } lll.sort((x, y) -> Util.AlphabeticalComparator.compare(x.toString(), y.toString())); for (X xx : lll) { referredTo.put(xx, fresh++); } all.put(en, lll); } fresh = 0; for (En en : ens) { List<Att> atts0 = Util .alphabetical(alg.schema().attsFrom(en).stream().map((Att x) -> x).collect(Collectors.toList())); List<Fk> fks0 = Util .alphabetical(alg.schema().fksFrom(en).stream().map((Fk x) -> x).collect(Collectors.toList())); List<String> atts0x = atts0.stream().map(Object::toString).collect(Collectors.toList()); List<String> fks0x = fks0.stream().map(Object::toString).collect(Collectors.toList()); List<String> header = Util.<String>append(atts0x, fks0x); //boolean aabr = true; if (header.size() > 8) { header = header.subList(0, 8); //easier on the eye header.add(0, "Row (Cols Abbr)"); } else { header.add(0, "Row"); } int n = Integer.min(limit, alg.size(en)); Object[][] data = new Object[n][]; if (n != 0) { int i = 0; for (X x : all.get(en)) { List<Object> row = new LinkedList<>(); row.add(x); int j = 1; for (Att att0 : atts0) { try { Term<Ty, Void, Sym, Void, Void, Void, Y> t = alg.att(att0, x); for (Y y : t.sks()) { // X z = alg.gen(g); if (!referredTo2.containsKey(y)) { referredTo2.put(y, fresh++); } Set<Pair<Integer, Integer>> v = nulls.get(en); if (v == null) { v = new THashSet<>(); nulls.put(en, v); } // System.out.println("add " + i + " , " + j + " bc " + y); v.add(new Pair<>(i, j)); // set.add(z); } row.add(t); } catch (Exception ex) { ex.printStackTrace(); row.add(Term.Var(Var.Var("ERR"))); } j++; } for (Fk fk0 : fks0) { X y = alg.fk(fk0, x); if (!referredTo.containsKey(y)) { referredTo.put(y, fresh++); } set.add(y); row.add(y); } data[i] = row.toArray(); i++; if (i == n) { break; } } } //System.out.println("RET " + en + " " + header + " data " + Arrays.deepToString(data)); ret.put(en, new Pair<>(header, data)); } if (!simplify) { BiFunction<En, Object, Object> f = (y, x) -> referredTo.get(x); BiFunction<Ty, Object, Object> g = (y, xx) -> ((Term<Ty, Void, Sym, Void, Void, Void, Y>) xx) .mapGenSk(x -> x, x -> "?" + referredTo2.get(x)).toString(); enTableSimpl(alg, ret, f, g, f); return ret; } BiFunction<En, Object, Object> a = (y, x) -> alg.printX(y, (X) x); BiFunction<Ty, Object, Object> b = (y, x) -> ((Term<Ty, Void, Sym, Void, Void, Void, Y>) x) .toString(z -> alg.printY(alg.talg().sks.get(z), z).toString(), Util.voidFn()); enTableSimpl(alg, ret, a, b, a); return ret; } private synchronized static <Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> void enTableSimpl( Algebra<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> alg, Map<En, Pair<List<String>, Object[][]>> ret, BiFunction<En, Object, Object> f, BiFunction<Ty, Object, Object> g, BiFunction<En, Object, Object> h) { for (En en : ret.keySet()) { Object[][] arr = ret.get(en).second; //System.out.println("en(before) " + en + " " + Arrays.deepToString(arr)); for (int i = 0; i < arr.length; i++) { Object[] o = arr[i]; int j = 0; o[0] = f.apply(en, o[0]); for (Att att : alg.schema().attsFrom(en)) { Ty e = alg.schema().atts.get(att).second; o[1 + j] = g.apply(e, o[1 + j]); j++; } for (Fk fk : alg.schema().fksFrom(en)) { En e = alg.schema().fks.get(fk).second; // System.out.println("On fk " + fk + " tgt is " + e + " and o " + Arrays.deepToString(o)); o[1 + j] = h.apply(e, o[1 + j]); j++; } } //System.out.println("en(after) " + en + " " + Arrays.deepToString(arr)); } } private <X, Y> Component viewAlgebra(float z, Algebra<catdata.aql.exp.Ty, catdata.aql.exp.En, catdata.aql.exp.Sym, catdata.aql.exp.Fk, catdata.aql.exp.Att, catdata.aql.exp.Gen, catdata.aql.exp.Sk, X, Y> algebra) { JPanel top = new JPanel(new GridBagLayout()); top.setBorder(BorderFactory.createEmptyBorder()); JCheckBox simp = new JCheckBox("", false); int a = Integer.min(maxrows, algebra.sizeOfBiggest()); JSlider sl = new JSlider(0, a, Integer.min(32, a)); JLabel limit = new JLabel("Row limit:", JLabel.RIGHT); JLabel lbl = new JLabel("Provenance:", JLabel.RIGHT); JLabel ids = new JLabel( " " + algebra.size() + " IDs, " + algebra.talg().sks.size() + " nulls, " + z + " seconds.", JLabel.LEFT); GridBagConstraints gbc = new GridBagConstraints(); gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.WEST; top.add(ids, gbc); gbc.anchor = GridBagConstraints.EAST; top.add(lbl, gbc); gbc.anchor = GridBagConstraints.WEST; top.add(simp, gbc); gbc.anchor = GridBagConstraints.EAST; top.add(limit, gbc); gbc.anchor = GridBagConstraints.WEST; top.add(sl, gbc); JPanel out = new JPanel(new BorderLayout()); out.setBorder(BorderFactory.createEtchedBorder()); Map<Pair<Boolean, Integer>, JScrollPane> cache = new THashMap<>(); viewAlgebraHelper(top, algebra, out, simp, sl, cache); sl.addChangeListener((x) -> { viewAlgebraHelper(top, algebra, out, simp, sl, cache); }); simp.addChangeListener((x) -> { viewAlgebraHelper(top, algebra, out, simp, sl, cache); }); return out; } private <X, Y> void viewAlgebraHelper(JComponent top, Algebra<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> algebra, JPanel out, JCheckBox simp, JSlider sl, Map<Pair<Boolean, Integer>, JScrollPane> cache) { boolean b = simp.isSelected(); int l = sl.getValue(); Pair<Boolean, Integer> p = new Pair<>(b, l); JScrollPane jsp = cache.get(p); if (jsp == null) { jsp = makeList2(algebra, b, l); cache.put(p, jsp); } out.removeAll(); out.add(jsp, BorderLayout.CENTER); out.add(top, BorderLayout.SOUTH); out.revalidate(); out.repaint(); } public static <X> List<String> toString(Collection<X> list) { List<String> l = new ArrayList<>(list.size()); for (X x : list) { l.add(x.toString()); } return l; } private <X, Y> JScrollPane makeList2( Algebra<catdata.aql.exp.Ty, catdata.aql.exp.En, catdata.aql.exp.Sym, catdata.aql.exp.Fk, catdata.aql.exp.Att, catdata.aql.exp.Gen, catdata.aql.exp.Sk, X, Y> algebra, boolean b, int l) { List<JComponent> list = makeList(algebra, b, l); JPanel c = new JPanel(); c.setLayout(new BoxLayout(c, BoxLayout.PAGE_AXIS)); for (JComponent x : list) { x.setAlignmentX(Component.LEFT_ALIGNMENT); x.setMinimumSize(x.getPreferredSize()); c.add(x); } JPanel p = new JPanel(new GridLayout(1, 1)); p.add(c); JScrollPane jsp = new JScrollPane(p); c.setBorder(BorderFactory.createEmptyBorder()); p.setBorder(BorderFactory.createEmptyBorder()); jsp.setBorder(BorderFactory.createEmptyBorder()); return jsp; } private <X, Y> List<JComponent> makeList(Algebra<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> algebra, boolean simplify, int limit) { List<JComponent> list = new LinkedList<>(); Map<En, Set<Pair<Integer, Integer>>> nulls = new THashMap<>(); Map<En, Pair<List<String>, Object[][]>> entables = makeEnTables(algebra, simplify, limit, nulls); for (En en : entables.keySet()) { Pair<List<String>, Object[][]> x = entables.get(en); String str; if (x.second.length < algebra.size(en)) { str = en + " (" + x.second.length + " of " + algebra.size(en) + ")"; } else { str = en + " (" + x.second.length + ")"; } JComponent p = GuiUtil.makeBoldHeaderTable(nulls.get(en), toString(algebra.schema().attsFrom(en)), BorderFactory.createEmptyBorder(), str, x.second, x.first.toArray(new String[x.first.size()])); list.add(p); } List<String> header = Collections.singletonList("Row"); if (simplify) { Map<Ty, Set<Y>> m = Util.revS(algebra.talg().sks); Map<Ty, Object[][]> tytables = makeTyTables(m, algebra); for (Ty ty : tytables.keySet()) { if (!m.containsKey(ty)) { continue; } Object[][] arr = tytables.get(ty); String str; if (arr.length < m.get(ty).size()) { str = ty + " (" + arr.length + " of " + m.get(ty).size() + ")"; } else { str = ty + " (" + arr.length + ")"; } JPanel z = GuiUtil.makeTable(BorderFactory.createEmptyBorder(), str, arr, header.toArray()); list.add(z); } } if (entables.size() != algebra.schema().ens.size()) { list.add(new JLabel("Display suppressed; showing only some tables")); } return list; } @SuppressWarnings("unchecked") @Override public <T, C> Unit visit(String k, JTabbedPane ret, TypeSide<T, C> T) { ret.addTab("DP", viewDP(T.semantics(), x->T.collage(), T.js)); ret.addTab("Model", makeHomSet((TypeSide<Ty, Sym>) T)); return Unit.unit; } private <En, Sym, Fk, Att, Gen, Sk, X, Y> JPanel makeHomSet(Instance<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> T) { JPanel ret = new JPanel(new GridLayout(1, 1)); JSplitPane pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); ret.add(pane); JPanel top = new JPanel(new GridLayout(3, 1)); JPanel p1 = new JPanel(); JPanel p2 = new JPanel(); JPanel p3 = new JPanel(); JTextField dst = new JTextField(32); p2.add(new JLabel("Enter a type: ")); p2.add(dst); CodeTextPanel bot = new CodeTextPanel(BorderFactory.createEtchedBorder(), "Result", ""); JButton go = new JButton("Saturate"); go.addActionListener(x -> { String l = dst.getText().trim(); if (l.isEmpty()) { return; } Ty r0 = Ty.Ty(dst.getText().trim()); Ty r = r0; Runnable runnable = () -> { try { Set<Term<Ty, En, Sym, Fk, Att, Gen, Sk>> z = T.getModel().get(r); if (z.isEmpty()) { bot.setText("empty"); } else { bot.setText(Util.sep(z, "\n\n")); } } catch (Exception ex) { ex.printStackTrace(); bot.setText(ex.getMessage()); } // finished = true; }; Thread t = new Thread(runnable); try { t.start(); t.join(10000); // TODO aql t.stop(); if (bot.getText().equals("")) { bot.setText("Timeout (10s)"); } } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException("Timout (10s)"); } }); p3.add(go); top.add(p1); top.add(p2); top.add(p3); pane.add(top); pane.add(bot); return ret; } private JPanel makeHomSet(TypeSide<Ty, Sym> T) { JPanel ret = new JPanel(new GridLayout(1, 1)); JSplitPane pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); ret.add(pane); JPanel top = new JPanel(new GridLayout(3, 1)); JPanel p1 = new JPanel(); JPanel p2 = new JPanel(); JPanel p3 = new JPanel(); JTextField src = new JTextField(32); JTextField dst = new JTextField(32); p1.add(new JLabel("Source Types (sep by ,):")); p1.add(src); p2.add(new JLabel("Target Type:")); p2.add(dst); CodeTextPanel bot = new CodeTextPanel(BorderFactory.createEtchedBorder(), "Result", ""); JButton go = new JButton("Compute hom set"); go.addActionListener(x -> { String b = dst.getText().trim(); if (b.isEmpty()) { return; } String[] l = src.getText().split(","); Ty r = Ty.Ty(b); List<Ty> l0 = new LinkedList<>(); for (String j : l) { String j2 = j.trim(); if (!j2.isEmpty()) { l0.add(Ty.Ty(j2)); } } Runnable runnable = () -> { try { Set<Term<Ty, Void, Sym, Void, Void, Void, Void>> z = T.hom(l0, r); // Collection<Pair<OplCtx<S, V>, OplTerm<C, V>>> z = // kb.hom0(Thread.currentThread(), l0, r); // List<String> u = z.stream().map(o -> OplTerm.strip(o.first + " |- " + // OplToKB.convert(o.second))).collect(Collectors.toList()); if (z.isEmpty()) { bot.setText("empty"); } else { bot.setText(Util.sep(z, "\n\n")); } } catch (Exception ex) { ex.printStackTrace(); bot.setText(ex.getMessage()); } // finished = true; }; Thread t = new Thread(runnable); try { t.start(); t.join(10000); // TODO aql t.stop(); if (bot.getText().equals("")) { bot.setText("Timeout (10s)"); } } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException("Timout (10s)"); } }); p3.add(go); top.add(p1); top.add(p2); top.add(p3); pane.add(top); pane.add(bot); return ret; } @SuppressWarnings("hiding") @Override public <Ty, En, Sym, Fk, Att> Unit visit(String k, JTabbedPane ret, Schema<Ty, En, Sym, Fk, Att> S) { ret.addTab("Graph", viewSchema(S)); // ret.add("Graph2", viewSchemaAlt(S)); ret.addTab("DP", viewDP(S.dp(), x->S.collage(), S.typeSide.js)); // ret.add(new CodeTextPanel("", schema.collage().toString()), "Temp"); ret.add("Acyclic?", acyclicPanel(S)); return Unit.unit; } private <Ty, En, Sym, Fk, Att> Component acyclicPanel(Schema<Ty, En, Sym, Fk, Att> s) { JPanel p = new JPanel(); JButton b = new JButton("Acyclic?"); p.add(b); b.addActionListener(x -> { String acyclic = Boolean.toString(s.acyclic()); p.remove(b); p.add(new JLabel(acyclic)); p.revalidate(); p.repaint(); }); return p; } @SuppressWarnings("unchecked") @Override public <Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> Unit visit(String k, JTabbedPane ret, Instance<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> I) { ret.addTab("Tables", viewAlgebra(env.performance.get(k), (Algebra<catdata.aql.exp.Ty, catdata.aql.exp.En, catdata.aql.exp.Sym, catdata.aql.exp.Fk, catdata.aql.exp.Att, catdata.aql.exp.Gen, catdata.aql.exp.Sk, X, Y>) I .algebra())); if (I.algebra().talg().sks.size() < 1024) { ret.addTab("TyAlg", new CodeTextPanel("", I.algebra().talgToString())); ret.addTab("Hom-sets", makeHomSet((Instance<catdata.aql.exp.Ty, En, Sym, Fk, Att, Gen, Sk, X, Y>) I)); if (I.size() < 1024) { ret.addTab("DP", viewDP(I.dp(), x->I.collage(), I.schema().typeSide.js)); } else { ret.addTab("DP", new CodeTextPanel("", "Suppressed, size " + I.algebra().talg().sks.size() + ".")); } } else { ret.addTab("TyAlg", new CodeTextPanel("", "Suppressed, size " + I.algebra().talg().sks.size() + ".")); ret.addTab("Hom-sets", new CodeTextPanel("", "Suppressed, size " + I.algebra().talg().sks.size() + ".")); ret.addTab("DP", new CodeTextPanel("", "Suppressed, size " + I.algebra().talg().sks.size() + ".")); } // ret.addTab("TPTP", new CodeTextPanel("", I.tptp())); return Unit.unit; } @SuppressWarnings("hiding") @Override public <Ty, En, Sym, Fk, Att, Gen1, Sk1, Gen2, Sk2, X1, Y1, X2, Y2> Unit visit(String k, JTabbedPane ret, Transform<Ty, En, Sym, Fk, Att, Gen1, Sk1, Gen2, Sk2, X1, Y1, X2, Y2> h) { ret.addTab("Tables", viewTransform(h)); return Unit.unit; } @Override public Unit visit(String k, JTabbedPane ret, Pragma P) { return Unit.unit; } @Override public Unit visit(String k, JTabbedPane ret, Comment P) { return Unit.unit; } @Override public Unit visit(String k, JTabbedPane ret, Mor P) { return Unit.unit; } @SuppressWarnings("hiding") @Override public <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Unit visit(String k, JTabbedPane ret, Query<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Q) { try { Q = Q.unnest(); JComponent comp = new CodeTextPanel("", Q.toString()); ret.addTab("Unnest", comp); } catch (Exception ex) { ex.printStackTrace(); ret.addTab("Unnest Exn", new CodeTextPanel("Exception", ex.getMessage())); return Unit.unit; } try { JComponent comp = makeQueryPanel(Q); ret.addTab("SQL", comp); } catch (Exception ex) { ex.printStackTrace(); ret.addTab("SQL Exn", new CodeTextPanel("Exception", ex.getMessage())); } return Unit.unit; } public <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> JComponent makeQueryPanel( Query<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> q) { try { List<String> l = q.toSQLViews("", "", "id", "varchar", "\"").first; return new CodeTextPanel("", Util.sep(l, ";\n\n")); } catch (Exception ex) { // ex.printStackTrace(); return new CodeTextPanel("SQL exn", ex.getMessage()); } } @SuppressWarnings("hiding") @Override public <Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> Unit visit(String k, JTabbedPane ret, Mapping<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2> M) { // ret.addTab("Translate", viewMorphism(M.semantics(), M.src.typeSide.js)); ret.addTab("Graph", viewMappingGraph(M)); ret.addTab("Collage", new CodeTextPanel("", M.collage().toString())); return Unit.unit; } @Override public <N, e> Unit visit(String k, JTabbedPane ret, catdata.aql.Graph<N, e> G) { ret.add("Graph", viewGraph(G.dmg)); return Unit.unit; } @Override public <N> Unit visit(String k, JTabbedPane arg, ColimitSchema<N> S) throws RuntimeException { return Unit.unit; } @SuppressWarnings("hiding") @Override public Unit visit(String k, JTabbedPane arg, Constraints S) throws RuntimeException { return Unit.unit; } @Override public Unit visit(String k, JTabbedPane pane, ApgTypeside t) throws RuntimeException { Object[][] rowData = new Object[t.Bs.size()][3]; Object[] colNames = new Object[2]; colNames[0] = "Base Type"; colNames[1] = "Java Class"; int j = 0; for (Entry<String, Pair<Class<?>, java.util.function.Function<String, Object>>> lt : t.Bs.entrySet()) { rowData[j][0] = lt.getKey(); rowData[j][1] = lt.getValue().first.getName(); j++; } JPanel x = GuiUtil.makeTable(BorderFactory.createEmptyBorder(), null, rowData, colNames); JPanel c = new JPanel(); c.setLayout(new BoxLayout(c, BoxLayout.PAGE_AXIS)); x.setAlignmentX(Component.LEFT_ALIGNMENT); x.setMinimumSize(x.getPreferredSize()); c.add(x); JPanel p = new JPanel(new GridLayout(1, 1)); p.add(c); JScrollPane jsp = new JScrollPane(p); c.setBorder(BorderFactory.createEmptyBorder()); p.setBorder(BorderFactory.createEmptyBorder()); jsp.setBorder(BorderFactory.createEmptyBorder()); pane.addTab("Table", p); return Unit.unit; } @Override public <L, e> Unit visit(String k, JTabbedPane pane, ApgInstance<L, e> G) throws RuntimeException { apgInst0(pane, G); apgInst1(pane, G); /* Graph<Pair<String,Object>, Pair<String, Integer>> sgv = new DirectedSparseMultigraph<>(); int i = 0; for (En1 en1 : G.) { sgv.addVertex(Node.En1(en1)); sgv.addEdge(Chc.inRight(i++), Node.En1(en1), Node.En2(M.ens.get(en1))); } for (En2 en2 : M.dst.ens) { sgv.addVertex(Node.En2(en2)); } // for (Ty ty : M.dst.typeSide.tys) { // sgv.addVertex(Node.Ty(ty)); // } for (Fk1 fk1 : M.src.fks.keySet()) { Pair<En2, List<Fk2>> l = M.fks.get(fk1); sgv.addEdge(Chc.inLeft(i++), Node.En1(M.src.fks.get(fk1).first), Node.Fk1(fk1)); sgv.addEdge(Chc.inLeft(i++), Node.Fk1(fk1), Node.En1(M.src.fks.get(fk1).second)); if (l.second.isEmpty()) { sgv.addEdge(Chc.inRight(i++), Node.Fk1(fk1), Node.En2(l.first)); } else { for (Fk2 fk2 : l.second) { sgv.addEdge(Chc.inRight(i++), Node.Fk1(fk1), Node.Fk2(fk2)); } } } if (showAtts) { for (Att1 att1 : M.src.atts.keySet()) { Triple<Var, En2, Term<Ty, En2, Sym, Fk2, Att2, Void, Void>> l = M.atts.get(att1); sgv.addEdge(Chc.inLeft(i++), Node.En1(M.src.atts.get(att1).first), Node.Att1(att1)); // sgv.addEdge(Chc.inLeft(i++), Node.Att1(att1), // Node.Ty(M.src.atts.get(att1).second)); for (Att2 x : l.third.atts()) { sgv.addEdge(Chc.inRight(i++), Node.Att1(att1), Node.Att2(x)); } // for (Fk2 x : l.third.fks()) { // sgv.addEdge(Chc.inRight(i++), Node.Att1(att1), Node.Fk2(x)); // } /* * boolean b = false; for (Sym x : l.third.syms()) { * sgv.addEdge(Chc.inRight(i++), Node.Att1(att1), * Node.Ty(M.dst.typeSide.syms.get(x).second)); b = true; break; } if (!b) { for * (Pair<Object, Ty> x : l.third.objs()) { sgv.addEdge(Chc.inRight(i++), * Node.Att1(att1), Node.Ty(x.second)); b = true; break; } } */ /* } } for (Fk2 fk2 : M.dst.fks.keySet()) { sgv.addEdge(Chc.inLeft(i++), Node.En2(M.dst.fks.get(fk2).first), Node.Fk2(fk2)); sgv.addEdge(Chc.inLeft(i++), Node.Fk2(fk2), Node.En2(M.dst.fks.get(fk2).second)); } if (showAtts) { for (Att2 att2 : M.dst.atts.keySet()) { sgv.addEdge(Chc.inLeft(i++), Node.En2(M.dst.atts.get(att2).first), Node.Att2(att2)); // sgv.addEdge(Chc.inLeft(i++), Node.Att2(att2), // Node.Ty(M.dst.atts.get(att2).second)); } } if (sgv.getVertexCount() == 0) { return new JPanel(); } FRLayout<Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2>, Chc<Integer, Integer>> layout = new FRLayout<>(sgv); layout.setSize(new Dimension(600, 400)); VisualizationViewer<Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2>, Chc<Integer, Integer>> vv = new VisualizationViewer<>( layout); Function<Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2>, Paint> vertexPaint = x -> x.color(); DefaultModalGraphMouse<Chc<Ty, En>, Chc<Fk, Att>> gm = new DefaultModalGraphMouse<>(); gm.setMode(Mode.TRANSFORMING); vv.setGraphMouse(gm); gm.setMode(Mode.PICKING); vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint); // vv.getRenderContext().setVert vv.getRenderContext().setEdgeStrokeTransformer(x -> { if (!x.left) { Stroke dashed = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 4 }, 0); return dashed; } return new BasicStroke(); }); Function<Chc<Integer, Integer>, String> et = x -> ""; Function<Node<Ty, En1, Sym, Fk1, Att1, En2, Fk2, Att2>, String> vt = x -> x.toString(); vv.getRenderContext().setEdgeLabelTransformer(et); vv.getRenderContext().setVertexLabelTransformer(vt); GraphZoomScrollPane zzz = new GraphZoomScrollPane(vv); JPanel ret = new JPanel(new GridLayout(1, 1)); ret.add(zzz); ret.setBorder(BorderFactory.createEtchedBorder()); vv.getRenderContext().setLabelOffset(16); vv.setBackground(Color.white); return ret; */ return Unit.unit; } private <e, L> void apgInst0(JTabbedPane pane, ApgInstance<L, e> G) { List<JComponent> list = new LinkedList<>(); Object[][] rowData; Object[] colNames; rowData = new Object[G.Es.size()][3]; colNames = new Object[3]; colNames[0] = "Element"; colNames[1] = "Label"; colNames[2] = "Value"; int j = 0; for (Entry<e, Pair<L, ApgTerm<L, e>>> lt : G.Es.entrySet()) { rowData[j][0] = lt.getKey(); rowData[j][1] = lt.getValue().first; rowData[j][2] = lt.getValue().second; j++; } list.add(GuiUtil.makeTable(BorderFactory.createEmptyBorder(), "Data", rowData, colNames)); JPanel c = new JPanel(); c.setLayout(new BoxLayout(c, BoxLayout.PAGE_AXIS)); for (JComponent x : list) { x.setAlignmentX(Component.LEFT_ALIGNMENT); x.setMinimumSize(x.getPreferredSize()); c.add(x); } JPanel p = new JPanel(new GridLayout(1, 1)); p.add(c); JScrollPane jsp = new JScrollPane(p); c.setBorder(BorderFactory.createEmptyBorder()); p.setBorder(BorderFactory.createEmptyBorder()); jsp.setBorder(BorderFactory.createEmptyBorder()); pane.addTab("Tables", p); } private <e, L> void apgInst1(JTabbedPane pane, ApgInstance<L, e> G) { List<JComponent> list = new LinkedList<>(); Map<L, Set<e>> map = Util.revS(Util.map(G.Es, (w,v)->new Pair<>(w,v.first))); for (Entry<L, ApgTy<L>> lt : G.Ls.entrySet()) { ApgTy<L> t = lt.getValue(); L l = lt.getKey(); Object[][] rowData; Object[] colNames; if (t.m != null && t.all) { colNames = new Object[t.m.size() + 1]; colNames[0] = l; int i = 1; for (Entry<String, ApgTy<L>> x : t.m.entrySet()) { colNames[i++] = x.getKey() + " : " + x.getValue(); } Set<e> set = map.get(l); if (set == null) { throw new RuntimeException("Anomaly, please report: missing label: " + l + ", available: " + map.keySet()); } rowData = new Object[set.size()][i]; int j = 0; for (e elem : set) { ApgTerm<L, e> w = G.Es.get(elem).second; rowData[j][0] = elem; int u = 1; for (String f : t.m.keySet()) { rowData[j][u++] = w.fields.get(f); } j++; } } else { colNames = new Object[2]; colNames[0] = l; colNames[1] = t.toString(); Set<e> set = map.get(l); rowData = new Object[set.size()][2]; int j = 0; for (e elem : set) { ApgTerm<L, e> w = G.Es.get(elem).second; rowData[j][0] = elem; rowData[j][1] = w; j++; } } list.add(GuiUtil.makeTable(BorderFactory.createEmptyBorder(), null, rowData, colNames)); } JPanel c = new JPanel(); c.setLayout(new BoxLayout(c, BoxLayout.PAGE_AXIS)); for (JComponent x : list) { x.setAlignmentX(Component.LEFT_ALIGNMENT); x.setMinimumSize(x.getPreferredSize()); c.add(x); } JPanel p = new JPanel(new GridLayout(1, 1)); p.add(c); JScrollPane jsp = new JScrollPane(p); c.setBorder(BorderFactory.createEmptyBorder()); p.setBorder(BorderFactory.createEmptyBorder()); jsp.setBorder(BorderFactory.createEmptyBorder()); pane.addTab("Labels", p); } @Override public <l1, e1, l2, e2> Unit visit(String k, JTabbedPane pane, ApgTransform<l1, e1, l2, e2> t) throws RuntimeException { List<JComponent> list = new LinkedList<>(); Object[][] rowData = new Object[t.lMap.size()][2]; Object[] colNames = new Object[2]; colNames[0] = "Input Label"; colNames[1] = "Output Label"; int j = 0; for (Entry<l1, l2> lt : t.lMap.entrySet()) { rowData[j][0] = lt.getKey(); rowData[j][1] = lt.getValue(); j++; } list.add(GuiUtil.makeTable(BorderFactory.createEmptyBorder(), "Schema", rowData, colNames)); rowData = new Object[t.eMap.size()][2]; colNames = new Object[2]; colNames[0] = "Input Element"; colNames[1] = "Output Element"; j = 0; for (Entry<e1, e2> lt : t.eMap.entrySet()) { rowData[j][0] = lt.getKey(); rowData[j][1] = lt.getValue(); j++; } list.add(GuiUtil.makeTable(BorderFactory.createEmptyBorder(), "Data", rowData, colNames)); JPanel c = new JPanel(); c.setLayout(new BoxLayout(c, BoxLayout.PAGE_AXIS)); for (JComponent x : list) { x.setAlignmentX(Component.LEFT_ALIGNMENT); x.setMinimumSize(x.getPreferredSize()); c.add(x); } JPanel p = new JPanel(new GridLayout(1, 1)); p.add(c); JScrollPane jsp = new JScrollPane(p); c.setBorder(BorderFactory.createEmptyBorder()); p.setBorder(BorderFactory.createEmptyBorder()); jsp.setBorder(BorderFactory.createEmptyBorder()); pane.addTab("Labels", p); return Unit.unit; } private <L> void apgSch0(JTabbedPane pane, ApgSchema<L> Ls) { List<JComponent> list = new LinkedList<>(); Object[][] rowData = new Object[Ls.size()][2]; Object[] colNames = new Object[2]; colNames[0] = "Label"; colNames[1] = "Type"; int j = 0; for (Entry<L, ApgTy<L>> lt : Ls.entrySet()) { rowData[j][0] = lt.getKey(); rowData[j][1] = lt.getValue(); j++; } list.add(GuiUtil.makeTable(BorderFactory.createEmptyBorder(), "Schema", rowData, colNames)); JPanel c = new JPanel(); c.setLayout(new BoxLayout(c, BoxLayout.PAGE_AXIS)); for (JComponent x : list) { x.setAlignmentX(Component.LEFT_ALIGNMENT); x.setMinimumSize(x.getPreferredSize()); c.add(x); } JPanel p = new JPanel(new GridLayout(1, 1)); p.add(c); JScrollPane jsp = new JScrollPane(p); c.setBorder(BorderFactory.createEmptyBorder()); p.setBorder(BorderFactory.createEmptyBorder()); jsp.setBorder(BorderFactory.createEmptyBorder()); pane.addTab("Tables", p); } @Override public <L> Unit visit(String k, JTabbedPane arg, ApgSchema<L> t) throws RuntimeException { apgSch0(arg, t); return Unit.unit; } @Override public <L1, L2> Unit visit(String k, JTabbedPane arg, ApgMapping<L1, L2> t) throws RuntimeException { // TODO Auto-generated method stub return Unit.unit; } /////////////////////////////////////////////////////// }