001 /* 002 // $Id: //open/mondrian/src/main/mondrian/gui/JDBCTreeModel.java#6 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2002-2007 Julian Hyde and others 007 // All Rights Reserved. 008 // You must accept the terms of that agreement to use this software. 009 */ 010 package mondrian.gui; 011 012 import javax.swing.event.TreeModelListener; 013 import javax.swing.tree.TreePath; 014 import java.sql.Connection; 015 import java.sql.DatabaseMetaData; 016 import java.sql.ResultSet; 017 import java.util.ArrayList; 018 import java.util.List; 019 import java.util.Vector; 020 021 import org.apache.log4j.Logger; 022 023 /** 024 * 025 * @author sean 026 * @version $Id: //open/mondrian/src/main/mondrian/gui/JDBCTreeModel.java#6 $ 027 */ 028 public class JDBCTreeModel implements javax.swing.tree.TreeModel { 029 030 private static final Logger LOGGER = Logger.getLogger(JDBCTreeModel.class); 031 032 private Vector treeModelListeners = new Vector(); 033 Connection connection; 034 DatabaseMetaData metadata; 035 List catalogs; 036 Node root; 037 038 /** Creates a new instance of JDBCTreeModel */ 039 public JDBCTreeModel(Connection c) { 040 connection = c; 041 try { 042 metadata = connection.getMetaData(); 043 catalogs = new ArrayList(); 044 String catalogName = connection.getCatalog(); 045 Node cat = new Node(catalogName, Node.CATALOG); 046 047 ResultSet trs = metadata.getTables(cat.name, null, null, null); 048 while (trs.next()) { 049 Node table = new Node(trs.getString(3), Node.TABLE); 050 cat.children.add(table); 051 //get the tables for each catalog. 052 ResultSet crs = metadata.getColumns(cat.name, null, table.name, null); 053 while (crs.next()) { 054 Node column = new Node(crs.getString(4), Node.COLUMN); 055 table.children.add(column); 056 } 057 } 058 root = cat; 059 060 } catch (Exception ex) { 061 LOGGER.error("JDBCTreeModel", ex); 062 } 063 } 064 065 066 /** Adds a listener for the <code>TreeModelEvent</code> 067 * posted after the tree changes. 068 * 069 * @param l the listener to add 070 * @see #removeTreeModelListener 071 * 072 */ 073 public void addTreeModelListener(TreeModelListener l) { 074 treeModelListeners.add(l); 075 } 076 077 /** Returns the child of <code>parent</code> at index <code>index</code> 078 * in the parent's 079 * child array. <code>parent</code> must be a node previously obtained 080 * from this data source. This should not return <code>null</code> 081 * if <code>index</code> 082 * is a valid index for <code>parent</code> (that is <code>index >= 0 && 083 * index < getChildCount(parent</code>)). 084 * 085 * @param parent a node in the tree, obtained from this data source 086 * @return the child of <code>parent</code> at index <code>index</code> 087 * 088 */ 089 public Object getChild(Object parent, int index) { 090 if (parent instanceof Node) { 091 return ((Node)parent).children.get(index); 092 } 093 094 return null; 095 } 096 097 /** Returns the number of children of <code>parent</code>. 098 * Returns 0 if the node 099 * is a leaf or if it has no children. <code>parent</code> must be a node 100 * previously obtained from this data source. 101 * 102 * @param parent a node in the tree, obtained from this data source 103 * @return the number of children of the node <code>parent</code> 104 * 105 */ 106 public int getChildCount(Object parent) { 107 if (parent instanceof Node) { 108 return ((Node)parent).children.size(); 109 } 110 return 0; 111 } 112 113 /** Returns the index of child in parent. If <code>parent</code> 114 * is <code>null</code> or <code>child</code> is <code>null</code>, 115 * returns -1. 116 * 117 * @param parent a note in the tree, obtained from this data source 118 * @param child the node we are interested in 119 * @return the index of the child in the parent, or -1 if either 120 * <code>child</code> or <code>parent</code> are <code>null</code> 121 * 122 */ 123 public int getIndexOfChild(Object parent, Object child) { 124 if (parent instanceof Node) { 125 return ((Node)parent).children.indexOf(child); 126 } 127 128 return -1; 129 } 130 131 /** Returns the root of the tree. Returns <code>null</code> 132 * only if the tree has no nodes. 133 * 134 * @return the root of the tree 135 * 136 */ 137 public Object getRoot() { 138 return root; 139 } 140 141 /** Returns <code>true</code> if <code>node</code> is a leaf. 142 * It is possible for this method to return <code>false</code> 143 * even if <code>node</code> has no children. 144 * A directory in a filesystem, for example, 145 * may contain no files; the node representing 146 * the directory is not a leaf, but it also has no children. 147 * 148 * @param node a node in the tree, obtained from this data source 149 * @return true if <code>node</code> is a leaf 150 * 151 */ 152 public boolean isLeaf(Object node) { 153 return getChildCount(node) == 0; 154 } 155 156 /** Removes a listener previously added with 157 * <code>addTreeModelListener</code>. 158 * 159 * @see #addTreeModelListener 160 * @param l the listener to remove 161 * 162 */ 163 public void removeTreeModelListener(TreeModelListener l) { 164 treeModelListeners.remove(l); 165 } 166 167 /** Messaged when the user has altered the value for the item identified 168 * by <code>path</code> to <code>newValue</code>. 169 * If <code>newValue</code> signifies a truly new value 170 * the model should post a <code>treeNodesChanged</code> event. 171 * 172 * @param path path to the node that the user has altered 173 * @param newValue the new value from the TreeCellEditor 174 * 175 */ 176 public void valueForPathChanged(TreePath path, Object newValue) { 177 } 178 179 class Node { 180 static final int CATALOG = 0; 181 static final int TABLE = 1; 182 static final int COLUMN = 2; 183 String name; 184 int type; 185 ArrayList children; 186 187 public Node(String n, int t) { 188 name = n; 189 type = t; 190 children = new ArrayList(); 191 } 192 193 public String toString() { 194 return name; 195 } 196 } 197 } 198 199 // End JDBCTreeModel.java