001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2002-2005 Julian Hyde 008// Copyright (C) 2005-2009 Pentaho and others 009// All Rights Reserved. 010*/ 011package mondrian.gui; 012 013import mondrian.gui.JdbcMetaData.DbColumn; 014 015import org.apache.log4j.Logger; 016 017import java.util.Enumeration; 018import java.util.List; 019import javax.swing.event.TreeExpansionEvent; 020import javax.swing.event.TreeWillExpandListener; 021import javax.swing.tree.*; 022 023/** 024 * @author sean 025 */ 026public class JdbcExplorer 027 extends javax.swing.JPanel 028 implements TreeWillExpandListener 029{ 030 private static final Logger LOGGER = Logger.getLogger(JdbcExplorer.class); 031 032 JdbcMetaData jdbcMetaData; 033 JdbcTreeModel model; 034 035 Workbench workbench; 036 037 DefaultMutableTreeNode root; 038 039 DefaultTreeModel treeModel; 040 041 public JdbcExplorer(JdbcMetaData jdbcMetaData, Workbench wb) { 042 workbench = wb; 043 initComponents(); 044 setMetaData(jdbcMetaData); 045 } 046 047 public void setMetaData(JdbcMetaData jdbcMetaData) { 048 try { 049 this.jdbcMetaData = jdbcMetaData; 050 051 Node rootNode = new Node(null, NodeType.ROOT, null); 052 root = new DefaultMutableTreeNode(rootNode); 053 054 for (String schemaName : jdbcMetaData.getAllSchemas()) { 055 Node cat = new Node(schemaName, NodeType.CATALOG, null); 056 057 DefaultMutableTreeNode catTreeNode = 058 new DefaultMutableTreeNode(cat); 059 cat.treeNode = catTreeNode; 060 root.add(catTreeNode); 061 062 List<String> tables = jdbcMetaData.getAllTables(schemaName); 063 for (String tableName : tables) { 064 Node table = new Node(tableName, NodeType.TABLE, null); 065 DefaultMutableTreeNode tableTreeNode = 066 new DefaultMutableTreeNode(table); 067 table.treeNode = tableTreeNode; 068 catTreeNode.add(tableTreeNode); 069 } 070 071 cat.gotChildren = true; 072 } 073 rootNode.gotChildren = true; 074 075 treeModel = new DefaultTreeModel(root, true); 076 tree.setModel(treeModel); 077 tree.addTreeWillExpandListener(this); 078 079 updater = new JTreeUpdater(tree); 080 } catch (Exception ex) { 081 LOGGER.error(ex); 082 } 083 } 084 085 public void resetMetaData(JdbcMetaData jdbcMetaData) { 086 setMetaData(jdbcMetaData); 087 } 088 089 public JTreeUpdater getTreeUpdater() { 090 return updater; 091 } 092 093 public void treeWillExpand(TreeExpansionEvent event) 094 throws ExpandVetoException 095 { 096 // The children are lazy loaded 097 LOGGER.debug( 098 "path = " + event.getPath() + ", last object is a " 099 + event.getPath().getLastPathComponent().getClass().getName()); 100 101 DefaultMutableTreeNode theTreeNode = 102 (DefaultMutableTreeNode) event.getPath().getLastPathComponent(); 103 Node theNode = (Node) theTreeNode.getUserObject(); 104 theNode.setChildren(); 105 106 logNode(theTreeNode, "will Expand"); 107 } 108 109 private void logNode(DefaultMutableTreeNode theTreeNode, String message) { 110 if (!LOGGER.isDebugEnabled()) { 111 return; 112 } 113 114 DefaultMutableTreeNode parentNode = 115 (DefaultMutableTreeNode) theTreeNode.getParent(); 116 117 Node theNode = (Node) theTreeNode.getUserObject(); 118 Node theParentNode = 119 parentNode == null 120 ? null 121 : (Node) parentNode.getUserObject(); 122 123 @SuppressWarnings({"unchecked"}) 124 Enumeration<DefaultMutableTreeNode> children = theTreeNode.children(); 125 126 LOGGER.debug( 127 message + ": " + theNode + ", " + theNode.type 128 + ", parent " + theParentNode 129 + (theParentNode == null 130 ? "" 131 : ", " + theParentNode.type)); 132 while (children.hasMoreElements()) { 133 DefaultMutableTreeNode treeNode = children.nextElement(); 134 Node child = (Node) treeNode.getUserObject(); 135 LOGGER.debug("\t" + child.toString() + ", " + child.type); 136 } 137 } 138 139 public void treeWillCollapse(TreeExpansionEvent arg0) 140 throws ExpandVetoException 141 { 142 } 143 144 enum NodeType { 145 CATALOG, 146 TABLE, 147 COLUMN, 148 ROOT 149 } 150 151 class Node { 152 final String name; 153 final NodeType type; 154 boolean gotChildren = false; 155 DefaultMutableTreeNode treeNode; 156 final JdbcMetaData.DbColumn columnInfo; 157 158 public Node( 159 String name, 160 NodeType type, 161 DefaultMutableTreeNode treeNode) 162 { 163 this(name, type, treeNode, null); 164 } 165 166 public Node( 167 String name, 168 NodeType type, 169 DefaultMutableTreeNode treeNode, 170 JdbcMetaData.DbColumn columnInfo) 171 { 172 this.name = name; 173 this.type = type; 174 this.treeNode = treeNode; 175 this.columnInfo = columnInfo; 176 } 177 178 public String toString() { 179 if (type == NodeType.ROOT) { 180 return workbench.getResourceConverter().getFormattedString( 181 "jdbcExplorer.root.name", 182 "All Schemas"); 183 } 184 185 StringBuilder sb = new StringBuilder(); 186 if (name == null || name.trim().length() == 0) { 187 switch (type) { 188 case CATALOG: 189 sb.append( 190 workbench.getResourceConverter().getFormattedString( 191 "jdbcExplorer.default.name.catalog", 192 "Default Schema")); 193 break; 194 case TABLE: 195 sb.append( 196 workbench.getResourceConverter().getFormattedString( 197 "jdbcExplorer.default.name.table", "Table")); 198 break; 199 case COLUMN: 200 sb.append( 201 workbench.getResourceConverter().getFormattedString( 202 "jdbcExplorer.default.name.column", 203 "Column")); 204 break; 205 } 206 } else { 207 sb.append(name); 208 } 209 210 if (type != NodeType.COLUMN) { 211 return sb.toString(); 212 } 213 214 // now for columns 215 216 sb.append(" - ").append(columnInfo.displayType()); 217 218 return sb.toString(); 219 } 220 221 public void setChildren() { 222 if (!gotChildren) { 223 if (type == NodeType.TABLE) { 224 DefaultMutableTreeNode theParentTreeNode = 225 (DefaultMutableTreeNode) treeNode.getParent(); 226 227 Node theParentNode = 228 (Node) theParentTreeNode.getUserObject(); 229 230 // This is a table, parent is a schema 231 232 List<DbColumn> columns = 233 jdbcMetaData.getAllDbColumns( 234 theParentNode.name, name); 235 for (DbColumn column : columns) { 236 Node columnNode = new Node( 237 column.name, NodeType.COLUMN, treeNode, column); 238 MutableTreeNode columnTreeNode = 239 new DefaultMutableTreeNode(columnNode, false); 240 treeNode.add(columnTreeNode); 241 } 242 } 243 } 244 gotChildren = true; 245 } 246 } 247 248 /** 249 * This method is called from within the constructor to 250 * initialize the form. 251 * WARNING: Do NOT modify this code. The content of this method is 252 * always regenerated by the Form Editor. 253 */ 254 private void initComponents() {//GEN-BEGIN:initComponents 255 jSplitPane1 = new javax.swing.JSplitPane(); 256 jScrollPane1 = new javax.swing.JScrollPane(); 257 tree = new javax.swing.JTree(); 258 jScrollPane2 = new javax.swing.JScrollPane(); 259 260 setLayout(new java.awt.BorderLayout()); 261 262 jSplitPane1.setDividerLocation(200); 263 jScrollPane1.setViewportView(tree); 264 265 jSplitPane1.setLeftComponent(jScrollPane1); 266 267 jSplitPane1.setRightComponent(jScrollPane2); 268 269 add(jSplitPane1, java.awt.BorderLayout.CENTER); 270 } //GEN-END:initComponents 271 272 273 // Variables declaration - do not modify//GEN-BEGIN:variables 274 private javax.swing.JScrollPane jScrollPane2; 275 private javax.swing.JScrollPane jScrollPane1; 276 private javax.swing.JTree tree; 277 private javax.swing.JSplitPane jSplitPane1; 278 // End of variables declaration//GEN-END:variables 279 280 private JTreeUpdater updater; 281} 282 283// End JdbcExplorer.java