0001: /*
0002: * TableListPanel.java
0003: *
0004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
0005: *
0006: * Copyright 2002-2008, Thomas Kellerer
0007: * No part of this code maybe reused without the permission of the author
0008: *
0009: * To contact the author please send an email to: support@sql-workbench.net
0010: *
0011: */
0012: package workbench.gui.dbobjects;
0013:
0014: import java.awt.BorderLayout;
0015: import java.awt.Component;
0016: import java.awt.Dimension;
0017: import java.awt.EventQueue;
0018: import java.awt.FlowLayout;
0019: import java.awt.Frame;
0020: import java.awt.GridBagConstraints;
0021: import java.awt.GridBagLayout;
0022: import java.awt.Toolkit;
0023: import java.awt.Window;
0024: import java.awt.event.ActionEvent;
0025: import java.awt.event.ActionListener;
0026: import java.awt.event.MouseEvent;
0027: import java.awt.event.MouseListener;
0028: import java.beans.PropertyChangeEvent;
0029: import java.beans.PropertyChangeListener;
0030: import java.io.File;
0031: import java.sql.SQLException;
0032: import java.util.ArrayList;
0033: import java.util.Collection;
0034: import java.util.List;
0035: import javax.swing.ActionMap;
0036: import javax.swing.ComponentInputMap;
0037: import javax.swing.InputMap;
0038: import javax.swing.JComboBox;
0039: import javax.swing.JDialog;
0040: import javax.swing.JFrame;
0041: import javax.swing.JLabel;
0042: import javax.swing.JPanel;
0043: import javax.swing.JSplitPane;
0044: import javax.swing.JTabbedPane;
0045: import javax.swing.JTable;
0046: import javax.swing.ListSelectionModel;
0047: import javax.swing.SwingConstants;
0048: import javax.swing.SwingUtilities;
0049: import javax.swing.border.EmptyBorder;
0050: import javax.swing.event.ChangeEvent;
0051: import javax.swing.event.ChangeListener;
0052: import javax.swing.event.ListSelectionEvent;
0053: import javax.swing.event.ListSelectionListener;
0054: import javax.swing.event.TableModelEvent;
0055: import javax.swing.event.TableModelListener;
0056: import javax.swing.table.TableModel;
0057: import workbench.db.DbMetadata;
0058: import workbench.db.DbSettings;
0059: import workbench.db.TableIdentifier;
0060: import workbench.db.WbConnection;
0061: import workbench.db.exporter.DataExporter;
0062: import workbench.gui.MainWindow;
0063: import workbench.gui.WbSwingUtilities;
0064: import workbench.gui.actions.ReloadAction;
0065: import workbench.gui.actions.SpoolDataAction;
0066: import workbench.gui.actions.ToggleTableSourceAction;
0067: import workbench.gui.actions.WbAction;
0068: import workbench.gui.components.DataStoreTableModel;
0069: import workbench.gui.components.QuickFilterPanel;
0070: import workbench.gui.components.WbScrollPane;
0071: import workbench.gui.components.WbSplitPane;
0072: import workbench.gui.components.WbTable;
0073: import workbench.gui.components.WbTraversalPolicy;
0074: import workbench.gui.dialogs.export.ExportFileDialog;
0075: import workbench.interfaces.ProgressReporter;
0076: import workbench.interfaces.PropertyStorage;
0077: import workbench.interfaces.ShareableDisplay;
0078: import workbench.interfaces.Exporter;
0079: import workbench.log.LogMgr;
0080: import workbench.resource.ResourceMgr;
0081: import workbench.resource.Settings;
0082: import workbench.storage.DataStore;
0083: import workbench.util.StringUtil;
0084: import workbench.util.WbThread;
0085: import workbench.util.ExceptionUtil;
0086: import workbench.WbManager;
0087: import workbench.db.DbObject;
0088: import workbench.db.IndexDefinition;
0089: import workbench.db.SequenceDefinition;
0090: import workbench.gui.actions.CompileDbObjectAction;
0091: import workbench.gui.actions.CreateDummySqlAction;
0092: import workbench.gui.actions.DeleteTablesAction;
0093: import workbench.gui.actions.DropDbObjectAction;
0094: import workbench.gui.actions.SchemaReportAction;
0095: import workbench.gui.actions.ScriptDbObjectAction;
0096: import workbench.gui.components.WbTabbedPane;
0097: import workbench.gui.sql.PanelContentSender;
0098: import workbench.interfaces.CriteriaPanel;
0099: import workbench.interfaces.DbExecutionListener;
0100: import workbench.interfaces.Reloadable;
0101: import workbench.util.WbWorkspace;
0102: import workbench.util.WbProperties;
0103:
0104: /**
0105: * @author support@sql-workbench.net
0106: */
0107: public class TableListPanel extends JPanel implements ActionListener,
0108: ChangeListener, ListSelectionListener, MouseListener,
0109: ShareableDisplay, Exporter, PropertyChangeListener,
0110: TableModelListener, DbObjectList {
0111: // <editor-fold defaultstate="collapsed" desc=" Variables ">
0112: protected WbConnection dbConnection;
0113: protected JPanel listPanel;
0114: protected CriteriaPanel findPanel;
0115: protected WbTable tableList;
0116: protected TableDefinitionPanel tableDefinition;
0117: protected WbTable indexes;
0118: protected WbTable importedKeys;
0119: protected WbTable exportedKeys;
0120:
0121: protected TableDataPanel tableData;
0122:
0123: private TableDependencyTreeDisplay importedTableTree;
0124: private WbSplitPane importedPanel;
0125:
0126: private TableDependencyTreeDisplay exportedTableTree;
0127: private WbSplitPane exportedPanel;
0128:
0129: private JPanel indexPanel;
0130: private TriggerDisplayPanel triggers;
0131: protected DbObjectSourcePanel tableSource;
0132: private JTabbedPane displayTab;
0133: private WbSplitPane splitPane;
0134:
0135: private JComboBox tableTypes = new JComboBox();
0136: private String currentSchema;
0137: private String currentCatalog;
0138: private SpoolDataAction spoolData;
0139:
0140: private CompileDbObjectAction compileAction;
0141:
0142: private MainWindow parentWindow;
0143:
0144: private TableIdentifier selectedTable;
0145:
0146: // For synonym resolution
0147: private TableIdentifier realTable;
0148:
0149: private boolean shiftDown = false;
0150: protected boolean shouldRetrieve;
0151:
0152: protected boolean shouldRetrieveTable;
0153: protected boolean shouldRetrieveTableSource;
0154: protected boolean shouldRetrieveTriggers;
0155: protected boolean shouldRetrieveIndexes;
0156: protected boolean shouldRetrieveExportedKeys;
0157: protected boolean shouldRetrieveImportedKeys;
0158: protected boolean shouldRetrieveExportedTree;
0159: protected boolean shouldRetrieveImportedTree;
0160: protected boolean shouldRetrieveTableDataCount;
0161:
0162: protected boolean busy;
0163: protected boolean ignoreStateChanged = false;
0164:
0165: private EditorTabSelectMenu showDataMenu;
0166:
0167: private ToggleTableSourceAction toggleTableSource;
0168:
0169: // holds a reference to other WbTables which
0170: // need to display the same table list
0171: // e.g. the table search panel
0172: private List<JTable> tableListClients;
0173:
0174: protected JDialog infoWindow;
0175: private JLabel infoLabel;
0176: private JLabel tableInfoLabel;
0177: private String tableTypeToSelect;
0178:
0179: // </editor-fold>
0180:
0181: public TableListPanel(MainWindow aParent) throws Exception {
0182: this .parentWindow = aParent;
0183: this .setBorder(WbSwingUtilities.EMPTY_BORDER);
0184: String tabLocation = Settings.getInstance().getProperty(
0185: "workbench.gui.dbobjects.tabletabs", "bottom");
0186: int location = JTabbedPane.BOTTOM;
0187: if (tabLocation.equalsIgnoreCase("top")) {
0188: location = JTabbedPane.TOP;
0189: } else if (tabLocation.equalsIgnoreCase("left")) {
0190: location = JTabbedPane.LEFT;
0191: } else if (tabLocation.equalsIgnoreCase("right")) {
0192: location = JTabbedPane.RIGHT;
0193: }
0194: this .displayTab = new WbTabbedPane(location);
0195:
0196: this .tableDefinition = new TableDefinitionPanel();
0197: this .tableDefinition.addPropertyChangeListener(
0198: TableDefinitionPanel.INDEX_PROP, this );
0199: this .displayTab.add(ResourceMgr
0200: .getString("TxtDbExplorerTableDefinition"),
0201: tableDefinition);
0202:
0203: Reloadable indexReload = new Reloadable() {
0204: public void reload() {
0205: shouldRetrieveIndexes = true;
0206: if (dbConnection.isBusy())
0207: return;
0208: try {
0209: dbConnection.setBusy(true);
0210: retrieveIndexes();
0211: } catch (SQLException e) {
0212: LogMgr.logError("TableListPanel.indexReloader",
0213: "Error retrieving indexes", e);
0214: } finally {
0215: dbConnection.setBusy(false);
0216: }
0217: }
0218: };
0219:
0220: this .indexes = new WbTable();
0221: this .indexes.setAdjustToColumnLabel(false);
0222: this .indexes.setSelectOnRightButtonClick(true);
0223: this .indexPanel = new TableIndexPanel(this .indexes, indexReload);
0224:
0225: Reloadable sourceReload = new Reloadable() {
0226: public void reload() {
0227: shouldRetrieveTable = true;
0228: if (dbConnection.isBusy())
0229: return;
0230:
0231: try {
0232: dbConnection.setBusy(true);
0233: retrieveTableSource();
0234: } finally {
0235: dbConnection.setBusy(false);
0236: }
0237: }
0238: };
0239:
0240: this .tableSource = new DbObjectSourcePanel(aParent,
0241: sourceReload);
0242:
0243: this .displayTab.add(ResourceMgr
0244: .getString("TxtDbExplorerSource"), this .tableSource);
0245: this .tableData = new TableDataPanel();
0246: this .tableData.setResultContainer(aParent);
0247:
0248: this .importedKeys = new WbTable();
0249: this .importedKeys.setAdjustToColumnLabel(false);
0250: WbScrollPane scroll = new WbScrollPane(this .importedKeys);
0251: this .importedPanel = new WbSplitPane(JSplitPane.VERTICAL_SPLIT);
0252: this .importedPanel.setDividerLocation(100);
0253: this .importedPanel.setDividerSize(6);
0254: this .importedPanel.setTopComponent(scroll);
0255: this .importedTableTree = new TableDependencyTreeDisplay();
0256: this .importedPanel.setBottomComponent(this .importedTableTree);
0257:
0258: this .exportedKeys = new WbTable();
0259: this .exportedKeys.setAdjustToColumnLabel(false);
0260: scroll = new WbScrollPane(this .exportedKeys);
0261: this .exportedPanel = new WbSplitPane(JSplitPane.VERTICAL_SPLIT);
0262: this .exportedPanel.setDividerLocation(100);
0263: this .exportedPanel.setDividerSize(5);
0264: this .exportedPanel.setTopComponent(scroll);
0265: this .exportedTableTree = new TableDependencyTreeDisplay();
0266: this .exportedPanel.setBottomComponent(this .exportedTableTree);
0267:
0268: this .triggers = new TriggerDisplayPanel();
0269:
0270: this .listPanel = new JPanel();
0271: this .tableList = new DbObjectTable();
0272: this .tableList.setSelectOnRightButtonClick(true);
0273: this .tableList.getSelectionModel().addListSelectionListener(
0274: this );
0275: this .tableList.getSelectionModel().setSelectionMode(
0276: ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
0277: this .tableList.setAdjustToColumnLabel(true);
0278: this .tableList.addTableModelListener(this );
0279:
0280: this .spoolData = new SpoolDataAction(this );
0281: this .tableList.addPopupAction(spoolData, true);
0282:
0283: this .extendPopupMenu();
0284:
0285: String[] s = new String[] { "NAME", "TYPE", "CATALOG",
0286: "SCHEMA", "REMARKS" };
0287: this .findPanel = new QuickFilterPanel(this .tableList, s, false,
0288: "tablelist");
0289:
0290: ReloadAction a = new ReloadAction(this );
0291: a.getToolbarButton().setToolTipText(
0292: ResourceMgr.getString("TxtRefreshTableList"));
0293: a.addToInputMap(tableList);
0294:
0295: this .findPanel.addToToolbar(a, true, false);
0296:
0297: JPanel selectPanel = new JPanel();
0298: selectPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
0299:
0300: JPanel topPanel = new JPanel();
0301: topPanel.setLayout(new GridBagLayout());
0302: GridBagConstraints constr = new GridBagConstraints();
0303: constr.anchor = GridBagConstraints.WEST;
0304: constr.gridx = 0;
0305:
0306: topPanel.add(this .tableTypes, constr);
0307:
0308: constr = new GridBagConstraints();
0309: constr.anchor = GridBagConstraints.WEST;
0310: constr.gridwidth = GridBagConstraints.REMAINDER;
0311: constr.fill = GridBagConstraints.HORIZONTAL;
0312: constr.weightx = 1.0;
0313: topPanel.add((JPanel) this .findPanel, constr);
0314:
0315: this .listPanel.setLayout(new BorderLayout());
0316: this .listPanel.add(topPanel, BorderLayout.NORTH);
0317:
0318: this .tableInfoLabel = new JLabel("");
0319:
0320: EmptyBorder b = new EmptyBorder(1, 3, 0, 0);
0321: this .tableInfoLabel.setBorder(b);
0322: this .listPanel.add(this .tableInfoLabel, BorderLayout.SOUTH);
0323:
0324: this .splitPane = new WbSplitPane(JSplitPane.HORIZONTAL_SPLIT);
0325: scroll = new WbScrollPane(this .tableList);
0326:
0327: this .listPanel.add(scroll, BorderLayout.CENTER);
0328: this .listPanel.setBorder(WbSwingUtilities.EMPTY_BORDER);
0329:
0330: this .splitPane.setLeftComponent(this .listPanel);
0331: this .splitPane.setRightComponent(displayTab);
0332: this .splitPane.setDividerSize(5);
0333: this .splitPane.setDividerBorder(WbSwingUtilities.EMPTY_BORDER);
0334: this .splitPane.setOneTouchExpandable(true);
0335: this .splitPane.setContinuousLayout(true);
0336:
0337: this .setLayout(new BorderLayout());
0338: this .add(splitPane, BorderLayout.CENTER);
0339:
0340: WbTraversalPolicy pol = new WbTraversalPolicy();
0341: pol.setDefaultComponent((JPanel) findPanel);
0342: pol.addComponent((JPanel) findPanel);
0343: pol.addComponent(tableList);
0344: pol.addComponent(tableDefinition);
0345: this .setFocusTraversalPolicy(pol);
0346: this .setFocusCycleRoot(false);
0347: this .displayTab.addMouseListener(this );
0348: this .tableList.addMouseListener(this );
0349:
0350: initIndexDropper(indexReload);
0351:
0352: this .toggleTableSource = new ToggleTableSourceAction(this );
0353: this .splitPane.setOneTouchTooltip(toggleTableSource
0354: .getTooltipTextWithKeys());
0355: setupActionMap();
0356:
0357: if (Settings.getInstance().showFocusInDbExplorer()) {
0358: EventQueue.invokeLater(new Runnable() {
0359: public void run() {
0360: tableDefinition.showFocusBorder();
0361: indexes.showFocusBorder();
0362: tableList.showFocusBorder();
0363: tableData.showFocusBorder();
0364: }
0365: });
0366: }
0367: }
0368:
0369: private void initIndexDropper(Reloadable indexReload) {
0370: DbObjectList indexList = new DbObjectList() {
0371: public Component getComponent() {
0372: return TableListPanel.this ;
0373: }
0374:
0375: public WbConnection getConnection() {
0376: return dbConnection;
0377: }
0378:
0379: public TableIdentifier getObjectTable() {
0380: return TableListPanel.this .getObjectTable();
0381: }
0382:
0383: public List<DbObject> getSelectedObjects() {
0384: int[] rows = indexes.getSelectedRows();
0385: if (rows == null)
0386: return null;
0387:
0388: ArrayList<DbObject> objects = new ArrayList<DbObject>(
0389: rows.length);
0390:
0391: TableIdentifier tbl = getObjectTable();
0392: String schema = (tbl == null ? null : tbl.getSchema());
0393:
0394: for (int i = 0; i < rows.length; i++) {
0395: String name = indexes
0396: .getValueAsString(
0397: rows[i],
0398: DbMetadata.COLUMN_IDX_TABLE_INDEXLIST_INDEX_NAME);
0399: IndexDefinition index = new IndexDefinition(tbl,
0400: schema, name, null);
0401: objects.add(index);
0402: }
0403: return objects;
0404: }
0405: };
0406:
0407: DropDbObjectAction dropAction = new DropDbObjectAction(
0408: "MnuTxtDropIndex", indexList, indexes
0409: .getSelectionModel(), indexReload);
0410: this .indexes.addPopupAction(dropAction, true);
0411: }
0412:
0413: public void dispose() {
0414: this .reset();
0415: this .tableDefinition.removePropertyChangeListener(this );
0416: this .tableData.dispose();
0417: }
0418:
0419: private void extendPopupMenu() {
0420: if (this .parentWindow != null) {
0421: this .showDataMenu = new EditorTabSelectMenu(this ,
0422: ResourceMgr.getString("MnuTxtShowTableData"),
0423: "LblShowDataInNewTab", "LblShowDataInTab",
0424: parentWindow);
0425: this .showDataMenu.setEnabled(false);
0426: this .tableList.addPopupMenu(this .showDataMenu, false);
0427: }
0428:
0429: this .tableList.addPopupAction(CreateDummySqlAction
0430: .createDummyInsertAction(this , tableList
0431: .getSelectionModel()), true);
0432: this .tableList.addPopupAction(CreateDummySqlAction
0433: .createDummySelectAction(this , tableList
0434: .getSelectionModel()), false);
0435:
0436: ScriptDbObjectAction createScript = new ScriptDbObjectAction(
0437: this , tableList.getSelectionModel());
0438: this .tableList.addPopupAction(createScript, false);
0439:
0440: SchemaReportAction action = new SchemaReportAction(this );
0441: tableList.addPopupMenu(action.getMenuItem(), false);
0442:
0443: compileAction = new CompileDbObjectAction(this , tableList
0444: .getSelectionModel());
0445: tableList.addPopupAction(compileAction, false);
0446:
0447: DropDbObjectAction dropAction = new DropDbObjectAction(this ,
0448: this .tableList.getSelectionModel(), this );
0449: tableList.addPopupAction(dropAction, true);
0450:
0451: tableList.addPopupAction(new DeleteTablesAction(this , tableList
0452: .getSelectionModel(), this .tableData), false);
0453: }
0454:
0455: public void setDbExecutionListener(DbExecutionListener l) {
0456: if (l != null) {
0457: tableData.addDbExecutionListener(l);
0458: }
0459: }
0460:
0461: private void setupActionMap() {
0462: InputMap im = new ComponentInputMap(this );
0463: ActionMap am = new ActionMap();
0464: this .setInputMap(WHEN_IN_FOCUSED_WINDOW, im);
0465: this .setActionMap(am);
0466:
0467: this .toggleTableSource.addToInputMap(im, am);
0468: }
0469:
0470: protected void addTablePanels() {
0471: WbSwingUtilities.invoke(new Runnable() {
0472: public void run() {
0473: try {
0474: if (displayTab.getComponentCount() > 3)
0475: return;
0476: ignoreStateChanged = true;
0477: if (displayTab.getComponentCount() == 2)
0478: addDataPanel();
0479: displayTab.add(ResourceMgr
0480: .getString("TxtDbExplorerIndexes"),
0481: indexPanel);
0482: displayTab.add(ResourceMgr
0483: .getString("TxtDbExplorerFkColumns"),
0484: importedPanel);
0485: displayTab
0486: .add(
0487: ResourceMgr
0488: .getString("TxtDbExplorerReferencedColumns"),
0489: exportedPanel);
0490: displayTab.add(ResourceMgr
0491: .getString("TxtDbExplorerTriggers"),
0492: triggers);
0493: } finally {
0494: ignoreStateChanged = false;
0495: }
0496: }
0497: });
0498: }
0499:
0500: private void removeTablePanels(final boolean includeDataPanel) {
0501: WbSwingUtilities.invoke(new Runnable() {
0502: public void run() {
0503: try {
0504: int index = displayTab.getSelectedIndex();
0505: ignoreStateChanged = true;
0506:
0507: displayTab.setSelectedIndex(0);
0508:
0509: int count = displayTab.getTabCount();
0510:
0511: if (count < 3 && includeDataPanel)
0512: return;
0513:
0514: if (count >= 3 && includeDataPanel)
0515: removeDataPanel();
0516:
0517: displayTab.remove(indexPanel);
0518: indexes.reset();
0519: displayTab.remove(importedPanel);
0520: importedKeys.reset();
0521: displayTab.remove(exportedPanel);
0522: exportedKeys.reset();
0523: displayTab.remove(triggers);
0524: triggers.reset();
0525: if (index < displayTab.getTabCount()) {
0526: displayTab.setSelectedIndex(index);
0527: }
0528: } finally {
0529: ignoreStateChanged = false;
0530: }
0531: }
0532: });
0533: }
0534:
0535: protected void addDataPanel() {
0536: WbSwingUtilities.invoke(new Runnable() {
0537: public void run() {
0538: displayTab.add(ResourceMgr
0539: .getString("TxtDbExplorerData"), tableData);
0540: }
0541: });
0542: }
0543:
0544: protected void removeDataPanel() {
0545: this .displayTab.remove(this .tableData);
0546: this .tableData.reset();
0547: }
0548:
0549: private boolean sourceExpanded = false;
0550:
0551: public void toggleExpandSource() {
0552: if (sourceExpanded) {
0553: int last = this .splitPane.getLastDividerLocation();
0554: this .splitPane.setDividerLocation(last);
0555: } else {
0556: int current = this .splitPane.getDividerLocation();
0557: this .splitPane.setLastDividerLocation(current);
0558: this .splitPane.setDividerLocation(0);
0559: }
0560: sourceExpanded = !sourceExpanded;
0561: }
0562:
0563: public void setInitialFocus() {
0564: findPanel.setFocusToEntryField();
0565: }
0566:
0567: public void disconnect() {
0568: this .dbConnection = null;
0569: this .tableTypes.removeActionListener(this );
0570: this .displayTab.removeChangeListener(this );
0571: this .tableTypes.removeAllItems();
0572: this .tableDefinition.setConnection(null);
0573: this .reset();
0574: }
0575:
0576: public void reset() {
0577: this .invalidateData();
0578: if (this .isBusy()) {
0579: return;
0580: }
0581:
0582: WbSwingUtilities.invoke(new Runnable() {
0583: public void run() {
0584: tableDefinition.reset();
0585: importedKeys.reset();
0586: exportedKeys.reset();
0587: indexes.reset();
0588: triggers.reset();
0589: tableSource.setText("");
0590: importedTableTree.reset();
0591: exportedTableTree.reset();
0592: tableData.reset();
0593: }
0594: });
0595: }
0596:
0597: private void resetCurrentPanel() {
0598: int index = this .displayTab.getSelectedIndex();
0599: switch (index) {
0600: case 0:
0601: this .tableDefinition.reset();
0602: break;
0603: case 1:
0604: this .tableSource.setText("");
0605: break;
0606: case 2:
0607: this .tableData.reset();
0608: break;
0609: case 3:
0610: this .indexes.reset();
0611: break;
0612: case 4:
0613: this .importedKeys.reset();
0614: this .importedTableTree.reset();
0615: break;
0616: case 5:
0617: this .exportedKeys.reset();
0618: this .exportedTableTree.reset();
0619: break;
0620: case 6:
0621: this .triggers.reset();
0622: }
0623: }
0624:
0625: protected void invalidateData() {
0626: this .shouldRetrieveTable = true;
0627: this .shouldRetrieveTableDataCount = true;
0628: this .shouldRetrieveTableSource = true;
0629: this .shouldRetrieveTriggers = true;
0630: this .shouldRetrieveIndexes = true;
0631: this .shouldRetrieveExportedKeys = true;
0632: this .shouldRetrieveImportedKeys = true;
0633: this .shouldRetrieveExportedTree = true;
0634: this .shouldRetrieveImportedTree = true;
0635: this .shouldRetrieveTableDataCount = true;
0636: }
0637:
0638: public void setConnection(WbConnection aConnection) {
0639: this .dbConnection = aConnection;
0640: this .importedTableTree.setConnection(aConnection);
0641: this .exportedTableTree.setConnection(aConnection);
0642: this .tableData.setConnection(aConnection);
0643: this .tableDefinition.setConnection(aConnection);
0644:
0645: this .tableTypes.removeActionListener(this );
0646:
0647: this .triggers.setConnection(aConnection);
0648: this .tableSource.setDatabaseConnection(aConnection);
0649: this .reset();
0650: try {
0651: Collection<String> types = this .dbConnection.getMetadata()
0652: .getTableTypes();
0653: this .tableTypes.removeAllItems();
0654: this .tableTypes.addItem("*");
0655:
0656: for (String type : types) {
0657: this .tableTypes.addItem(type);
0658: }
0659:
0660: String tableView = this .dbConnection.getMetadata()
0661: .getTableTypeName()
0662: + ","
0663: + this .dbConnection.getMetadata().getViewTypeName();
0664: String add = Settings.getInstance().getProperty(
0665: "workbench.dbexplorer.typefilter.additional",
0666: tableView);
0667: List<String> userFilter = StringUtil.stringToList(add, ";",
0668: true, true);
0669:
0670: for (String t : userFilter) {
0671: this .tableTypes.addItem(t);
0672: }
0673:
0674: this .tableTypes.setSelectedIndex(0);
0675: if (tableTypeToSelect != null) {
0676: this .tableTypes.setSelectedItem(this .tableTypeToSelect);
0677: }
0678: } catch (Exception e) {
0679: LogMgr.logError("TableListPanel.setConnection()",
0680: "Error when setting up connection", e);
0681: }
0682:
0683: this .tableTypes.addActionListener(this );
0684: this .displayTab.addChangeListener(this );
0685: this .compileAction.setConnection(aConnection);
0686: }
0687:
0688: public boolean isReallyVisible() {
0689: if (!this .isVisible())
0690: return false;
0691: Window w = SwingUtilities.getWindowAncestor(this );
0692: return (w.isActive() && w.isFocused() && w.isVisible());
0693:
0694: }
0695:
0696: public void setCatalogAndSchema(String aCatalog, String aSchema)
0697: throws Exception {
0698: this .setCatalogAndSchema(aCatalog, aSchema, true);
0699: }
0700:
0701: public void setCatalogAndSchema(String aCatalog, String aSchema,
0702: boolean retrieve) throws Exception {
0703: this .currentSchema = aSchema;
0704: this .currentCatalog = aCatalog;
0705: this .invalidateData();
0706:
0707: if (this .isBusy()) {
0708: this .shouldRetrieve = retrieve;
0709: return;
0710: }
0711:
0712: this .reset();
0713:
0714: if (!retrieve)
0715: return;
0716: if (this .dbConnection == null)
0717: return;
0718:
0719: if (this .isReallyVisible() || this .isClientVisible()) {
0720: this .retrieve();
0721: this .setFocusToTableList();
0722: } else {
0723: this .shouldRetrieve = true;
0724: }
0725: }
0726:
0727: public void tableChanged(TableModelEvent e) {
0728: String info = tableList.getRowCount() + " "
0729: + ResourceMgr.getString("TxtTableListObjects");
0730: this .tableInfoLabel.setText(info);
0731:
0732: }
0733:
0734: private void setFocusToTableList() {
0735: EventQueue.invokeLater(new Runnable() {
0736: public void run() {
0737: listPanel.requestFocus();
0738: tableList.requestFocus();
0739: }
0740: });
0741: }
0742:
0743: public void retrieve() {
0744: if (this .isBusy()) {
0745: this .invalidateData();
0746: return;
0747: }
0748:
0749: if (dbConnection == null || dbConnection.isClosed()) {
0750: WbSwingUtilities.showErrorMessageKey(this ,
0751: "ErrConnectionGone");
0752: return;
0753: }
0754:
0755: try {
0756: WbSwingUtilities.showWaitCursor(this );
0757: reset();
0758:
0759: // do not call setBusy() before reset() because
0760: // reset will do nothing if the panel is busy
0761: setBusy(true);
0762:
0763: String[] types = null;
0764: String type = (String) tableTypes.getSelectedItem();
0765:
0766: if (!"*".equals(type)) {
0767: List<String> typeList = StringUtil.stringToList(type);
0768: types = new String[typeList.size()];
0769: for (int i = 0; i < typeList.size(); i++) {
0770: types[i] = typeList.get(i);
0771: }
0772: }
0773:
0774: DataStore ds = dbConnection.getMetadata().getTables(
0775: currentCatalog, currentSchema, types);
0776: final DataStoreTableModel model = new DataStoreTableModel(
0777: ds);
0778: model.sortByColumn(0);
0779:
0780: WbSwingUtilities.invoke(new Runnable() {
0781: public void run() {
0782: tableList.setModel(model, true);
0783: tableList.getExportAction().setEnabled(true);
0784: tableList.adjustOrOptimizeColumns();
0785: updateDisplayClients();
0786: }
0787: });
0788:
0789: shouldRetrieve = false;
0790: } catch (OutOfMemoryError mem) {
0791: reset();
0792: this .shouldRetrieve = true;
0793: WbManager.getInstance().showOutOfMemoryError();
0794: } catch (Throwable e) {
0795: LogMgr.logError("TableListPanel.retrieve()",
0796: "Error retrieving table list", e);
0797: final String msg = ExceptionUtil.getDisplay(e);
0798: invalidateData();
0799: this .shouldRetrieve = true;
0800: EventQueue.invokeLater(new Runnable() {
0801: public void run() {
0802: WbSwingUtilities.showErrorMessage(
0803: TableListPanel.this , msg);
0804: }
0805: });
0806: } finally {
0807: WbSwingUtilities.showDefaultCursor(this );
0808: setBusy(false);
0809: }
0810: }
0811:
0812: /**
0813: * Starts the retrieval of the tables in a background thread
0814: */
0815: public void startRetrieve() {
0816: Thread t = new WbThread("TableListPanel retrieve() thread") {
0817: public void run() {
0818: retrieve();
0819: }
0820: };
0821: t.start();
0822: }
0823:
0824: public void panelSelected() {
0825: if (this .shouldRetrieve)
0826: startRetrieve();
0827: }
0828:
0829: public void setVisible(boolean aFlag) {
0830: super .setVisible(aFlag);
0831: if (aFlag && this .shouldRetrieve)
0832: this .retrieve();
0833: }
0834:
0835: private String getWorkspacePrefix(int index) {
0836: return "dbexplorer" + index + ".tablelist.";
0837: }
0838:
0839: /**
0840: * Save settings to global settings file
0841: */
0842: public void saveSettings() {
0843: this .triggers.saveSettings();
0844: this .tableData.saveSettings();
0845: this .tableDefinition.saveSettings();
0846: String prefix = this .getClass().getName() + ".";
0847: storeSettings(Settings.getInstance(), prefix);
0848: findPanel.saveSettings(Settings.getInstance(),
0849: "workbench.quickfilter.");
0850: }
0851:
0852: /**
0853: * Restore settings from global settings file.
0854: */
0855: public void restoreSettings() {
0856: String prefix = this .getClass().getName() + ".";
0857: Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
0858: readSettings(Settings.getInstance(), prefix);
0859: findPanel.restoreSettings(Settings.getInstance(),
0860: "workbench.quickfilter.");
0861: this .triggers.restoreSettings();
0862: this .tableData.restoreSettings();
0863: this .tableDefinition.restoreSettings();
0864: }
0865:
0866: /**
0867: * Save settings to a workspace
0868: *
0869: * @param w the Workspace into which the settings should be saved
0870: * @param index the index to be used in the Workspace
0871: */
0872: public void saveToWorkspace(WbWorkspace w, int index) {
0873: tableData.saveToWorkspace(w, index);
0874: WbProperties props = w.getSettings();
0875: String prefix = getWorkspacePrefix(index);
0876: storeSettings(props, prefix);
0877: this .findPanel.saveSettings(props, "workbench.quickfilter.");
0878: }
0879:
0880: /**
0881: * Read settings from a workspace
0882: *
0883: * @param w the Workspace from which to read the settings
0884: * @param index the index inside the workspace
0885: */
0886: public void readFromWorkspace(WbWorkspace w, int index) {
0887: // first we read the global settings, then we'll let
0888: // the settings in the workspace override the global ones
0889: restoreSettings();
0890: tableData.readFromWorkspace(w, index);
0891: WbProperties props = w.getSettings();
0892: String prefix = getWorkspacePrefix(index);
0893: readSettings(props, prefix);
0894: findPanel.restoreSettings(props, "workbench.quickfilter.");
0895: }
0896:
0897: private void storeSettings(PropertyStorage props, String prefix) {
0898: try {
0899: String type = (String) tableTypes.getSelectedItem();
0900: if (type != null)
0901: props.setProperty(prefix + "objecttype", type);
0902: props.setProperty(prefix + "divider", Integer
0903: .toString(this .splitPane.getDividerLocation()));
0904: props.setProperty(prefix + "exportedtreedivider", Integer
0905: .toString(this .exportedPanel.getDividerLocation()));
0906: props.setProperty(prefix + "importedtreedivider", Integer
0907: .toString(this .exportedPanel.getDividerLocation()));
0908: } catch (Throwable th) {
0909: LogMgr.logError("TableListPanel.storeSettings()",
0910: "Error storing settings", th);
0911: }
0912: }
0913:
0914: private void readSettings(PropertyStorage props, String prefix) {
0915: Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
0916: int maxWidth = (int) (d.getWidth() - 50);
0917:
0918: int loc = props.getIntProperty(prefix + "divider", -1);
0919: if (loc != -1) {
0920: if (loc == 0 || loc > maxWidth)
0921: loc = 200;
0922: this .splitPane.setDividerLocation(loc);
0923: }
0924:
0925: loc = props.getIntProperty(prefix + "exportedtreedivider", -1);
0926: if (loc != -1) {
0927: if (loc == 0 || loc > maxWidth)
0928: loc = 200;
0929: this .exportedPanel.setDividerLocation(loc);
0930: }
0931:
0932: loc = props.getIntProperty(prefix + "importedtreedivider", -1);
0933: if (loc != -1) {
0934: if (loc == 0 || loc > maxWidth)
0935: loc = 200;
0936: this .importedPanel.setDividerLocation(loc);
0937: }
0938:
0939: if (Settings.getInstance().getStoreExplorerObjectType()) {
0940: this .tableTypeToSelect = props.getProperty(prefix
0941: + "objecttype", null);
0942: } else {
0943: this .tableTypeToSelect = null;
0944: }
0945: }
0946:
0947: private boolean suspendTableSelection = false;
0948:
0949: public void suspendTableSelection(boolean flag) {
0950: boolean wasSuspended = this .suspendTableSelection;
0951: this .suspendTableSelection = flag;
0952: if (wasSuspended && !this .suspendTableSelection) {
0953: this .updateDisplay();
0954: }
0955: }
0956:
0957: /**
0958: * Invoked when the selection in the table list has changed
0959: */
0960: public void valueChanged(ListSelectionEvent e) {
0961: if (e.getValueIsAdjusting())
0962: return;
0963: if (e.getSource() == this .tableList.getSelectionModel()
0964: && !this .suspendTableSelection) {
0965: if (this .showDataMenu != null) {
0966: this .showDataMenu.setEnabled(this .tableList
0967: .getSelectedRowCount() == 1);
0968: }
0969: this .updateDisplay();
0970: }
0971: }
0972:
0973: public void updateDisplay() {
0974: int count = this .tableList.getSelectedRowCount();
0975:
0976: this .spoolData.setEnabled(count > 0);
0977:
0978: if (count > 1)
0979: return;
0980:
0981: int row = this .tableList.getSelectedRow();
0982: if (row < 0)
0983: return;
0984:
0985: this .selectedTable = createTableIdentifier(row);
0986: this .realTable = null;
0987:
0988: this .invalidateData();
0989:
0990: boolean isTable = isTable();
0991: boolean hasData = isTable;
0992: if (!isTable) {
0993: hasData = canContainData();
0994: }
0995: if (isTable) {
0996: addTablePanels();
0997: } else {
0998: if (hasData) {
0999: if (this .displayTab.getTabCount() == 2) {
1000: this .addDataPanel();
1001: } else {
1002: this .removeTablePanels(false);
1003: }
1004: } else {
1005: removeTablePanels(true);
1006: }
1007: }
1008:
1009: this .tableData.reset();
1010: this .tableData.setReadOnly(!isTableType(this .selectedTable
1011: .getType()));
1012: this .tableData.setTable(this .selectedTable);
1013:
1014: this .setShowDataMenuStatus(hasData);
1015:
1016: this .startRetrieveCurrentPanel();
1017: }
1018:
1019: private void setShowDataMenuStatus(boolean flag) {
1020: if (this .showDataMenu != null)
1021: this .showDataMenu.setEnabled(flag);
1022: }
1023:
1024: private boolean isTableType(String type) {
1025: if (type == null)
1026: return false;
1027: return (type.indexOf("TABLE") > -1
1028: || type.indexOf("table") > -1 || type
1029: .equalsIgnoreCase(DbMetadata.MVIEW_NAME));
1030: }
1031:
1032: private boolean isSynonym(TableIdentifier table) {
1033: if (table == null)
1034: return false;
1035: DbMetadata meta = this .dbConnection.getMetadata();
1036: DbSettings dbs = this .dbConnection.getDbSettings();
1037: return (meta.supportsSynonyms() && dbs.isSynonymType(table
1038: .getType()));
1039: }
1040:
1041: private boolean isTable() {
1042: if (this .selectedTable == null)
1043: return false;
1044: DbMetadata meta = this .dbConnection.getMetadata();
1045: DbSettings dbs = this .dbConnection.getDbSettings();
1046: String type = selectedTable.getType();
1047: if (isTableType(type))
1048: return true;
1049: if (meta.supportsSynonyms() && dbs.isSynonymType(type)) {
1050: TableIdentifier rt = getObjectTable();
1051: if (rt == null)
1052: return false;
1053: return isTableType(realTable.getType());
1054: }
1055: return false;
1056: }
1057:
1058: private boolean canContainData() {
1059: if (selectedTable == null)
1060: return false;
1061: String type = selectedTable.getType();
1062: DbMetadata meta = this .dbConnection.getMetadata();
1063: DbSettings dbs = this .dbConnection.getDbSettings();
1064: if (meta.supportsSynonyms() && dbs.isSynonymType(type)) {
1065: TableIdentifier rt = getObjectTable();
1066: if (rt == null)
1067: return false;
1068: type = rt.getType();
1069: }
1070: return meta.objectTypeCanContainData(type);
1071: }
1072:
1073: protected void retrieveTableSource() {
1074: tableSource.setPlainText(ResourceMgr
1075: .getString("TxtRetrievingSourceCode"));
1076:
1077: try {
1078: WbSwingUtilities.showWaitCursor(this );
1079: CharSequence sql = "";
1080:
1081: DbMetadata meta = this .dbConnection.getMetadata();
1082: DbSettings dbs = this .dbConnection.getDbSettings();
1083: if (this .shouldRetrieveTable
1084: || tableDefinition.getRowCount() == 0) {
1085: this .retrieveTableDefinition();
1086: this .shouldRetrieveIndexes = true;
1087: this .shouldRetrieveImportedTree = true;
1088: }
1089: String type = this .selectedTable.getType();
1090:
1091: if (dbs.isViewType(type)) {
1092: sql = meta.getExtendedViewSource(this .selectedTable,
1093: tableDefinition.getDataStore(), true);
1094: } else if (dbs.isSynonymType(type)) {
1095: sql = meta.getSynonymSource(this .selectedTable);
1096: if (sql.length() == 0) {
1097: sql = ResourceMgr
1098: .getString("MsgSynonymSourceNotImplemented")
1099: + " " + meta.getProductName();
1100: } else {
1101: try {
1102: TableIdentifier tbl = meta
1103: .getSynonymTable(this .selectedTable);
1104: String tableSql = meta.getTableSource(tbl,
1105: false, true);
1106: if (!StringUtil.isEmptyString(tableSql)) {
1107: StringBuilder sb = new StringBuilder(sql
1108: .length()
1109: + tableSql.length() + 50);
1110: String nl = Settings.getInstance()
1111: .getInternalEditorLineEnding();
1112: sb.append(sql);
1113: sb.append(nl);
1114: sb.append(nl);
1115: sb.append("-------------- ");
1116: sb.append(tbl
1117: .getTableExpression(dbConnection));
1118: sb.append(" --------------");
1119: sb.append(nl);
1120: sb.append(nl);
1121: sb.append(tableSql);
1122: sql = sb;
1123: }
1124: } catch (Exception e) {
1125: LogMgr
1126: .logError(
1127: "TableListPanel.retrieveTableSource()",
1128: "Error when retrieving source for synonym table",
1129: e);
1130: }
1131: }
1132: } else if ("sequence".equalsIgnoreCase(type)) {
1133: sql = meta.getSequenceSource(this .selectedTable
1134: .getCatalog(), this .selectedTable.getSchema(),
1135: this .selectedTable.getTableName());
1136: if (sql.length() == 0) {
1137: sql = ResourceMgr
1138: .getString("MsgSequenceSourceNotImplemented")
1139: + " " + meta.getProductName();
1140: }
1141: } else if (isTableType(type)) {
1142: // the table information has to be retrieved before
1143: // the table source, because otherwise the DataStores
1144: // passed to getTableSource() would be empty
1145: if (this .shouldRetrieveIndexes)
1146: this .retrieveIndexes();
1147: if (this .shouldRetrieveImportedTree)
1148: this .retrieveImportedTables();
1149: sql = meta.getTableSource(selectedTable,
1150: tableDefinition.getDataStore(), indexes
1151: .getDataStore(), importedKeys
1152: .getDataStore(), true, null);
1153: }
1154: final String s = (sql == null ? "" : sql.toString());
1155: EventQueue.invokeLater(new Runnable() {
1156: public void run() {
1157: tableSource.setText(s);
1158: tableSource.setCaretPosition(0, false);
1159: }
1160: });
1161: shouldRetrieveTableSource = false;
1162: } catch (Exception e) {
1163: LogMgr.logError("TableListPanel.retrieveTableSource()",
1164: "Error retrieving table source", e);
1165: final String msg = ExceptionUtil.getDisplay(e);
1166: EventQueue.invokeLater(new Runnable() {
1167: public void run() {
1168: tableSource.setText(msg);
1169: }
1170: });
1171: } finally {
1172: WbSwingUtilities.showDefaultCursor(this );
1173: }
1174: }
1175:
1176: private void retrieveTableDefinition() throws SQLException {
1177:
1178: try {
1179: WbSwingUtilities.showWaitCursor(this );
1180: this .tableDefinition.retrieve(selectedTable);
1181: this .shouldRetrieveTable = false;
1182: shouldRetrieveTable = false;
1183: } catch (SQLException e) {
1184: shouldRetrieveTable = true;
1185: throw e;
1186: } finally {
1187: WbSwingUtilities.showDefaultCursor(this );
1188: tableDefinition.setIgnoreRepaint(false);
1189: }
1190: }
1191:
1192: protected void showCancelMessage() {
1193: this .showPopupMessagePanel(ResourceMgr
1194: .getString("MsgTryCancelling"));
1195: }
1196:
1197: protected void showWaitMessage() {
1198: this .showPopupMessagePanel(ResourceMgr
1199: .getString("MsgWaitRetrieveEnded"));
1200: }
1201:
1202: private void showRetrieveMessage() {
1203: this .showPopupMessagePanel(ResourceMgr
1204: .getString("MsgRetrieving"));
1205: }
1206:
1207: private void showPopupMessagePanel(String aMsg) {
1208: if (this .infoWindow != null) {
1209: this .infoLabel.setText(aMsg);
1210: this .infoWindow.invalidate();
1211: Thread.yield();
1212: return;
1213: }
1214: JPanel p = new JPanel();
1215: p.setBorder(WbSwingUtilities.getBevelBorderRaised());
1216: p.setLayout(new BorderLayout());
1217: this .infoLabel = new JLabel(aMsg);
1218: this .infoLabel.setHorizontalAlignment(SwingConstants.CENTER);
1219: p.add(this .infoLabel, BorderLayout.CENTER);
1220: JFrame f = (JFrame) SwingUtilities.getWindowAncestor(this );
1221: this .infoWindow = new JDialog(f, true);
1222: this .infoWindow
1223: .setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
1224: this .infoWindow.getContentPane().setLayout(new BorderLayout());
1225: this .infoWindow.getContentPane().add(p, BorderLayout.CENTER);
1226: this .infoWindow.setUndecorated(true);
1227: this .infoWindow.setSize(260, 50);
1228: WbSwingUtilities.center(this .infoWindow, f);
1229: WbThread t = new WbThread("Info display") {
1230: public void run() {
1231: infoWindow.setVisible(true);
1232: }
1233: };
1234: t.start();
1235: Thread.yield();
1236: }
1237:
1238: private void closeInfoWindow() {
1239: if (this .infoWindow != null) {
1240: this .infoLabel = null;
1241: this .infoWindow.getOwner().setEnabled(true);
1242: this .infoWindow.setVisible(false);
1243: this .infoWindow.dispose();
1244: this .infoWindow = null;
1245: }
1246: }
1247:
1248: protected Thread panelRetrieveThread;
1249:
1250: private void startCancelThread() {
1251: Thread t = new WbThread("TableListPanel Cancel") {
1252: public void run() {
1253: try {
1254: if (tableData.isRetrieving()) {
1255: showCancelMessage();
1256: tableData.cancelRetrieve();
1257: } else {
1258: showWaitMessage();
1259: }
1260:
1261: if (panelRetrieveThread != null) {
1262: panelRetrieveThread.join();
1263: panelRetrieveThread = null;
1264: }
1265: } catch (InterruptedException e) {
1266: }
1267: setBusy(false);
1268: invalidateData();
1269: startRetrieveThread(true);
1270: }
1271: };
1272: t.start();
1273: }
1274:
1275: protected void startRetrieveCurrentPanel() {
1276: if (isBusy()) {
1277: startCancelThread();
1278: } else {
1279: startRetrieveThread(false);
1280: }
1281: }
1282:
1283: protected void startRetrieveThread(final boolean withMessage) {
1284: panelRetrieveThread = new WbThread(
1285: "TableListPanel RetrievePanel") {
1286: public void run() {
1287: try {
1288: retrieveCurrentPanel(withMessage);
1289: } finally {
1290: panelRetrieveThread = null;
1291: }
1292: }
1293: };
1294: panelRetrieveThread.start();
1295: }
1296:
1297: protected void retrieveCurrentPanel(final boolean withMessage) {
1298: if (this .isBusy() || this .dbConnection.isBusy()) {
1299: this .invalidateData();
1300: this .resetCurrentPanel();
1301: return;
1302: }
1303:
1304: if (this .tableList.getSelectedRowCount() <= 0)
1305: return;
1306: int index = this .displayTab.getSelectedIndex();
1307:
1308: if (withMessage)
1309: showRetrieveMessage();
1310:
1311: this .setBusy(true);
1312:
1313: try {
1314: synchronized (this .dbConnection) {
1315: switch (index) {
1316: case 0:
1317: if (this .shouldRetrieveTable)
1318: this .retrieveTableDefinition();
1319: break;
1320: case 1:
1321: if (this .shouldRetrieveTableSource)
1322: this .retrieveTableSource();
1323: break;
1324: case 2:
1325: if (this .shouldRetrieveTableDataCount) {
1326: this .tableData.showData(!this .shiftDown);
1327: this .shouldRetrieveTableDataCount = false;
1328: }
1329: break;
1330: case 3:
1331: if (this .shouldRetrieveIndexes)
1332: this .retrieveIndexes();
1333: break;
1334: case 4:
1335: if (this .shouldRetrieveImportedKeys)
1336: this .retrieveImportedTables();
1337: if (this .shouldRetrieveImportedTree)
1338: this .retrieveImportedTree();
1339: break;
1340: case 5:
1341: if (this .shouldRetrieveExportedKeys)
1342: this .retrieveExportedTables();
1343: if (this .shouldRetrieveExportedTree)
1344: this .retrieveExportedTree();
1345: break;
1346: case 6:
1347: if (this .shouldRetrieveTriggers)
1348: this .retrieveTriggers();
1349: }
1350: }
1351: } catch (Throwable ex) {
1352: LogMgr.logError("TableListPanel.retrieveCurrentPanel()",
1353: "Error retrieving panel " + index, ex);
1354: } finally {
1355: if (this .dbConnection.selectStartsTransaction()
1356: && !this .dbConnection.getAutoCommit()) {
1357: try {
1358: this .dbConnection.commit();
1359: } catch (Throwable th) {
1360: }
1361: }
1362: this .setBusy(false);
1363: this .repaint();
1364: closeInfoWindow();
1365: WbSwingUtilities.showDefaultCursor(this );
1366: }
1367: }
1368:
1369: private final Object busyLock = new Object();
1370:
1371: private boolean isBusy() {
1372: synchronized (busyLock) {
1373: return this .busy;
1374: }
1375: }
1376:
1377: protected void setBusy(boolean aFlag) {
1378: synchronized (busyLock) {
1379: this .busy = aFlag;
1380: this .dbConnection.setBusy(aFlag);
1381: }
1382: }
1383:
1384: public TableIdentifier getObjectTable() {
1385: if (this .selectedTable == null)
1386: return null;
1387: if (!isSynonym(selectedTable))
1388: return selectedTable;
1389:
1390: if (realTable == null) {
1391: realTable = getRealTable(this .selectedTable);
1392: }
1393: return realTable;
1394: }
1395:
1396: protected TableIdentifier getRealTable(TableIdentifier tbl) {
1397: return this .dbConnection.getMetadata().resolveSynonym(tbl);
1398: }
1399:
1400: protected void retrieveTriggers() throws SQLException {
1401: try {
1402: WbSwingUtilities.showDefaultCursor(this );
1403: triggers.readTriggers(getObjectTable());
1404: this .shouldRetrieveTriggers = false;
1405: } catch (Throwable th) {
1406: this .shouldRetrieveTriggers = true;
1407: LogMgr.logError("TableListPanel.retrieveTriggers()",
1408: "Error retrieving triggers", th);
1409: WbSwingUtilities.showErrorMessage(this , ExceptionUtil
1410: .getDisplay(th));
1411: } finally {
1412: WbSwingUtilities.showDefaultCursor(this );
1413: }
1414: }
1415:
1416: protected void retrieveIndexes() throws SQLException {
1417: try {
1418: WbSwingUtilities.showWaitCursor(this );
1419: DbMetadata meta = this .dbConnection.getMetadata();
1420: DataStore ds = meta
1421: .getTableIndexInformation(getObjectTable());
1422: DataStoreTableModel model = new DataStoreTableModel(ds);
1423: indexes.setModel(model, true);
1424: indexes.adjustOrOptimizeColumns();
1425:
1426: this .shouldRetrieveIndexes = false;
1427: } catch (Throwable th) {
1428: this .shouldRetrieveIndexes = true;
1429: LogMgr.logError("TableListPanel.retrieveIndexes()",
1430: "Error retrieving indexes", th);
1431: WbSwingUtilities.showErrorMessage(this , ExceptionUtil
1432: .getDisplay(th));
1433: } finally {
1434: WbSwingUtilities.showDefaultCursor(this );
1435: }
1436: }
1437:
1438: protected void retrieveExportedTables() throws SQLException {
1439: try {
1440: DbMetadata meta = this .dbConnection.getMetadata();
1441: DataStoreTableModel model = new DataStoreTableModel(meta
1442: .getReferencedBy(getObjectTable()));
1443: exportedKeys.setModel(model, true);
1444: exportedKeys.adjustOrOptimizeColumns();
1445: this .shouldRetrieveExportedKeys = false;
1446: } catch (Throwable th) {
1447: this .shouldRetrieveExportedKeys = true;
1448: LogMgr.logError("TableListPanel.retrieveExportedTables()",
1449: "Error retrieving table references", th);
1450: WbSwingUtilities.showErrorMessage(this , ExceptionUtil
1451: .getDisplay(th));
1452: }
1453: }
1454:
1455: protected void retrieveImportedTables() throws SQLException {
1456: try {
1457: WbSwingUtilities.showWaitCursor(this );
1458: DbMetadata meta = this .dbConnection.getMetadata();
1459: DataStoreTableModel model = new DataStoreTableModel(meta
1460: .getForeignKeys(getObjectTable(), false));
1461: importedKeys.setModel(model, true);
1462: importedKeys.adjustOrOptimizeColumns();
1463: this .shouldRetrieveImportedKeys = false;
1464: } catch (Throwable th) {
1465: this .shouldRetrieveImportedKeys = true;
1466: LogMgr.logError("TableListPanel.retrieveImportedTables()",
1467: "Error retrieving table references", th);
1468: WbSwingUtilities.showErrorMessage(this , ExceptionUtil
1469: .getDisplay(th));
1470: } finally {
1471: WbSwingUtilities.showDefaultCursor(this );
1472: }
1473: }
1474:
1475: protected void retrieveImportedTree() {
1476: try {
1477: WbSwingUtilities.showWaitCursor(this );
1478: importedTableTree.readReferencedTables(getObjectTable());
1479: this .shouldRetrieveImportedTree = false;
1480: } catch (Throwable th) {
1481: this .shouldRetrieveImportedTree = true;
1482: LogMgr.logError("TableListPanel.retrieveImportedTree()",
1483: "Error retrieving table references", th);
1484: WbSwingUtilities.showErrorMessage(this , ExceptionUtil
1485: .getDisplay(th));
1486: } finally {
1487: WbSwingUtilities.showDefaultCursor(this );
1488: }
1489: }
1490:
1491: protected void retrieveExportedTree() {
1492: try {
1493: WbSwingUtilities.showWaitCursor(this );
1494: exportedTableTree.readReferencingTables(getObjectTable());
1495: this .shouldRetrieveExportedTree = false;
1496: } catch (Throwable th) {
1497: LogMgr.logError("TableListPanel.retrieveImportedTree()",
1498: "Error retrieving table references", th);
1499: this .shouldRetrieveExportedTree = true;
1500: WbSwingUtilities.showErrorMessage(this , ExceptionUtil
1501: .getDisplay(th));
1502: } finally {
1503: WbSwingUtilities.showDefaultCursor(this );
1504: }
1505: }
1506:
1507: public void reload() {
1508: this .reset();
1509: this .retrieve();
1510: }
1511:
1512: private void showTableData(final int panelIndex,
1513: final boolean appendText) {
1514: PanelContentSender sender = new PanelContentSender(
1515: this .parentWindow);
1516: sender.sendContent(buildSqlForTable(), panelIndex, appendText);
1517: }
1518:
1519: private String buildSqlForTable() {
1520: if (this .selectedTable == null)
1521: return null;
1522:
1523: if (this .shouldRetrieveTable
1524: || this .tableDefinition.getRowCount() == 0) {
1525: try {
1526: this .retrieveTableDefinition();
1527: } catch (Exception e) {
1528: LogMgr.logError("TableListPanel.buidlSqlForTable()",
1529: "Error retrieving table definition", e);
1530: String msg = ExceptionUtil.getDisplay(e);
1531: WbSwingUtilities.showErrorMessage(this , msg);
1532: return null;
1533: }
1534: }
1535: String sql = tableDefinition.getSelectForTable() + ";";
1536: if (sql == null) {
1537: String msg = ResourceMgr.getString("ErrNoColumnsRetrieved")
1538: .replaceAll("%table%",
1539: this .selectedTable.getTableName());
1540: WbSwingUtilities.showErrorMessage(this , msg);
1541: }
1542: return sql;
1543: }
1544:
1545: /**
1546: * Invoked when the type dropdown changes or one of the additional actions
1547: * is invoked that are put into the context menu of the table list
1548: *
1549: * @param e the Event that ocurred
1550: */
1551: public void actionPerformed(ActionEvent e) {
1552: if (e.getSource() == this .tableTypes) {
1553: try {
1554: this .removeTablePanels(true);
1555: this .retrieve();
1556: this .setFocusToTableList();
1557: } catch (Exception ex) {
1558: LogMgr.logError("TableListPanel.actionPerformed()",
1559: "Error while retrieving", ex);
1560: }
1561: } else {
1562: String command = e.getActionCommand();
1563:
1564: if (command
1565: .startsWith(EditorTabSelectMenu.PANEL_CMD_PREFIX)
1566: && this .parentWindow != null) {
1567: try {
1568: final int panelIndex = Integer
1569: .parseInt(command
1570: .substring(EditorTabSelectMenu.PANEL_CMD_PREFIX
1571: .length()));
1572: final boolean appendText = WbAction
1573: .isCtrlPressed(e);
1574: // Allow the selection change to finish so that
1575: // we have the correct table name in the instance variables
1576: EventQueue.invokeLater(new Runnable() {
1577: public void run() {
1578: showTableData(panelIndex, appendText);
1579: }
1580: });
1581: } catch (Exception ex) {
1582: LogMgr.logError(
1583: "TableListPanel().actionPerformed()",
1584: "Error when accessing editor tab", ex);
1585: }
1586: }
1587: }
1588: }
1589:
1590: private boolean isClientVisible() {
1591: if (this .tableListClients == null)
1592: return false;
1593: for (JTable table : tableListClients) {
1594: if (table.isVisible())
1595: return true;
1596: }
1597: return false;
1598: }
1599:
1600: protected void updateDisplayClients() {
1601: if (this .tableListClients == null)
1602: return;
1603: TableModel model = this .tableList.getModel();
1604: for (JTable table : tableListClients) {
1605: if (table != null && model != null) {
1606: table.setModel(model);
1607: if (table instanceof WbTable) {
1608: WbTable t = (WbTable) table;
1609: t.adjustOrOptimizeColumns();
1610: }
1611: table.repaint();
1612: }
1613: }
1614: }
1615:
1616: public void addTableListDisplayClient(JTable aClient) {
1617: if (this .tableListClients == null)
1618: this .tableListClients = new ArrayList<JTable>();
1619: if (!this .tableListClients.contains(aClient))
1620: this .tableListClients.add(aClient);
1621: }
1622:
1623: public void removeTableListDisplayClient(JTable aClient) {
1624: if (this .tableListClients == null)
1625: return;
1626: this .tableListClients.remove(aClient);
1627: }
1628:
1629: /**
1630: * Return a TableIdentifier for the given row number in the table list.
1631: * @param row the row from the tableList Table
1632: * @return a TableIdentifier for that row
1633: */
1634: private TableIdentifier createTableIdentifier(int row) {
1635: String name = this .tableList.getValueAsString(row,
1636: DbMetadata.COLUMN_IDX_TABLE_LIST_NAME);
1637: String schema = this .tableList.getValueAsString(row,
1638: DbMetadata.COLUMN_IDX_TABLE_LIST_SCHEMA);
1639: String catalog = this .tableList.getValueAsString(row,
1640: DbMetadata.COLUMN_IDX_TABLE_LIST_CATALOG);
1641: String type = this .tableList.getValueAsString(row,
1642: DbMetadata.COLUMN_IDX_TABLE_LIST_TYPE);
1643: TableIdentifier tbl = new TableIdentifier(catalog, schema, name);
1644: tbl.setType(type);
1645: tbl.setNeverAdjustCase(true);
1646: return tbl;
1647: }
1648:
1649: public WbConnection getConnection() {
1650: return this .dbConnection;
1651: }
1652:
1653: public Component getComponent() {
1654: return this ;
1655: }
1656:
1657: public List<DbObject> getSelectedObjects() {
1658: int[] rows = this .tableList.getSelectedRows();
1659: int count = rows.length;
1660: if (count == 0)
1661: return null;
1662:
1663: List<DbObject> result = new ArrayList<DbObject>(count);
1664: for (int i = 0; i < count; i++) {
1665: TableIdentifier table = createTableIdentifier(rows[i]);
1666: if (table.getType().equalsIgnoreCase("SEQUENCE")) {
1667: result.add(new SequenceDefinition(table.getSchema(),
1668: table.getTableName()));
1669: } else {
1670: result.add(table);
1671: }
1672: }
1673: return result;
1674: }
1675:
1676: public void exportData() {
1677: if (!WbSwingUtilities.checkConnection(this , this .dbConnection))
1678: return;
1679: int rowCount = this .tableList.getSelectedRowCount();
1680: if (rowCount <= 0)
1681: return;
1682:
1683: if (rowCount > 1) {
1684: this .exportTables();
1685: return;
1686: }
1687:
1688: int row = this .tableList.getSelectedRow();
1689: if (row < 0)
1690: return;
1691: TableIdentifier id = createTableIdentifier(row);
1692: DataExporter exporter = new DataExporter(this .dbConnection);
1693: exporter
1694: .setReportInterval(ProgressReporter.DEFAULT_PROGRESS_INTERVAL);
1695: exporter
1696: .exportTable(SwingUtilities.getWindowAncestor(this ), id);
1697: }
1698:
1699: private void exportTables() {
1700: ExportFileDialog dialog = new ExportFileDialog(this );
1701: dialog.setIncludeSqlInsert(true);
1702: dialog.setIncludeSqlUpdate(false);
1703: dialog.setSelectDirectoryOnly(true);
1704: dialog.restoreSettings();
1705:
1706: String title = ResourceMgr.getString("LblSelectDirTitle");
1707: DbMetadata meta = this .dbConnection.getMetadata();
1708: boolean answer = dialog.selectOutput(title);
1709: if (answer) {
1710: String fdir = dialog.getSelectedFilename();
1711:
1712: DataExporter exporter = new DataExporter(this .dbConnection);
1713: dialog.setExporterOptions(exporter);
1714: exporter.setShowProgressWindow(true);
1715: String ext = null;
1716: int type = dialog.getExportType();
1717:
1718: if (type == DataExporter.EXPORT_SQL) {
1719: ext = ".sql";
1720: } else if (type == DataExporter.EXPORT_XML) {
1721: ext = ".xml";
1722: } else if (type == DataExporter.EXPORT_TXT) {
1723: ext = ".txt";
1724: } else if (type == DataExporter.EXPORT_HTML) {
1725: ext = ".html";
1726: }
1727:
1728: int[] rows = this .tableList.getSelectedRows();
1729: for (int i = 0; i < rows.length; i++) {
1730: if (rows[i] < 0)
1731: continue;
1732: TableIdentifier id = createTableIdentifier(rows[i]);
1733:
1734: String ttype = id.getType();
1735: if (ttype == null)
1736: continue;
1737: if (!meta.objectTypeCanContainData(ttype))
1738: continue;
1739: String fname = StringUtil.makeFilename(id
1740: .getTableName());
1741: File f = new File(fdir, fname + ext);
1742: try {
1743: exporter.addTableExportJob(f.getAbsolutePath(), id);
1744: } catch (SQLException e) {
1745: LogMgr.logError("TableListPanel.exportTables()",
1746: "Error adding ExportJob", e);
1747: WbSwingUtilities.showMessage(this , e.getMessage());
1748: }
1749: }
1750: exporter
1751: .setReportInterval(ProgressReporter.DEFAULT_PROGRESS_INTERVAL);
1752: exporter.startExportJobs((Frame) SwingUtilities
1753: .getWindowAncestor(this ));
1754: }
1755: }
1756:
1757: public Window getParentWindow() {
1758: return SwingUtilities.getWindowAncestor(this );
1759: }
1760:
1761: /** Invoked when the displayed tab has changed.
1762: * Retrieve table detail information here.
1763: */
1764: public void stateChanged(ChangeEvent e) {
1765: if (this .ignoreStateChanged)
1766: return;
1767: if (e.getSource() == this .displayTab) {
1768: EventQueue.invokeLater(new Runnable() {
1769: public void run() {
1770: startRetrieveCurrentPanel();
1771: }
1772:
1773: });
1774: }
1775: }
1776:
1777: /**
1778: * If an index is created in the TableDefinitionPanel it
1779: * sends a PropertyChange event. This will invalidate
1780: * the currently retrieved index list
1781: */
1782: public void propertyChange(PropertyChangeEvent evt) {
1783: if (TableDefinitionPanel.INDEX_PROP.equals(evt
1784: .getPropertyName())) {
1785: this .shouldRetrieveIndexes = true;
1786: }
1787: }
1788:
1789: public void mouseClicked(MouseEvent e) {
1790: this .shiftDown = ((e.getModifiers() & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK);
1791: }
1792:
1793: public void mouseEntered(MouseEvent e) {
1794: }
1795:
1796: public void mouseExited(MouseEvent e) {
1797: }
1798:
1799: public void mousePressed(MouseEvent e) {
1800: }
1801:
1802: public void mouseReleased(MouseEvent e) {
1803: }
1804:
1805: }
|