DBVIEW
|
00001 /* 00002 DbView - Graph Visualization 00003 Copyright (C) 2012 Denis BEURIVE 00004 00005 This program is free software: you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation, either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 /** 00020 * @author Denis Beurive 00021 */ 00022 00023 package org.dbview.databaseExporters.dot; 00024 00025 import java.util.*; 00026 import org.dbview.addons.output.table.utils.dot.*; 00027 import org.dbview.db.structure.Database; 00028 import org.dbview.db.structure.Field; 00029 import org.dbview.db.structure.Table; 00030 import org.dbview.utils.dot.*; 00031 import org.dbview.utils.dot.label.*; 00032 00033 /** 00034 * This class implements the export to DOT, with an intermediate level of details. 00035 * @see AbstractDatabaseExporter 00036 * @author Denis Beurive 00037 */ 00038 public class DotMedium extends AbstractDatabaseExporter 00039 { 00040 /** 00041 * Create the exporter. 00042 * @param in_tables List of tables to export. 00043 * @param in_db Handle to the database. 00044 */ 00045 public DotMedium(ArrayList<Table> in_tables, Database in_db) 00046 { 00047 super(in_tables, in_db); 00048 } 00049 00050 /** 00051 * This method exports the given tables, from the given database. 00052 * @param in_options Options. 00053 * Options may be: 00054 * <ul> 00055 * <li>"layout"</li> 00056 * </ul> 00057 * @return The method returns a string that represents the DOT representation. 00058 * @throws Exception 00059 */ 00060 public String export(Hashtable<String, Object> in_options) throws Exception 00061 { 00062 DiGraph digraph = new DiGraph(); 00063 if (null != in_options) 00064 { 00065 if (in_options.containsKey("layout")) 00066 digraph.setRankdir((String)in_options.get("layout")); 00067 } 00068 00069 // ------------------------------------------------------------------ 00070 // Configure the directed graph. 00071 // ------------------------------------------------------------------ 00072 00073 digraph.setNodesep(new Float(0.5)); 00074 digraph.setRankset(new Float(0.7)); 00075 digraph.setCompound(Boolean.TRUE); 00076 00077 // ------------------------------------------------------------------ 00078 // Add the table. 00079 // ------------------------------------------------------------------ 00080 00081 for (Table table : this._tables) 00082 { 00083 Node table_node = new Node(table.getName()); 00084 table_node.setShape("record"); 00085 table_node.setStyle("bold"); 00086 table_node.setLabel(this.__createMediumTableLabel(table, digraph.getRankdir())); 00087 00088 SubGraph sub_graph = new SubGraph(table.getName()); 00089 sub_graph.setStyle("filled"); 00090 sub_graph.setBackgroundColor(Conf.TABLE_BG_COLOR); 00091 sub_graph.setNodeStyle("filled"); 00092 sub_graph.setNodeColor(Conf.TABLE_GRID_COLOR); 00093 sub_graph.setLabel(table.getName()); 00094 sub_graph.addNode(table_node); 00095 00096 digraph.addSubGraph(sub_graph); 00097 } 00098 00099 // ------------------------------------------------------------------ 00100 // Add the joins between tables. 00101 // ------------------------------------------------------------------ 00102 00103 Integer looper = 0; 00104 for (Table dependant_table : this._tables) 00105 { 00106 for (Table reference_table : this._db.getReferenceTables(dependant_table)) 00107 { 00108 // WARNING: If we work on a sub list of the total list of tables (zoom level is activated), then some target's tables may not be printed! 00109 if (! this._tables.contains(reference_table)) { continue; } 00110 00111 String edge_color = this._relationColor(this._db.getTableToTableRelationType(dependant_table, reference_table)); 00112 00113 if (0 != dependant_table.getName().compareTo(reference_table.getName())) 00114 { 00115 // Create the edge from the reference table to the target table. 00116 Edge join = new Edge(); 00117 join.setFrom(dependant_table.getName()); 00118 join.setTo(reference_table.getName()); 00119 join.setPenwidth("2"); 00120 join.setColor(edge_color); 00121 join.setLtail(SubGraph.generateName(dependant_table.getName())); 00122 join.setLhead(SubGraph.generateName(reference_table.getName())); 00123 digraph.addEdge(join); 00124 } 00125 else 00126 { 00127 String middle_name = "l" + looper.toString(); 00128 looper += 1; 00129 00130 Node middle = new Node(middle_name); 00131 middle.setShape("point"); 00132 digraph.addNode(middle); 00133 00134 Edge join1 = new Edge(); 00135 join1.setArrowhead("none"); 00136 join1.setFrom(dependant_table.getName()); 00137 join1.setTo(middle_name); 00138 join1.setPenwidth("2"); 00139 join1.setColor(edge_color); 00140 join1.setLtail(SubGraph.generateName(dependant_table.getName())); 00141 digraph.addEdge(join1); 00142 00143 Edge join2 = new Edge(); 00144 join2.setFrom(middle_name); 00145 join2.setTo(reference_table.getName()); 00146 join2.setPenwidth("2"); 00147 join2.setColor(edge_color); 00148 join2.setLhead(SubGraph.generateName(reference_table.getName())); 00149 digraph.addEdge(join2); 00150 } 00151 } 00152 } 00153 00154 return digraph.toString(); 00155 } 00156 00157 /** 00158 * This method creates the "medium" label for a given table. The label is a 00159 * grid that contains 5 columns, and as many row as the number of fields in 00160 * the table. 00161 * 00162 * @param in_table 00163 * The table. 00164 * @param in_rankdir 00165 * Initial orientation of a record node. Values can be: 00166 * <ul> 00167 * <li>TB (Top to bottom)</li> 00168 * <li>LR (Left to right)</li> 00169 * <li>RL 'Right to left)</li> 00170 * </ul> 00171 * <p>See GRAPHVIZ' documentation for "rankdir": http://www.graphviz.org/doc/info/shapes.html</p> 00172 * @return The method returns a string that represents the label. 00173 */ 00174 private String __createMediumTableLabel(Table in_table, String in_rankdir) 00175 { 00176 GridByRow label = new GridByRow(); 00177 label.setRankdir(in_rankdir); 00178 00179 // Create rows: {name}. 00180 for (Field field : in_table.getFields()) 00181 { 00182 ArrayList<String> line = new ArrayList<String>(); 00183 00184 // Add the name of the field. 00185 line.add(field.getName()); 00186 00187 // Add the line to the label. 00188 label.add(line); 00189 } 00190 00191 return label.toString(); 00192 } 00193 }