0001: /*
0002: * ConnectionsTreePanel.java
0003: *
0004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
0005: *
0006: * This program is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU General Public License
0008: * as published by the Free Software Foundation; either version 2
0009: * of the License, or any later version.
0010: *
0011: * This program is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0014: * GNU General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU General Public License
0017: * along with this program; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0019: *
0020: */
0021:
0022: package org.executequery.gui.browser;
0023:
0024: import java.awt.BorderLayout;
0025: import java.awt.Point;
0026: import java.awt.event.ActionEvent;
0027: import java.awt.event.ActionListener;
0028: import java.awt.event.MouseAdapter;
0029: import java.awt.event.MouseEvent;
0030: import java.sql.SQLException;
0031: import java.util.ArrayList;
0032: import java.util.Enumeration;
0033: import java.util.HashMap;
0034: import java.util.List;
0035: import java.util.Map;
0036: import java.util.Properties;
0037: import java.util.Vector;
0038: import javax.swing.JButton;
0039: import javax.swing.JMenu;
0040: import javax.swing.JMenuItem;
0041: import javax.swing.JOptionPane;
0042: import javax.swing.JPanel;
0043: import javax.swing.JPopupMenu;
0044: import javax.swing.JScrollPane;
0045: import javax.swing.SwingUtilities;
0046: import javax.swing.event.TreeExpansionEvent;
0047: import javax.swing.event.TreeExpansionListener;
0048: import javax.swing.event.TreeSelectionEvent;
0049: import javax.swing.event.TreeSelectionListener;
0050: import javax.swing.tree.DefaultMutableTreeNode;
0051: import javax.swing.tree.TreeNode;
0052: import javax.swing.tree.TreePath;
0053: import org.executequery.ConnectionProperties;
0054: import org.executequery.EventMediator;
0055: import org.executequery.GUIUtilities;
0056: import org.executequery.SystemUtilities;
0057: import org.underworldlabs.swing.tree.DynamicTree;
0058: import org.underworldlabs.swing.toolbar.PanelToolBar;
0059: import org.executequery.event.ConnectionEvent;
0060: import org.executequery.event.ConnectionListener;
0061: import org.executequery.databasemediators.DatabaseConnection;
0062: import org.executequery.databasemediators.MetaDataValues;
0063: import org.executequery.gui.AbstractDockedTabActionPanel;
0064: import org.executequery.components.table.BrowserTreeCellRenderer;
0065: import org.executequery.gui.BaseDialog;
0066: import org.executequery.gui.importexport.ImportExportDelimitedPanel;
0067: import org.executequery.gui.importexport.ImportExportExcelPanel;
0068: import org.executequery.gui.importexport.ImportExportProcess;
0069: import org.executequery.gui.importexport.ImportExportXMLPanel;
0070: import org.executequery.util.Log;
0071: import org.underworldlabs.swing.GUIUtils;
0072: import org.underworldlabs.swing.actions.ReflectiveAction;
0073: import org.underworldlabs.swing.util.IconUtilities;
0074: import org.underworldlabs.util.MiscUtils;
0075: import org.underworldlabs.swing.util.SwingWorker;
0076:
0077: /* ----------------------------------------------------------
0078: * CVS NOTE: Changes to the CVS repository prior to the
0079: * release of version 3.0.0beta1 has meant a
0080: * resetting of CVS revision numbers.
0081: * ----------------------------------------------------------
0082: */
0083:
0084: /**
0085: *
0086: * @author Takis Diakoumis
0087: * @version $Revision: 1.27 $
0088: * @date $Date: 2006/09/21 14:36:14 $
0089: */
0090: public class ConnectionsTreePanel extends AbstractDockedTabActionPanel
0091: implements ConnectionListener, TreeExpansionListener,
0092: TreeSelectionListener {
0093:
0094: /** the title for this panel */
0095: public static final String TITLE = "Connections";
0096:
0097: /** the tree object */
0098: private DynamicTree tree;
0099:
0100: /** saved connections */
0101: private Vector<DatabaseConnection> connections;
0102:
0103: /** Worker for meta data retrieval */
0104: private SwingWorker worker;
0105:
0106: /** the browser's control object */
0107: private BrowserController controller;
0108:
0109: /** the old selected browser node */
0110: private TreePath oldSelectionPath;
0111:
0112: /** the tree popup menu */
0113: private PopMenu popupMenu;
0114:
0115: /** indicates whether to reselect the connection
0116: * properties node following a disconnection event. */
0117: private boolean rootSelectOnDisconnect;
0118:
0119: // -------------------------------------
0120: // tool bar buttons
0121:
0122: /** move connection up button */
0123: private JButton upButton;
0124:
0125: /** move connection down button */
0126: private JButton downButton;
0127:
0128: /** the reload node button */
0129: private JButton reloadButton;
0130:
0131: /** new connection button */
0132: private JButton newConnectionButton;
0133:
0134: /** delete connection button */
0135: private JButton deleteConnectionButton;
0136:
0137: // -------------------------------------
0138:
0139: /** Creates a new instance of ConnectionsPanel */
0140: public ConnectionsTreePanel() {
0141: super (new BorderLayout());
0142: init();
0143: }
0144:
0145: private void init() {
0146: // default to not select the root node after a disconnection
0147: rootSelectOnDisconnect = false;
0148:
0149: // initialise the controller
0150: controller = new BrowserController(this );
0151:
0152: // setup the root node - simple label only
0153: DatabaseObject rootObject = new DatabaseObject(
0154: BrowserConstants.ROOT_NODE, "Database Connections");
0155: DefaultMutableTreeNode root = new DefaultMutableTreeNode(
0156: rootObject);
0157:
0158: // loop through available connections and add as leaf objects
0159: connections = ConnectionProperties.getConnectionsVector();
0160: for (int i = 0, k = connections.size(); i < k; i++) {
0161: DatabaseConnection dc = connections.elementAt(i);
0162: ConnectionObject object = new ConnectionObject(dc);
0163: BrowserTreeNode node = new BrowserTreeNode(object, true);
0164: root.add(node);
0165: }
0166:
0167: // load the tree and panel icons
0168: Map icons = new HashMap();
0169: for (int i = 0; i < BrowserConstants.NODE_ICONS.length; i++) {
0170: icons.put(BrowserConstants.NODE_ICONS[i], GUIUtilities
0171: .loadIcon(BrowserConstants.NODE_ICONS[i], true));
0172: }
0173: icons
0174: .put(BrowserConstants.DATABASE_OBJECT_IMAGE,
0175: GUIUtilities.loadIcon(
0176: BrowserConstants.DATABASE_OBJECT_IMAGE,
0177: true));
0178:
0179: tree = new DynamicTree(root);
0180: tree.setCellRenderer(new BrowserTreeCellRenderer(icons));
0181: tree.addTreeSelectionListener(this );
0182: tree.addTreeExpansionListener(this );
0183: tree.addMouseListener(new MouseHandler());
0184:
0185: // ---------------------------------------
0186: // the tool bar
0187: PanelToolBar tools = new PanelToolBar();
0188: newConnectionButton = tools
0189: .addButton(this , "newConnection", GUIUtilities
0190: .getAbsoluteIconPath("NewConnection16.gif"),
0191: "New connection");
0192: deleteConnectionButton = tools.addButton(this ,
0193: "deleteConnection", GUIUtilities
0194: .getAbsoluteIconPath("Delete16.gif"),
0195: "Remove connection");
0196: upButton = tools
0197: .addButton(this , "moveConnectionUp", GUIUtilities
0198: .getAbsoluteIconPath("Up16.gif"), "Move up");
0199: downButton = tools.addButton(this , "moveConnectionDown",
0200: GUIUtilities.getAbsoluteIconPath("Down16.gif"),
0201: "Move down");
0202:
0203: reloadButton = tools.addButton(this , "reloadSelection",
0204: GUIUtilities.getAbsoluteIconPath("Reload16.gif"),
0205: "Reload the currently selected node");
0206:
0207: // add the tools and tree to the panel
0208: add(tools, BorderLayout.NORTH);
0209: add(new JScrollPane(tree), BorderLayout.CENTER);
0210:
0211: // register with the event listener
0212: EventMediator.registerListener(EventMediator.CONNECTION_EVENT,
0213: this );
0214:
0215: enableButtons(false);
0216: tree.setSelectionRow(0);
0217: }
0218:
0219: private void enableButtons(final boolean enable) {
0220: SwingUtilities.invokeLater(new Runnable() {
0221: public void run() {
0222: upButton.setEnabled(enable);
0223: downButton.setEnabled(enable);
0224: reloadButton.setEnabled(!enable);
0225: deleteConnectionButton.setEnabled(enable);
0226: }
0227: });
0228: }
0229:
0230: /**
0231: * Moves the selected connection (host node) up in the list.
0232: */
0233: public void moveConnectionUp() {
0234: tree.moveSelectionUp();
0235: // adjust the position of the connection
0236: Object object = tree.getLastPathComponent();
0237: moveNode((BrowserTreeNode) object, DynamicTree.MOVE_UP);
0238: }
0239:
0240: /**
0241: * Sets the selected connection tree node to the
0242: * specified database connection.
0243: *
0244: * @param dc - the database connection to select
0245: * @param reload - if true, ensures the view panel is set to
0246: * the connection properties
0247: */
0248: public void setSelectedConnection(DatabaseConnection dc,
0249: boolean reload) {
0250: try {
0251: reloadView = true;
0252: setSelectedConnection(dc);
0253: } finally {
0254: reloadView = false;
0255: }
0256: }
0257:
0258: /**
0259: * Sets the selected connection tree node to the
0260: * specified database connection.
0261: *
0262: * @param dc - the database connection to select
0263: */
0264: public void setSelectedConnection(DatabaseConnection dc) {
0265: DefaultMutableTreeNode node = null;
0266:
0267: // retrieve the root node and loop through
0268: DefaultMutableTreeNode root = tree.getRootNode();
0269: for (Enumeration i = root.children(); i.hasMoreElements();) {
0270: DefaultMutableTreeNode _node = (DefaultMutableTreeNode) i
0271: .nextElement();
0272: Object userObject = _node.getUserObject();
0273:
0274: // make sure its a connection object
0275: if (userObject instanceof ConnectionObject) {
0276: ConnectionObject object = (ConnectionObject) userObject;
0277: if (object.getDatabaseConnection() == dc) {
0278: node = _node;
0279: break;
0280: }
0281: }
0282:
0283: }
0284:
0285: // select the node path
0286: if (node != null) {
0287: TreePath path = new TreePath(node.getPath());
0288: tree.scrollPathToVisible(path);
0289: tree.setSelectionPath(path);
0290:
0291: if (reloadView) {
0292: Object object = tree.getLastPathComponent();
0293: if (object instanceof BrowserTreeNode) {
0294: controller.valueChanged(getSelectedMetaObject(),
0295: (BrowserTreeNode) object, false);
0296: }
0297: }
0298:
0299: }
0300: }
0301:
0302: /**
0303: * Deletes the selected connection (host node) from the list.
0304: */
0305: public void deleteConnection() {
0306: deleteConnection(null);
0307: }
0308:
0309: /**
0310: * Deletes the specified connection (host node) from the list.
0311: *
0312: * @param the node representing the connection to be removed
0313: */
0314: public void deleteConnection(BrowserTreeNode node) {
0315: boolean isSelectedNode = false;
0316: if (node == null) {
0317: Object object = tree.getLastPathComponent();
0318: node = (BrowserTreeNode) object;
0319: isSelectedNode = true;
0320: } else {
0321: if (tree.getLastPathComponent() == node) {
0322: isSelectedNode = true;
0323: }
0324: }
0325:
0326: int yesNo = GUIUtilities
0327: .displayConfirmCancelDialog("Are you sure you want to delete the connection "
0328: + node + " ?");
0329:
0330: if (yesNo != JOptionPane.YES_OPTION) {
0331: return;
0332: }
0333:
0334: ConnectionObject metaObject = (ConnectionObject) node
0335: .getDatabaseUserObject();
0336: DatabaseConnection dc = metaObject.getDatabaseConnection();
0337:
0338: // the next selection index will be the index of
0339: // the one being removed - (index - 1)
0340: int index = connections.indexOf(dc);
0341: if (index == -1) {
0342: return;
0343: }
0344:
0345: // remove from the connections
0346: connections.remove(index);
0347:
0348: if (index > connections.size() - 1) {
0349: index = connections.size() - 1;
0350: }
0351:
0352: if (isSelectedNode) {
0353: String prefix = connections.get(index).getName();
0354: tree.removeNode(node, prefix);
0355: } else {
0356: tree.removeNode(node);
0357: }
0358:
0359: // save the connections
0360: controller.saveConnections();
0361: }
0362:
0363: /**
0364: * Returns the database connection at the specified point.
0365: *
0366: * @return the connection properties object
0367: */
0368: protected DatabaseConnection getConnectionAt(Point point) {
0369: TreePath path = tree.getPathForLocation(point.x, point.y);
0370: return getConnectionAt(tree
0371: .getPathForLocation(point.x, point.y));
0372: }
0373:
0374: /**
0375: * Returns the database connection associated with the specified path.
0376: *
0377: * @return the connection properties object
0378: */
0379: protected DatabaseConnection getConnectionAt(TreePath path) {
0380: if (path != null) {
0381: Object object = path.getLastPathComponent();
0382: if (object instanceof BrowserTreeNode) {
0383: return getDatabaseConnection((BrowserTreeNode) object);
0384: }
0385: }
0386: return null;
0387: }
0388:
0389: /**
0390: * Removes the tree listener.
0391: */
0392: protected void removeTreeListener() {
0393: tree.removeTreeSelectionListener(this );
0394: }
0395:
0396: /**
0397: * Adds the tree listener.
0398: */
0399: protected void addTreeListener() {
0400: tree.addTreeSelectionListener(this );
0401: }
0402:
0403: /**
0404: * Selects the specified node.
0405: */
0406: protected void setNodeSelected(DefaultMutableTreeNode node) {
0407: TreePath path = new TreePath(node.getPath());
0408: tree.setSelectionPath(path);
0409: }
0410:
0411: /**
0412: * Removes the selected tree node (database object) from the tree.
0413: */
0414: public void removeSelectedNode() {
0415: // remove the listener
0416: tree.removeTreeSelectionListener(this );
0417:
0418: // store the current row
0419: int row = tree.getSelectionRows()[0];
0420:
0421: // retrieve the current selection node
0422: BrowserTreeNode node = (BrowserTreeNode) tree
0423: .getLastPathComponent();
0424: tree.removeNode(node);
0425:
0426: // add listener and select row above
0427: tree.addTreeSelectionListener(this );
0428: row = (row == 0 ? 1 : row - 1);
0429: tree.setSelectionRow(row);
0430: }
0431:
0432: /**
0433: * Creates a new connection and adds it to the bottom
0434: * of the list.
0435: */
0436: public void newConnection() {
0437: newConnection(null);
0438: }
0439:
0440: /**
0441: * Creates a new connection based on the specified connection.
0442: *
0443: * @param dc - the connection the new one is to be based on
0444: */
0445: public void newConnection(DatabaseConnection dc) {
0446: if (dc == null) {
0447: String name = buildConnectionName("New Connection");
0448: dc = new DatabaseConnection(name);
0449: }
0450:
0451: ConnectionObject metaObject = new ConnectionObject(dc);
0452: connections.add(dc);
0453: BrowserTreeNode node = new BrowserTreeNode(metaObject, true);
0454: tree.addToRoot(node);
0455: }
0456:
0457: /**
0458: * Moves the selected connection (host node) down in the list.
0459: */
0460: public void moveConnectionDown() {
0461: tree.moveSelectionDown();
0462: // adjust the position of the connection
0463: Object object = tree.getLastPathComponent();
0464: moveNode((BrowserTreeNode) object, DynamicTree.MOVE_DOWN);
0465: }
0466:
0467: private void moveNode(BrowserTreeNode node, int direction) {
0468: ConnectionObject metaObject = (ConnectionObject) node
0469: .getDatabaseUserObject();
0470: DatabaseConnection dc = metaObject.getDatabaseConnection();
0471:
0472: int currentIndex = connections.indexOf(dc);
0473: if (currentIndex == 0 && direction == DynamicTree.MOVE_UP) {
0474: return;
0475: }
0476:
0477: int newIndex = -1;
0478: if (direction == DynamicTree.MOVE_UP) {
0479: newIndex = currentIndex - 1;
0480: } else {
0481: newIndex = currentIndex + 1;
0482: if (newIndex > (connections.size() - 1)) {
0483: return;
0484: }
0485: }
0486:
0487: connections.remove(currentIndex);
0488: connections.insertElementAt(dc, newIndex);
0489:
0490: // save the connections
0491: //viewPanel.saveConnections();
0492: }
0493:
0494: /**
0495: * Indicates that a node name has changed and fires a call
0496: * to repaint the tree display.
0497: */
0498: protected void nodeNameValueChanged(ConnectionObject metaObject) {
0499: TreeNode node = tree.getNodeFromRoot(metaObject);
0500: if (node != null) {
0501: tree.nodeChanged(node);
0502: }
0503: }
0504:
0505: /**
0506: * Ensures we have a browser panel and that it is visible.
0507: */
0508: private void checkBrowserPanel() {
0509: controller.checkBrowserPanel();
0510: }
0511:
0512: /**
0513: * Override min size for split pane insertion.
0514: *
0515: * @return the enforced minimum size
0516: */
0517: /*
0518: public Dimension getMinimumSize() {
0519: return new Dimension(250, 80);
0520: }
0521: */
0522:
0523: /**
0524: * Returns the currently selected node's user object where the
0525: * node is a BrowserTreeNode and the user object is a DatabaseObject.
0526: * If the above is not met, null is returned.
0527: *
0528: * @return the user object of the selected node where the
0529: * user object is a DatabaseObject
0530: */
0531: protected BrowserTreeNode getSelectedBrowserNode() {
0532: // if path is null return null
0533: if (tree.isSelectionEmpty()) {
0534: return null;
0535: }
0536:
0537: // make sure we have a BrowserTreeNode
0538: Object object = tree.getLastPathComponent();
0539: if (!(object instanceof BrowserTreeNode)) {
0540: return null;
0541: }
0542:
0543: return (BrowserTreeNode) object;
0544: }
0545:
0546: /**
0547: * Returns the whether the currently selected node's user object
0548: * is a parent type where the node is a BrowserTreeNode and the
0549: * user object is a DatabaseObject. If the above is not met, false is
0550: * returned, otherwise the object is evaluated.
0551: *
0552: * @return true | false
0553: */
0554: protected boolean isTypeParentSelected() {
0555: // if path is null return null
0556: if (tree.isSelectionEmpty()) {
0557: return false;
0558: }
0559:
0560: // make sure we have a BrowserTreeNode
0561: Object object = tree.getLastPathComponent();
0562: if (!(object instanceof BrowserTreeNode)) {
0563: return false;
0564: }
0565:
0566: // return the parent connection meta object
0567: return ((BrowserTreeNode) object).isTypeParent();
0568: }
0569:
0570: /**
0571: * Returns the currently selected node's user object where the
0572: * node is a BrowserTreeNode and the user object is a DatabaseObject.
0573: * If the above is not met, null is returned.
0574: *
0575: * @return the user object of the selected node where the
0576: * user object is a DatabaseObject
0577: */
0578: protected DatabaseObject getSelectedDatabaseObject() {
0579: // if path is null return null
0580: if (tree.isSelectionEmpty()) {
0581: return null;
0582: }
0583:
0584: // make sure we have a BrowserTreeNode
0585: Object object = tree.getLastPathComponent();
0586: if (!(object instanceof BrowserTreeNode)) {
0587: return null;
0588: }
0589:
0590: // return the parent connection meta object
0591: BrowserTreeNode node = (BrowserTreeNode) object;
0592: return node.getDatabaseUserObject();
0593: }
0594:
0595: /**
0596: * Returns the selected meta object host node.
0597: *
0598: * @return the selected host node meta object
0599: */
0600: protected ConnectionObject getSelectedMetaObject() {
0601: // if path is null return null
0602: if (tree.isSelectionEmpty()) {
0603: return null;
0604: }
0605:
0606: // make sure we have a BrowserTreeNode
0607: Object object = tree.getLastPathComponent();
0608: if (!(object instanceof BrowserTreeNode)) {
0609: return null;
0610: }
0611:
0612: // return the parent connection meta object
0613: BrowserTreeNode node = (BrowserTreeNode) object;
0614: BrowserTreeNode parent = getParentNode(node);
0615: return ((ConnectionObject) parent.getDatabaseUserObject());
0616: }
0617:
0618: /**
0619: * Returns the selected database connection.
0620: *
0621: * @return the selected connection properties object
0622: */
0623: public DatabaseConnection getSelectedDatabaseConnection() {
0624: ConnectionObject object = getSelectedMetaObject();
0625: if (object != null) {
0626: return object.getDatabaseConnection();
0627: }
0628: return null;
0629: }
0630:
0631: // ------------------------------------------
0632: // ConnectionListner implementation
0633: // ------------------------------------------
0634:
0635: /**
0636: * Indicates a connection has been established.
0637: *
0638: * @param the encapsulating event
0639: */
0640: public void connected(ConnectionEvent connectionEvent) {
0641: DatabaseConnection dc = connectionEvent.getSource();
0642: BrowserTreeNode node = getParentConnectionNode(dc);
0643:
0644: ConnectionObject metaObject = (ConnectionObject) node
0645: .getDatabaseUserObject();
0646: TreePath path = new TreePath(node.getPath());
0647: TreeExpansionEvent _e = new TreeExpansionEvent(tree, path);
0648: treeExpanded(_e);
0649: tree.nodeStructureChanged(node);
0650: }
0651:
0652: /**
0653: * Indicates a connection has been closed.
0654: *
0655: * @param the encapsulating event
0656: */
0657: public void disconnected(ConnectionEvent connectionEvent) {
0658: DatabaseConnection dc = connectionEvent.getSource();
0659: BrowserTreeNode node = getParentConnectionNode(dc);
0660:
0661: node.setExpanded(false);
0662: node.removeAllChildren();
0663: tree.nodeStructureChanged(node);
0664:
0665: // check if we select the root node
0666: if (rootSelectOnDisconnect) {
0667: tree.setSelectionRow(0);
0668: }
0669: // otherwise select the host node
0670: else {
0671: tree.setSelectionPath(new TreePath(node.getPath()));
0672: }
0673:
0674: }
0675:
0676: // ------------------------------------------
0677:
0678: /**
0679: * Returns the previosuly selected path before the current
0680: * selection.
0681: *
0682: * @return the previous path
0683: */
0684: protected TreePath getOldSelectionPath() {
0685: return oldSelectionPath;
0686: }
0687:
0688: /**
0689: * Returns the previously selected browse node before the
0690: * current selection.
0691: *
0692: * @return the previous node selection
0693: */
0694: protected BrowserTreeNode getOldBrowserNodeSelection() {
0695: Object object = getOldSelectionPath().getLastPathComponent();
0696: if (object != null && object instanceof BrowserTreeNode) {
0697: return (BrowserTreeNode) object;
0698: }
0699: return null;
0700: }
0701:
0702: protected BrowserTreeNode getParentConnectionNode(
0703: DatabaseConnection dc) {
0704: for (Enumeration i = tree.getRootNode().children(); i
0705: .hasMoreElements();) {
0706: Object object = i.nextElement();
0707: if (object instanceof BrowserTreeNode) {
0708: BrowserTreeNode node = (BrowserTreeNode) object;
0709: object = node.getUserObject();
0710: if (object instanceof ConnectionObject) {
0711: ConnectionObject conn = (ConnectionObject) object;
0712: if (conn.getDatabaseConnection() == dc) {
0713: return node;
0714: }
0715: }
0716: }
0717: }
0718: return null;
0719: }
0720:
0721: /**
0722: * Notification that the currently selected node (a host)
0723: * has had their associated db connection closed.
0724: */
0725: protected void selectedNodeDisconnected() {
0726: Object object = tree.getLastPathComponent();
0727: if (!(object instanceof BrowserTreeNode)) {
0728: return;
0729: }
0730:
0731: // remove all choldren from the host node
0732: // of the current path
0733: BrowserTreeNode node = (BrowserTreeNode) object;
0734: if (!(node.getUserObject() instanceof ConnectionObject)) {
0735: node = getParentNode(node);
0736: }
0737:
0738: node.setExpanded(false);
0739: BrowserTreeNode parent = getParentNode(node);
0740: parent.removeAllChildren();
0741: tree.nodeStructureChanged(parent);
0742: }
0743:
0744: /**
0745: * Notification that the currently selected node (a host)
0746: * has had their associated db connection created.
0747: */
0748: protected void selectedNodeConnected() {
0749: if (tree.isSelectionEmpty()) {
0750: return;
0751: }
0752:
0753: Object object = tree.getLastPathComponent();
0754: if (!(object instanceof BrowserTreeNode)) {
0755: return;
0756: }
0757:
0758: // ensure node is expandable
0759: BrowserTreeNode node = (BrowserTreeNode) object;
0760: if (node.isLeaf()
0761: && node.getNodeType() == BrowserConstants.HOST_NODE) {
0762: ConnectionObject metaObject = (ConnectionObject) node
0763: .getDatabaseUserObject();
0764: TreeExpansionEvent _e = new TreeExpansionEvent(tree, tree
0765: .getSelectionPath());//selectedPath);
0766: treeExpanded(_e);
0767: tree.nodeStructureChanged(node);
0768: }
0769: }
0770:
0771: // --------------------------------------------------
0772: // ------- TreeSelectionListener implementation
0773: // --------------------------------------------------
0774:
0775: /**
0776: * Called whenever the value of the selection changes.
0777: * This will store the current path selection.
0778: *
0779: * @param the event that characterizes the change
0780: */
0781: public void valueChanged(TreeSelectionEvent e) {
0782: // store the last position
0783: oldSelectionPath = e.getOldLeadSelectionPath();
0784:
0785: // check that we don't have any alter tables
0786: if (!reselecting && controller.hasAlterTable()) {
0787: controller.applyTableChange(true);
0788: return;
0789: }
0790:
0791: Object object = e.getPath().getLastPathComponent();
0792: if (object == null) {
0793: return;
0794: }
0795:
0796: controller.selectionChanging();
0797:
0798: if (object == tree.getRootNode()) { // root node
0799: controller.displayRootPanel();
0800: enableButtons(false);
0801: return;
0802: }
0803:
0804: final BrowserTreeNode node = (BrowserTreeNode) object;
0805: // check if it is an unexpanded host node
0806: if (node.getNodeType() == BrowserConstants.HOST_NODE) {
0807: // enable buttons
0808: enableButtons(true);
0809:
0810: // check expanded state
0811: if (node.isLeaf()) {
0812: ConnectionObject metaObject = (ConnectionObject) node
0813: .getDatabaseUserObject();
0814: if (metaObject.isConnected()) {
0815: GUIUtils.invokeAndWait(new Runnable() {
0816: public void run() {
0817: doHostExpansion(node);
0818: }
0819: });
0820: //doHostExpansion(node);
0821: }
0822: }
0823: } else {
0824: enableButtons(false);
0825: }
0826:
0827: try {
0828: controller.valueChanged(getSelectedMetaObject(),
0829: (BrowserTreeNode) object, reloadView);
0830: } finally {
0831: // make sure we reset these flags
0832: reloadView = false;
0833: reselecting = false;
0834: }
0835: }
0836:
0837: private boolean connectionValid(boolean showDialog) {
0838: boolean isConnected = !(SystemUtilities.isConnected());
0839: if (!isConnected && showDialog) {
0840: GUIUtilities
0841: .displayWarningMessage("No connection available");
0842: }
0843: return isConnected;
0844: }
0845:
0846: /**
0847: * Reloads the currently selected node.
0848: */
0849: public void reloadSelection() {
0850: reloadPath(tree.getSelectionPath());
0851: }
0852:
0853: /** whether to reload the panel view */
0854: private boolean reloadView;
0855:
0856: /**
0857: * Reloads the specified tree path.
0858: */
0859: public void reloadPath(TreePath path) {
0860:
0861: if (treeExpanding) {
0862: return;
0863: }
0864:
0865: Object object = path.getLastPathComponent();
0866: if (!(object instanceof BrowserTreeNode)) {
0867: return;
0868: }
0869:
0870: BrowserTreeNode node = (BrowserTreeNode) object;
0871: doHostExpansion(node, true);
0872: }
0873:
0874: // --------------------------------------------------
0875: // ------- TreeExpansionListener implementation
0876: // --------------------------------------------------
0877:
0878: public void treeExpanded(TreeExpansionEvent e) {
0879: TreePath path = e.getPath();
0880: Object object = path.getLastPathComponent();
0881: if (!(object instanceof BrowserTreeNode)) {
0882: return;
0883: }
0884: doHostExpansion((BrowserTreeNode) object);
0885: }
0886:
0887: /** provides an indicator that an expansion is in progress */
0888: private boolean treeExpanding = false;
0889:
0890: /**
0891: * Performs the expansion on a host node.
0892: *
0893: * @param node - the host node to be expanded
0894: */
0895: private void doHostExpansion(BrowserTreeNode node) {
0896: doHostExpansion(node, false);
0897: }
0898:
0899: private synchronized void doHostExpansion(
0900: final BrowserTreeNode node, final boolean reload) {
0901: // if its already expanded - return
0902: if (node.isExpanded() && !reload) {
0903: return;
0904: }
0905:
0906: worker = new SwingWorker() {
0907: public Object construct() {
0908: try {
0909: treeExpanding = true;
0910: //Log.debug("BEFORE expanding "+treeExpanding);
0911: GUIUtilities.showWaitCursor();
0912: if (reload) {
0913: node.removeAllChildren();
0914: }
0915: return doTreeExpandedWork(node);
0916: } finally {
0917: GUIUtilities.showNormalCursor();
0918: treeExpanding = false;
0919: }
0920: }
0921:
0922: public void finished() {
0923: try {
0924: GUIUtilities.showWaitCursor();
0925: BrowserTreeNode _node = (BrowserTreeNode) get();
0926: tree.nodeStructureChanged(_node);
0927: _node.setExpanded(true);
0928:
0929: if (reload) {
0930: reloadView = true;
0931: TreePath path = tree.getSelectionPath();
0932: valueChanged(new TreeSelectionEvent(tree, path,
0933: true, oldSelectionPath, path));
0934: }
0935:
0936: } finally {
0937: GUIUtilities.showNormalCursor();
0938: treeExpanding = false;
0939: //Log.debug("AFTER expanding "+treeExpanding);
0940: }
0941: }
0942: };
0943: worker.start();
0944: }
0945:
0946: /**
0947: * Performs the tree expansion work for the expanded node.
0948: *
0949: * @param the node expanded
0950: */
0951: private BrowserTreeNode doTreeExpandedWork(BrowserTreeNode node) {
0952: DatabaseObject metaObject = node.getDatabaseUserObject();
0953: int type = metaObject.getType();
0954:
0955: switch (type) {
0956: case BrowserConstants.HOST_NODE:
0957: populateHostBranches(node);
0958: break;
0959: case BrowserConstants.CATALOG_NODE:
0960: populateSchemaBranches(node);
0961: break;
0962: case BrowserConstants.SCHEMA_NODE:
0963: populateSchemaObjectBranches(node);
0964: break;
0965: case BrowserConstants.FUNCTIONS_NODE:
0966: case BrowserConstants.INDEX_NODE:
0967: case BrowserConstants.PROCEDURE_NODE:
0968: case BrowserConstants.SEQUENCE_NODE:
0969: case BrowserConstants.SYNONYM_NODE:
0970: case BrowserConstants.SYSTEM_TABLE_NODE:
0971: case BrowserConstants.TABLE_NODE:
0972: case BrowserConstants.TRIGGER_NODE:
0973: case BrowserConstants.VIEW_NODE:
0974: case BrowserConstants.SYSTEM_FUNCTION_NODE:
0975: case BrowserConstants.SYSTEM_STRING_FUNCTIONS_NODE:
0976: case BrowserConstants.SYSTEM_NUMERIC_FUNCTIONS_NODE:
0977: case BrowserConstants.SYSTEM_DATE_TIME_FUNCTIONS_NODE:
0978: case BrowserConstants.OTHER_NODE:
0979: populateObjectBranches(node);
0980: break;
0981: }
0982:
0983: return node;
0984: }
0985:
0986: public void treeCollapsed(TreeExpansionEvent e) {
0987: } // do nothing
0988:
0989: // --------------------------------------------------
0990:
0991: /**
0992: * Populates the branches of a host (connection) node.
0993: *
0994: * @param the host node
0995: */
0996: private void populateHostBranches(BrowserTreeNode parent) {
0997: ConnectionObject object = (ConnectionObject) parent
0998: .getDatabaseUserObject();
0999:
1000: if (!object.isConnected()) {
1001: return;
1002: }
1003:
1004: BrowserTreeNode node = null;
1005: DatabaseConnection dc = object.getDatabaseConnection();
1006: String defaultCatalog = controller.getCatalogName(dc);
1007:
1008: Vector<String> values = controller.getHostedCatalogs(dc);
1009: if (values == null || values.isEmpty()) {
1010: object.setCatalogsInUse(false);
1011: DatabaseObject catalog = new DatabaseObject(
1012: BrowserConstants.CATALOG_NODE, controller
1013: .getDataSourceName(dc));
1014: catalog.setUseInQuery(false);
1015: node = new BrowserTreeNode(catalog, true);
1016: parent.add(node);
1017: } else {
1018: object.setCatalogsInUse(true);
1019: for (int i = 0, k = values.size(); i < k; i++) {
1020: String value = values.get(i);
1021: DatabaseObject catalog = new DatabaseObject(
1022: BrowserConstants.CATALOG_NODE, value);
1023: catalog.setCatalogName(value);
1024: catalog.setDefaultCatalog(defaultCatalog
1025: .equalsIgnoreCase(value));
1026: node = new BrowserTreeNode(catalog, true);
1027: parent.add(node);
1028: }
1029:
1030: }
1031:
1032: }
1033:
1034: protected BrowserTreeNode getParentNode(BrowserTreeNode child) {
1035: if (child.getDatabaseUserObject().getType() == BrowserConstants.HOST_NODE) {
1036: return child;
1037: }
1038:
1039: BrowserTreeNode _parent = null;
1040: TreeNode parent = child.getParent();
1041: while (parent != null) {
1042:
1043: if (parent instanceof BrowserTreeNode) {
1044: _parent = (BrowserTreeNode) parent;
1045:
1046: if (_parent.getDatabaseUserObject().getType() == BrowserConstants.HOST_NODE) {
1047: return _parent;
1048: }
1049: parent = _parent.getParent();
1050: }
1051:
1052: }
1053: return null;
1054: }
1055:
1056: /**
1057: * Selects the node that matches the specified prefix forward
1058: * from the currently selected node.
1059: *
1060: * @param prefix - the prefix of the node to select
1061: */
1062: protected void selectBrowserNode(final String prefix) {
1063: // make sure it has its children
1064: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
1065: .getSelectionPath().getLastPathComponent();
1066:
1067: if (node.getChildCount() == 0) {
1068: doHostExpansion((BrowserTreeNode) node);
1069: }
1070:
1071: // SwingUtilities.invokeLater(new Runnable() {
1072: // public void run() {
1073: tree.expandSelectedRow();
1074: tree.selectNextNode(prefix);
1075: // }
1076: // });
1077: }
1078:
1079: /**
1080: * Returns the available meta key names associated with the
1081: * specified child node.
1082: */
1083: protected String[] getMetaKeyNames(BrowserTreeNode child) {
1084: // get the host node for this path
1085: BrowserTreeNode parent = getParentNode(child);
1086: // get the meta data object from the host node
1087: ConnectionObject object = (ConnectionObject) parent
1088: .getDatabaseUserObject();
1089: return object.getMetaKeyNames();
1090: }
1091:
1092: /**
1093: * Returns the connection properties object associated with
1094: * the specified child node.
1095: */
1096: protected DatabaseConnection getDatabaseConnection(
1097: BrowserTreeNode child) {
1098: return getConnectionObject(child).getDatabaseConnection();
1099: }
1100:
1101: /**
1102: * Returns the ConnectionObject (host node) associated with
1103: * the specified child node.
1104: */
1105: protected ConnectionObject getConnectionObject(BrowserTreeNode child) {
1106: // get the host node for this path
1107: BrowserTreeNode parent = getParentNode(child);
1108: // get the meta data object from the host node
1109: return (ConnectionObject) parent.getDatabaseUserObject();
1110: }
1111:
1112: private void populateObjectBranches(BrowserTreeNode parent) {
1113: BrowserTreeNode node = null;
1114:
1115: DatabaseObject object = parent.getDatabaseUserObject();
1116: DatabaseConnection dc = getDatabaseConnection(parent);
1117: String defaultSchema = controller.getCatalogName(dc);
1118:
1119: boolean isDefault = defaultSchema.equalsIgnoreCase(object
1120: .getSchemaName())
1121: || defaultSchema.equalsIgnoreCase(object
1122: .getCatalogName());
1123:
1124: int type = object.getType();
1125:
1126: // populate the column nodes for table type nodes
1127: if ((type == BrowserConstants.TABLE_NODE || type == BrowserConstants.SYSTEM_TABLE_NODE)
1128: && !parent.isTypeParent()) {
1129:
1130: String[] columns = controller.getColumnNames(dc, object
1131: .getName(), object.getSchemaName());
1132:
1133: for (int i = 0; i < columns.length; i++) {
1134: DatabaseObject column = new DatabaseObject(
1135: BrowserConstants.COLUMN_NODE, columns[i]);
1136: column.setCatalogName(object.getCatalogName());
1137: column.setSchemaName(object.getSchemaName());
1138: column.setParentName(object.getName());
1139: column.setDefaultCatalog(isDefault);
1140: node = new BrowserTreeNode(column, false);
1141: parent.add(node);
1142: }
1143: }
1144:
1145: // populate the system functions types
1146: else if (type == BrowserConstants.SYSTEM_FUNCTION_NODE
1147: || type == BrowserConstants.SYSTEM_STRING_FUNCTIONS_NODE
1148: || type == BrowserConstants.SYSTEM_NUMERIC_FUNCTIONS_NODE
1149: || type == BrowserConstants.SYSTEM_DATE_TIME_FUNCTIONS_NODE) {
1150:
1151: String na = "Not Applicable";
1152: // if its the parent node add the types
1153: if (parent.isTypeParent()) {
1154: String systemFunction = "System Function";
1155: DatabaseObject table = new DatabaseObject(
1156: BrowserConstants.SYSTEM_STRING_FUNCTIONS_NODE,
1157: "String Functions");
1158: table.setSchemaName(na);
1159: table.setMetaDataKey(systemFunction);
1160: table.setSystemObject(true);
1161: node = new BrowserTreeNode(table, true, false);
1162: parent.add(node);
1163:
1164: table = new DatabaseObject(
1165: BrowserConstants.SYSTEM_NUMERIC_FUNCTIONS_NODE,
1166: "Numeric Functions");
1167: table.setSchemaName(na);
1168: table.setMetaDataKey(systemFunction);
1169: table.setSystemObject(true);
1170: node = new BrowserTreeNode(table, true, false);
1171: parent.add(node);
1172:
1173: table = new DatabaseObject(
1174: BrowserConstants.SYSTEM_DATE_TIME_FUNCTIONS_NODE,
1175: "Date/Time Functions");
1176: table.setSchemaName(na);
1177: table.setMetaDataKey(systemFunction);
1178: table.setSystemObject(true);
1179: node = new BrowserTreeNode(table, true, false);
1180: parent.add(node);
1181: }
1182:
1183: else { // add the individual functions
1184: String[] functions = null;
1185: switch (type) {
1186:
1187: case BrowserConstants.SYSTEM_STRING_FUNCTIONS_NODE:
1188: functions = controller.getSystemFunctions(dc,
1189: MetaDataValues.STRING_FUNCTIONS);
1190: break;
1191:
1192: case BrowserConstants.SYSTEM_NUMERIC_FUNCTIONS_NODE:
1193: functions = controller.getSystemFunctions(dc,
1194: MetaDataValues.NUMERIC_FUNCTIONS);
1195: break;
1196:
1197: case BrowserConstants.SYSTEM_DATE_TIME_FUNCTIONS_NODE:
1198: functions = controller.getSystemFunctions(dc,
1199: MetaDataValues.TIME_DATE_FUNCTIONS);
1200: break;
1201:
1202: }
1203:
1204: if (functions != null && functions.length > 0) {
1205:
1206: for (int i = 0; i < functions.length; i++) {
1207: DatabaseObject table = new DatabaseObject(type,
1208: functions[i]);
1209: table.setSchemaName(na);
1210: table.setMetaDataKey(object.getMetaDataKey());
1211: node = new BrowserTreeNode(table, false);
1212: parent.add(node);
1213: }
1214:
1215: }
1216:
1217: }
1218:
1219: }
1220:
1221: else {
1222: String[] tables = controller.getTables(dc, object
1223: .getCatalogName(), object.getSchemaName(), object
1224: .getName());
1225:
1226: // if we have nothing check if its a proc or function node
1227: if (tables == null || tables.length == 0) {
1228: tables = controller.checkProcedureTerm(dc, object);
1229: }
1230:
1231: for (int i = 0; i < tables.length; i++) {
1232: DatabaseObject table = new DatabaseObject(type,
1233: tables[i]);
1234: table.setCatalogName(object.getCatalogName());
1235: table.setSchemaName(object.getSchemaName());
1236: table.setMetaDataKey(object.getMetaDataKey());
1237: table.setDefaultCatalog(isDefault);
1238:
1239: if (type == BrowserConstants.TABLE_NODE
1240: || type == BrowserConstants.SYSTEM_TABLE_NODE) {
1241: node = new BrowserTreeNode(table, true, false);
1242: } else {
1243: node = new BrowserTreeNode(table, false);
1244: }
1245: parent.add(node);
1246: }
1247:
1248: }
1249:
1250: }
1251:
1252: private void populateSchemaObjectBranches(BrowserTreeNode parent) {
1253: ConnectionObject hostObject = getConnectionObject(parent);
1254: DatabaseConnection dc = hostObject.getDatabaseConnection();
1255:
1256: boolean hasKeys = true;
1257: ArrayList keyNames = null;
1258: if (!hostObject.hasMetaKeys()) {
1259: hasKeys = false;
1260: keyNames = new ArrayList(BrowserConstants.META_TYPES.length);
1261: }
1262:
1263: BrowserTreeNode node = null;
1264: DatabaseObject schema = parent.getDatabaseUserObject();
1265:
1266: for (int i = 0; i < BrowserConstants.META_TYPES.length; i++) {
1267: DatabaseObject object = new DatabaseObject(i,
1268: BrowserConstants.META_TYPES[i]);
1269: object.setCatalogName(schema.getCatalogName());
1270: object.setSchemaName(schema.getName());
1271: object.setMetaDataKey(BrowserConstants.META_TYPES[i]);
1272: node = new BrowserTreeNode(object, true);
1273: parent.add(node);
1274:
1275: if (!hasKeys) {
1276: keyNames.add(BrowserConstants.META_TYPES[i]);
1277: }
1278:
1279: }
1280:
1281: // add other non-default objects available
1282: boolean isDerivative = false;
1283: DatabaseObject object = null;
1284:
1285: String[] tableTypes = controller.getTableTypes(dc);
1286: for (int i = 0; i < tableTypes.length; i++) {
1287:
1288: if (!MiscUtils.containsValue(BrowserConstants.META_TYPES,
1289: tableTypes[i])) {
1290:
1291: if (!hasKeys) {
1292: keyNames.add(tableTypes[i]);
1293: }
1294:
1295: // check to see if the type is a derivative of a default
1296: // ie. SYSTEM INDEX is a derivative of INDEX so we use
1297: // the same icon and display format
1298: for (int j = 0; j < BrowserConstants.META_TYPES.length; j++) {
1299:
1300: if (MiscUtils.containsWholeWord(tableTypes[i],
1301: BrowserConstants.META_TYPES[j])) {
1302: isDerivative = true;
1303: object = new DatabaseObject(j, tableTypes[i]);
1304: break;
1305: }
1306:
1307: }
1308:
1309: if (!isDerivative) {
1310: object = new DatabaseObject(
1311: BrowserConstants.OTHER_NODE, tableTypes[i]);
1312: }
1313:
1314: isDerivative = false;
1315: object.setCatalogName(schema.getCatalogName());
1316: object.setSchemaName(schema.getName());
1317: object.setMetaDataKey(tableTypes[i]);
1318: node = new BrowserTreeNode(object, true);
1319: parent.add(node);
1320:
1321: }
1322:
1323: }
1324:
1325: if (!hasKeys) {
1326: hostObject.setMetaKeyNames((String[]) keyNames
1327: .toArray(new String[keyNames.size()]));
1328: }
1329:
1330: }
1331:
1332: private void populateSchemaBranches(BrowserTreeNode parent) {
1333: DatabaseConnection dc = getDatabaseConnection(parent);
1334: List schemas = controller.getCatalogSchemas(dc);
1335: String defaultSchema = controller.getSchemaName(dc);
1336:
1337: // no schemas = try by catalogue
1338: if (schemas == null || schemas.isEmpty()) {
1339: populateSchemaObjectBranches(parent);
1340: }
1341:
1342: // no schemas or catalogues available - bail
1343: if (schemas == null || schemas.isEmpty()) {
1344: return;
1345: }
1346:
1347: BrowserTreeNode node = null;
1348: DatabaseObject catalog = parent.getDatabaseUserObject();
1349: for (int i = 0, k = schemas.size(); i < k; i++) {
1350: String value = (String) schemas.get(i);
1351: DatabaseObject schema = new DatabaseObject(
1352: BrowserConstants.SCHEMA_NODE, value);
1353: schema.setCatalogName(catalog.getName());
1354: schema.setDefaultCatalog(defaultSchema
1355: .equalsIgnoreCase(value));
1356: node = new BrowserTreeNode(schema, true);
1357: parent.add(node);
1358: populateSchemaObjectBranches(node);
1359: node.setExpanded(true);
1360: }
1361:
1362: }
1363:
1364: /**
1365: * Removes the selected node.<br>
1366: *
1367: * This will attempt to propagate the call to the connected
1368: * database using a DROP statement.
1369: */
1370: public void removeTreeNode() {
1371:
1372: tree.removeTreeSelectionListener(this );
1373: int row = tree.getSelectionRows()[0];
1374:
1375: try {
1376: TreePath selection = tree.getSelectionPath();
1377: if (selection != null) {
1378:
1379: DefaultMutableTreeNode node = (DefaultMutableTreeNode) selection
1380: .getLastPathComponent();
1381:
1382: DatabaseObject object = (DatabaseObject) node
1383: .getUserObject();
1384: String name = object.getName();
1385:
1386: int yesNo = GUIUtilities
1387: .displayConfirmDialog("Are you sure you want to drop "
1388: + object.getName() + "?");
1389: if (yesNo == JOptionPane.NO_OPTION) {
1390: return;
1391: }
1392:
1393: else {
1394:
1395: try {
1396: DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node
1397: .getParent();
1398: int result = controller.dropObject(
1399: getSelectedMetaObject()
1400: .getDatabaseConnection(),
1401: object);
1402:
1403: if (result >= 0 && parent != null) {
1404: tree.removeNode(node);
1405: row = (row == 0 ? 1 : row - 1);
1406: return;
1407: }
1408:
1409: } catch (SQLException e) {
1410: StringBuffer sb = new StringBuffer();
1411: sb
1412: .append(
1413: "An error occurred removing the selected object.")
1414: .append("\n\nThe system returned:\n")
1415: .append(MiscUtils.formatSQLError(e));
1416: GUIUtilities.displayExceptionErrorDialog(sb
1417: .toString(), e);
1418: }
1419:
1420: }
1421:
1422: }
1423: } finally {
1424: tree.addTreeSelectionListener(this );
1425: tree.setSelectionRow(row);
1426: }
1427:
1428: }
1429:
1430: /**
1431: * Returns the name of a new connection to be added where
1432: * the name of the connection may already exist.
1433: *
1434: * @param name - the name of the connection
1435: */
1436: private String buildConnectionName(String name) {
1437: int count = 0;
1438: for (int i = 0, n = connections.size(); i < n; i++) {
1439: DatabaseConnection _dc = connections.get(i);
1440: if (_dc.getName().startsWith(name)) {
1441: count++;
1442: }
1443: }
1444:
1445: if (count > 0) {
1446: count++;
1447: name += " " + count;
1448: }
1449: return name;
1450: }
1451:
1452: public boolean isRootSelectOnDisconnect() {
1453: return rootSelectOnDisconnect;
1454: }
1455:
1456: public void setRootSelectOnDisconnect(boolean rootSelectOnDisconnect) {
1457: this .rootSelectOnDisconnect = rootSelectOnDisconnect;
1458: }
1459:
1460: public String toString() {
1461: return TITLE;
1462: }
1463:
1464: public static final String MENU_ITEM_KEY = "viewConnections";
1465:
1466: public static final String PROPERTY_KEY = "system.display.connections";
1467:
1468: // ----------------------------------------
1469: // DockedTabView Implementation
1470: // ----------------------------------------
1471:
1472: /**
1473: * Returns the display title for this view.
1474: *
1475: * @return the title displayed for this view
1476: */
1477: public String getTitle() {
1478: return TITLE;
1479: }
1480:
1481: /**
1482: * Returns the name defining the property name for this docked tab view.
1483: *
1484: * @return the key
1485: */
1486: public String getPropertyKey() {
1487: return PROPERTY_KEY;
1488: }
1489:
1490: /**
1491: * Returns the name defining the menu cache property
1492: * for this docked tab view.
1493: *
1494: * @return the preferences key
1495: */
1496: public String getMenuItemKey() {
1497: return MENU_ITEM_KEY;
1498: }
1499:
1500: /** The tree's popup menu function */
1501: private class PopMenu extends JPopupMenu {
1502:
1503: private JMenuItem addNewConnection;
1504: private JMenuItem connect;
1505: private JMenuItem disconnect;
1506: private JMenuItem reload;
1507: private JMenuItem duplicate;
1508: private JMenuItem delete;
1509: private JMenuItem recycleConnection;
1510:
1511: private JMenu exportData;
1512: private JMenu importData;
1513:
1514: protected TreePath popupPath;
1515: protected DatabaseConnection hover;
1516:
1517: public PopMenu() {
1518: ActionListener listener = new PopupMenuActionListener();
1519:
1520: addNewConnection = createMenuItem("New Connection",
1521: "addNewConnection", listener);
1522: add(addNewConnection);
1523:
1524: addSeparator();
1525:
1526: reload = createMenuItem("Reload", "reload", listener);
1527: add(reload);
1528: recycleConnection = createMenuItem(
1529: "Recycle this connection", "recycle", listener);
1530: add(recycleConnection);
1531:
1532: addSeparator();
1533:
1534: connect = createMenuItem("Connect", "connect", listener);
1535: add(connect);
1536: disconnect = createMenuItem("Disconnect", "disconnect",
1537: listener);
1538: add(disconnect);
1539:
1540: addSeparator();
1541:
1542: duplicate = createMenuItem("Duplicate", "duplicate",
1543: listener);
1544: add(duplicate);
1545: delete = createMenuItem("Delete", "delete", listener);
1546: add(delete);
1547:
1548: addSeparator();
1549:
1550: exportData = new JMenu("Export Data");
1551: exportData.add(createMenuItem("Export to XML File",
1552: "exportXml", listener));
1553: exportData.add(createMenuItem("Export to Delimited File",
1554: "exportDelimited", listener));
1555: exportData.add(createMenuItem(
1556: "Export to Excel Spreadsheet", "exportExcel",
1557: listener));
1558: add(exportData);
1559:
1560: importData = new JMenu("Import Data");
1561: importData.add(createMenuItem("Import from XML File",
1562: "importXml", listener));
1563: importData.add(createMenuItem("Import from Delimited File",
1564: "importDelimited", listener));
1565: add(importData);
1566:
1567: addSeparator();
1568: add(createMenuItem("Connection Properties", "properties",
1569: listener));
1570: }
1571:
1572: private JMenuItem createMenuItem(String text,
1573: String actionCommand, ActionListener listener) {
1574: JMenuItem menuItem = new JMenuItem(text);
1575: menuItem.setActionCommand(actionCommand);
1576: menuItem.addActionListener(listener);
1577: return menuItem;
1578: }
1579:
1580: public void setToConnect(boolean canConnect) {
1581: connect.setEnabled(canConnect);
1582: disconnect.setEnabled(!canConnect);
1583: delete.setEnabled(canConnect);
1584:
1585: String label = null;
1586: // check whether reload is available
1587: if (popupPath != null) {
1588: Object object = popupPath.getLastPathComponent();
1589: if (object instanceof BrowserTreeNode) {
1590: BrowserTreeNode node = (BrowserTreeNode) object;
1591: if (node.getUserObject() instanceof ConnectionObject) {
1592: reload.setEnabled(false);
1593: exportData.setEnabled(false);
1594: importData.setEnabled(false);
1595: recycleConnection.setEnabled(!canConnect);
1596: } else {
1597: label = node.toString();
1598: reload.setEnabled(true);
1599: recycleConnection.setEnabled(false);
1600:
1601: boolean importExport = (node
1602: .getDatabaseUserObject().getType() == BrowserConstants.TABLE_NODE && !node
1603: .isTypeParent());
1604: exportData.setEnabled(importExport);
1605: importData.setEnabled(importExport);
1606: }
1607: }
1608: }
1609:
1610: // re-label the menu items
1611: if (hover != null) {
1612: String name = hover.getName();
1613: connect.setText("Connect Data Source " + name);
1614: disconnect.setText("Disconnect Data Source " + name);
1615: delete.setText("Remove Data Source " + name);
1616: duplicate.setText("Create Duplicate of Data Source "
1617: + name);
1618:
1619: if (label != null) {
1620: reload.setText("Reload " + label);
1621: } else {
1622: reload.setText("Reload");
1623: }
1624:
1625: }
1626:
1627: }
1628:
1629: }
1630:
1631: // declared public un-intentionally here for the reflective
1632: // action extension and its use to work correctly.
1633: // may need to revise !!??
1634: public class PopupMenuActionListener extends ReflectiveAction {
1635:
1636: public PopupMenuActionListener() {
1637: }
1638:
1639: public void actionPerformed(ActionEvent e) {
1640: try {
1641: super .actionPerformed(e);
1642: } finally {
1643: reloadView = false;
1644: popupMenu.hover = null;
1645: popupMenu.popupPath = null;
1646: }
1647: }
1648:
1649: public void addNewConnection(ActionEvent e) {
1650: newConnection();
1651: }
1652:
1653: public void delete(ActionEvent e) {
1654: if (popupMenu.popupPath != null) {
1655: BrowserTreeNode node = (BrowserTreeNode) popupMenu.popupPath
1656: .getLastPathComponent();
1657: deleteConnection(node);
1658: }
1659: }
1660:
1661: public void recycle(ActionEvent e) {
1662: ConnectionObject dbObject = getSelectedMetaObject();
1663: controller.recycleConnection(dbObject
1664: .getDatabaseConnection());
1665: }
1666:
1667: public void reload(ActionEvent e) {
1668: if (popupMenu.popupPath != null) {
1669: reloadPath(popupMenu.popupPath);
1670: }
1671: }
1672:
1673: public void disconnect(ActionEvent e) {
1674: // check if the selected node belongs to the
1675: // connection about to closed
1676: boolean selectHover = (getSelectedDatabaseConnection() == popupMenu.hover);
1677: controller.connect(popupMenu.hover, false);
1678:
1679: //System.err.println("selectHover: " + selectHover);
1680:
1681: if (selectHover) {
1682: try {
1683: reloadView = true;
1684: setSelectedConnection(popupMenu.hover);
1685: // select the properties panel for the
1686: // just closed connection
1687: /*
1688: controller.valueChanged(
1689: getSelectedMetaObject(),
1690: (BrowserTreeNode)popupPath.getLastPathComponent(),
1691: false);
1692: */
1693: } finally {
1694: reloadView = false;
1695: }
1696: }
1697: }
1698:
1699: public void duplicate(ActionEvent e) {
1700: if (popupMenu.hover != null) {
1701: String name = buildConnectionName(popupMenu.hover
1702: .getName()
1703: + " (Copy")
1704: + ")";
1705:
1706: DatabaseConnection dc = new DatabaseConnection(name);
1707: dc
1708: .setPasswordStored(popupMenu.hover
1709: .isPasswordStored());
1710: dc.setPasswordEncrypted(popupMenu.hover
1711: .isPasswordEncrypted());
1712: dc.setDriverId(popupMenu.hover.getDriverId());
1713: dc.setDatabaseType(popupMenu.hover.getDatabaseType());
1714: dc.setHost(popupMenu.hover.getHost());
1715: dc.setPort(popupMenu.hover.getPort());
1716: dc.setSourceName(popupMenu.hover.getSourceName());
1717: dc.setTransactionIsolation(popupMenu.hover
1718: .getTransactionIsolation());
1719: dc.setURL(popupMenu.hover.getURL());
1720: dc.setUserName(popupMenu.hover.getUserName());
1721:
1722: if (popupMenu.hover.getJdbcProperties() != null) {
1723: dc.setJdbcProperties((Properties) popupMenu.hover
1724: .getJdbcProperties().clone());
1725: }
1726:
1727: if (dc.isPasswordEncrypted()) {
1728: dc.setEncryptedPassword(popupMenu.hover
1729: .getPassword());
1730: } else {
1731: dc.setPassword(popupMenu.hover.getPassword());
1732: }
1733:
1734: newConnection(dc);
1735: }
1736:
1737: }
1738:
1739: public void exportExcel(ActionEvent e) {
1740: importExportDialog(ImportExportProcess.EXCEL);
1741: }
1742:
1743: public void importXml(ActionEvent e) {
1744: importExportDialog(ImportExportProcess.IMPORT_XML);
1745: }
1746:
1747: public void exportXml(ActionEvent e) {
1748: importExportDialog(ImportExportProcess.EXPORT_XML);
1749: }
1750:
1751: public void importDelimited(ActionEvent e) {
1752: importExportDialog(ImportExportProcess.IMPORT_DELIMITED);
1753: }
1754:
1755: public void exportDelimited(ActionEvent e) {
1756: importExportDialog(ImportExportProcess.EXPORT_DELIMITED);
1757: }
1758:
1759: public void properties(ActionEvent e) {
1760: reloadView = true;
1761: setSelectedConnection(popupMenu.hover);
1762: }
1763:
1764: public void connect(ActionEvent e) {
1765: controller.connect(popupMenu.hover, false);
1766: }
1767:
1768: private void importExportDialog(int transferType) {
1769: BaseDialog dialog = null;
1770: JPanel panel = null;
1771:
1772: DatabaseConnection dc = getSelectedDatabaseConnection();
1773: String schemaName = getSelectedDatabaseObject()
1774: .getSchemaName();
1775: String tableName = getSelectedDatabaseObject().getName();
1776:
1777: try {
1778: GUIUtilities.showWaitCursor();
1779: switch (transferType) {
1780: case ImportExportProcess.EXPORT_DELIMITED:
1781: dialog = new BaseDialog("Export Data", false, false);
1782: panel = new ImportExportDelimitedPanel(dialog,
1783: ImportExportProcess.EXPORT, dc, schemaName,
1784: tableName);
1785: break;
1786:
1787: case ImportExportProcess.IMPORT_DELIMITED:
1788: dialog = new BaseDialog("Import Data", false, false);
1789: panel = new ImportExportDelimitedPanel(dialog,
1790: ImportExportProcess.IMPORT, dc, schemaName,
1791: tableName);
1792: break;
1793:
1794: case ImportExportProcess.EXPORT_XML:
1795: dialog = new BaseDialog("Export XML", false, false);
1796: panel = new ImportExportXMLPanel(dialog,
1797: ImportExportProcess.EXPORT, dc, schemaName,
1798: tableName);
1799: break;
1800:
1801: case ImportExportProcess.IMPORT_XML:
1802: dialog = new BaseDialog("Import XML", false, false);
1803: panel = new ImportExportXMLPanel(dialog,
1804: ImportExportProcess.IMPORT, dc, schemaName,
1805: tableName);
1806: break;
1807:
1808: case ImportExportProcess.EXCEL:
1809: dialog = new BaseDialog("Export Excel Spreadsheet",
1810: false, false);
1811: panel = new ImportExportExcelPanel(dialog,
1812: ImportExportProcess.EXPORT, dc, schemaName,
1813: tableName);
1814: break;
1815:
1816: }
1817:
1818: dialog.addDisplayComponent(panel);
1819: dialog.display();
1820: } finally {
1821: GUIUtilities.showNormalCursor();
1822: }
1823: }
1824:
1825: }
1826:
1827: private boolean reselecting;
1828:
1829: private class MouseHandler extends MouseAdapter {
1830:
1831: public MouseHandler() {
1832: }
1833:
1834: public void mouseClicked(MouseEvent e) {
1835: if (e.getClickCount() < 2) {
1836: reselecting = false;
1837: return;
1838: }
1839: TreePath path = tree.getPathForLocation(e.getX(), e.getY());
1840: if (path != null && path == tree.getSelectionPath()) {
1841: reselecting = true;
1842: valueChanged(new TreeSelectionEvent(tree, path, true,
1843: oldSelectionPath, path));
1844: }
1845: }
1846:
1847: public void mousePressed(MouseEvent e) {
1848: maybeShowPopup(e);
1849: }
1850:
1851: public void mouseReleased(MouseEvent e) {
1852: maybeShowPopup(e);
1853: }
1854:
1855: private void maybeShowPopup(MouseEvent e) {
1856: if (e.isPopupTrigger()) {
1857:
1858: if (popupMenu == null) {
1859: popupMenu = new PopMenu();
1860: }
1861:
1862: Point point = new Point(e.getX(), e.getY());
1863: popupMenu.popupPath = tree.getPathForLocation(point.x,
1864: point.y);
1865: // get the connection at this point
1866: popupMenu.hover = getConnectionAt(point);
1867: if (popupMenu.hover != null) {
1868: try {
1869: // enable/disable items
1870: popupMenu.setToConnect(!popupMenu.hover
1871: .isConnected());
1872: tree
1873: .removeTreeSelectionListener(ConnectionsTreePanel.this);
1874: tree.setSelectionPath(popupMenu.popupPath);
1875: } finally {
1876: tree
1877: .addTreeSelectionListener(ConnectionsTreePanel.this);
1878: }
1879: popupMenu.show(e.getComponent(), point.x, point.y);
1880: }
1881: }
1882: }
1883:
1884: }
1885:
1886: }
|