package org.basex.io.serial; import static org.basex.core.Text.*; import org.basex.data.ExprInfo; import org.basex.query.expr.And; import org.basex.query.expr.Arith; import org.basex.query.expr.CFrag; import org.basex.query.expr.Cast; import org.basex.query.expr.Catch; import org.basex.query.expr.CmpG; import org.basex.query.expr.CmpN; import org.basex.query.expr.CmpR; import org.basex.query.expr.CmpV; import org.basex.query.expr.Context; import org.basex.query.expr.Except; import org.basex.query.expr.If; import org.basex.query.expr.IndexAccess; import org.basex.query.expr.InterSect; import org.basex.query.expr.List; import org.basex.query.expr.Or; import org.basex.query.expr.Pos; import org.basex.query.expr.Preds; import org.basex.query.expr.Quantifier; import org.basex.query.expr.Range; import org.basex.query.expr.RangeAccess; import org.basex.query.expr.Root; import org.basex.query.expr.Try; import org.basex.query.expr.Union; import org.basex.query.expr.VarRef; import org.basex.query.flwor.FLWR; import org.basex.query.flwor.ForLet; import org.basex.query.flwor.GFLWOR; import org.basex.query.flwor.Order; import org.basex.query.flwor.OrderBy; import org.basex.query.flwor.OrderByExpr; import org.basex.query.ft.FTContains; import org.basex.query.ft.FTExpr; import org.basex.query.ft.FTIndexAccess; import org.basex.query.func.StandardFunc; import org.basex.query.func.UserFunc; import org.basex.query.func.UserFuncCall; import org.basex.query.func.UserFuncs; import org.basex.query.path.AxisStep; import org.basex.query.path.Path; import org.basex.query.util.Var; import org.basex.query.util.VarStack; import org.basex.util.Util; /** * This class contains formatting information for the DOT output. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ final class DOTData { /** Font. */ private static final String FONT = "Tahoma"; //"Charter BT"; /** Node entry. */ static final String HEADER = "digraph BaseXAlgebra {" + NL + "node [shape=box style=bold width=0 height=0];" + NL + "node [fontsize=12 fontname=\"" + FONT + "\"];"; /** Node entry. */ static final String FOOTER = "}"; /** Node entry. */ static final String DOTNODE = "node% [label=\"%\" color=\"#%\"];"; /** Link entry. */ static final String DOTLINK = "node% -> node%;"; /** Node entry. */ static final String DOTATTR = "\\n%: %"; /** Link entry. */ static final String ELEM1 = "303030"; /** Link entry. */ static final String ELEM2 = "909090"; /** Link entry. */ static final String ITEM = "3366CC"; /** Link entry. */ static final String TEXT = "6666FF"; /** Link entry. */ static final String COMM = "3366FF"; /** Link entry. */ static final String PI = "3399FF"; /** Private constructors. */ private DOTData() { } /** Hash map, caching colors for expressions. */ private static final Object[][] COLORS = { // blue { "6666FF", "Item" }, { "6666FF", "sequence" }, // violet { "9933FF", CFrag.class }, { "9933CC", And.class }, { "9933CC", Or.class }, { "9933CC", Union.class }, { "9933CC", InterSect.class }, { "9933CC", Except.class }, { "9933CC", "Then" }, { "9933CC", "Else" }, // pink { "CC3399", If.class }, { "CC3399", Quantifier.class }, { "CC3399", "Where" }, { "CC3399", Order.class }, { "CC6699", OrderBy.class }, // red { "FF3333", Arith.class }, { "FF3333", CmpG.class }, { "FF3333", CmpN.class }, { "FF3333", CmpV.class }, { "FF3333", CmpR.class }, { "FF3333", Pos.class }, { "FF3333", FTContains.class }, { "FF6666", FTExpr.class }, { "FF6666", Try.class }, { "FF6666", Catch.class }, // orange { "AA9988", UserFunc.class }, { "776655", UserFuncs.class }, { "CC6600", Path.class }, { "FF9900", Preds.class }, // green { "009900", GFLWOR.class }, { "339933", VarStack.class }, { "33CC33", ForLet.class }, { "33CC33", List.class }, { "33CC33", Range.class }, { "33CC33", Context.class }, { "33CC33", "Return" }, { "66CC66", Var.class }, { "66CC66", Cast.class }, // cyan { "009999", UserFuncCall.class }, { "00BBBB", StandardFunc.class }, { "00BBBB", Root.class }, { "00BBBB", VarRef.class }, { "00BBBB", IndexAccess.class }, { "00BBBB", RangeAccess.class }, { "00BBBB", FTIndexAccess.class }, }; /** Hash map, caching expression names. */ private static final Object[][] NAMES = { { "Calculation", Arith.class }, { "Comparison", CmpG.class }, { "Comparison", CmpN.class }, { "Comparison", CmpV.class }, { "Comparison", CmpR.class }, { "FLWOR", FLWR.class }, { "Declaration", UserFunc.class }, { "Function", StandardFunc.class }, { null, Path.class }, { "Step", AxisStep.class }, { "Variables", VarStack.class }, { "OrderBy", OrderByExpr.class }, { "operator", "op" }, }; /** * Returns the color for the specified expression, or {@code null}. * @param e expression * @return color */ static String color(final ExprInfo e) { for(final Object[] o : COLORS) { if(o[1] instanceof Class<?> && ((Class<?>) o[1]).isInstance(e)) return o[0].toString(); } return null; } /** * Returns the color for the specified string, or {@code null}. * @param s string string * @return color */ static String color(final String s) { for(final Object[] o : COLORS) { if(o[1] instanceof String && s.equals(o[1].toString())) { return o[0].toString(); } } return null; } /** * Returns the node name for the specified expression. * @param e expression * @return name */ static String name(final ExprInfo e) { final String name = e.info(); for(final Object[] o : NAMES) { if(!(o[1] instanceof Class<?>)) continue; final Class<?> c = (Class<?>) o[1]; if(!c.isInstance(e)) continue; return o[0] != null ? o[0].toString() : Util.name(c); } return name; } /** * Returns the node name for the specified string. * @param s string * @return name */ static String name(final String s) { for(final Object[] o : NAMES) { if(!(o[1] instanceof String)) continue; final String c = (String) o[1]; if(c.equals(s)) return o[0].toString(); } return s; } }