/*
* Copyright (C) 2004 Anthony Smith
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* ----------------------------------------------------------------------------
* TITLE $Id$
* ---------------------------------------------------------------------------
*
* --------------------------------------------------------------------------*/
package opendbcopy.gui.database.single;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.util.Iterator;
import java.util.List;
import java.util.Observable;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import opendbcopy.config.OperationType;
import opendbcopy.config.XMLTags;
import opendbcopy.controller.MainController;
import opendbcopy.gui.DynamicPanel;
import opendbcopy.gui.PluginGui;
import opendbcopy.plugin.model.database.DatabaseModel;
import opendbcopy.plugin.model.exception.MissingElementException;
import org.jdom.Element;
/**
* class description
*
* @author Anthony Smith
* @version $Revision$
*/
public class PanelProcessColumn extends DynamicPanel {
private static final String SQL_START = "SELECT <RECORDS> FROM ";
private static final String WHERE = " WHERE";
private DatabaseModel model;
private String currentTable;
private DefaultMutableTreeNode top;
private ProcessColumnModel processColumnModel;
private boolean select_all = false;
private Border borderRightPanel;
private BorderLayout borderLayout = new BorderLayout();
private BorderLayout borderLayoutRight = new BorderLayout();
private BorderLayout borderLayoutTextfield = new BorderLayout();
private GridLayout gridLayoutFilter = new GridLayout();
private JPanel panelOptions = new JPanel();
private JPanel panelRight = new JPanel();
private JPanel panelTableFilters = new JPanel();
private JPanel panelProcessColumns = null;
private JPanel panelSelection = new JPanel();
private JPanel panelControlFilter = new JPanel();
private JSplitPane splitPane = new JSplitPane();
private JScrollPane scrollPaneTree = null;
private JScrollPane scrollPaneTables = null;
private JTree treeSourceTables = new JTree();
private JTable tableProcessColumn = new JTable();
private JTextField tfFilter = new JTextField();
private JButton buttonApplyTestFilter = new JButton();
private JButton buttonDeleteFilter = new JButton();
private JCheckBox checkBoxProcess = new JCheckBox();
private JLabel labelSelect = new JLabel();
private JLabel labelInfo = new JLabel();
/**
* Creates a new PanelProcessColumn object.
*
* @param controller DOCUMENT ME!
* @param pluginGui DOCUMENT ME!
* @param registerAsObserver DOCUMENT ME!
*
* @throws Exception DOCUMENT ME!
*/
public PanelProcessColumn(MainController controller,
PluginGui workingMode,
Boolean registerAsObserver) throws Exception {
super(controller, workingMode, registerAsObserver);
model = (DatabaseModel) super.model;
guiInit();
loadTablesToProcess();
}
/**
* DOCUMENT ME!
*
* @param o DOCUMENT ME!
* @param obj DOCUMENT ME!
*/
public final void update(Observable o,
Object obj) {
if ((currentTable != null) && (currentTable.length() > 0)) {
try {
Element tableFilter = model.getTableFilter(currentTable);
if (tableFilter != null) {
tfFilter.setText(tableFilter.getAttributeValue(XMLTags.VALUE));
}
} catch (Exception e) {
postException(e);
}
}
}
/**
* DOCUMENT ME!
*/
public final void onSelect() {
try {
loadTablesToProcess();
} catch (Exception e) {
postException(e);
}
}
/**
* DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
public final void loadTablesToProcess() throws MissingElementException {
if (model.getNbrSourceTables() > 0) {
// remove component
splitPane.remove(scrollPaneTree);
top = new DefaultMutableTreeNode(rm.getString("text.column.processSourceTableView"));
createNodes(top);
treeSourceTables = new JTree(top);
// Listen for when the selection changes.
treeSourceTables.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeSourceTables.getLastSelectedPathComponent();
if (node == null) {
return;
}
if (node.getLevel() == 1) {
try {
loadColumnsAndFilter(node.toString());
} catch (Exception ex) {
postException(ex);
}
}
}
});
// add component
scrollPaneTree = new JScrollPane(treeSourceTables);
splitPane.add(scrollPaneTree);
splitPane.updateUI();
if ((currentTable != null) && (currentTable.length() > 0)) {
Element tableFilter = model.getTableFilter(currentTable);
if (tableFilter != null) {
tfFilter.setText(tableFilter.getAttributeValue(XMLTags.VALUE));
}
}
// if visible remove panels on right hand side
if ((panelRight != null) && (panelProcessColumns != null)) {
panelRight.remove(panelProcessColumns);
}
enableFilterPanels(false);
} else {
enableFilterPanels(false);
}
}
/**
* DOCUMENT ME!
*
* @param tableName DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
private void loadColumnsAndFilter(String tableName) throws MissingElementException {
currentTable = tableName;
// remove components if existing
if ((panelRight != null) && (panelProcessColumns != null)) {
panelProcessColumns.removeAll();
try {
panelRight.remove(panelProcessColumns);
} catch (Exception e) {
// who cares
}
}
processColumnModel = new ProcessColumnModel(model.getSourceColumns(tableName));
// load filter for table
labelSelect.setText(SQL_START + tableName + WHERE);
Element tableFilter = model.getTableFilter(tableName);
if (tableFilter != null) {
tfFilter.setText(tableFilter.getAttributeValue(XMLTags.VALUE));
buttonDeleteFilter.setEnabled(true);
checkBoxProcess.setSelected(Boolean.valueOf(tableFilter.getAttributeValue(XMLTags.PROCESS)).booleanValue());
// display number of records for this filter if available
String nbrRecordsString = tableFilter.getAttributeValue(XMLTags.RECORDS);
if (nbrRecordsString != null) {
String[] param = { nbrRecordsString };
labelInfo.setText(rm.getString("text.column.selectedRecords", param));
}
} else {
buttonDeleteFilter.setEnabled(false);
checkBoxProcess.setSelected(false);
tfFilter.setText("");
labelInfo.setText("");
}
tableProcessColumn = new JTable(processColumnModel);
panelProcessColumns.add(tableProcessColumn.getTableHeader(), BorderLayout.PAGE_START);
panelProcessColumns.add(tableProcessColumn, BorderLayout.CENTER);
enableFilterPanels(true);
panelRight.add(panelProcessColumns, BorderLayout.CENTER);
panelRight.updateUI();
}
/**
* DOCUMENT ME!
*
* @param enable DOCUMENT ME!
*/
private void enableFilterPanels(boolean enable) {
for (int i = 0; i < panelTableFilters.getComponentCount(); i++) {
panelTableFilters.getComponent(i).setEnabled(enable);
}
for (int i = 0; i < panelControlFilter.getComponentCount(); i++) {
panelControlFilter.getComponent(i).setEnabled(enable);
}
for (int i = 0; i < panelSelection.getComponentCount(); i++) {
panelSelection.getComponent(i).setEnabled(enable);
}
}
/**
* DOCUMENT ME!
*
* @param top DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
private void createNodes(DefaultMutableTreeNode top) throws MissingElementException {
DefaultMutableTreeNode table = null;
Iterator itSourceTables = model.getSourceTables().iterator();
while (itSourceTables.hasNext()) {
Element tableElement = (Element) itSourceTables.next();
if (tableElement.getAttributeValue(XMLTags.PROCESS).compareTo("true") == 0) {
table = new DefaultMutableTreeNode(tableElement.getAttributeValue(XMLTags.NAME));
top.add(table);
}
}
}
/**
* DOCUMENT ME!
*/
private void guiInit() {
borderLayout.setHgap(10);
borderLayout.setVgap(10);
borderRightPanel = BorderFactory.createEmptyBorder(0, 0, 0, 0);
panelOptions.setLayout(null);
splitPane.setBorder(BorderFactory.createEmptyBorder());
splitPane.setOpaque(false);
splitPane.setOneTouchExpandable(true);
splitPane.setContinuousLayout(true);
splitPane.setResizeWeight(0.3);
splitPane.setLastDividerLocation(splitPane.getDividerLocation());
borderLayoutRight.setHgap(0);
borderLayoutRight.setVgap(0);
panelRight.setLayout(borderLayoutRight);
gridLayoutFilter.setColumns(1);
gridLayoutFilter.setHgap(0);
gridLayoutFilter.setRows(3);
gridLayoutFilter.setVgap(5);
borderLayoutTextfield.setHgap(5);
panelControlFilter.setLayout(null);
panelSelection.setLayout(borderLayoutTextfield);
panelTableFilters.setMinimumSize(new Dimension(300, 105));
panelTableFilters.setPreferredSize(new Dimension(300, 105));
panelTableFilters.setLayout(gridLayoutFilter);
panelTableFilters.setBorder(BorderFactory.createCompoundBorder(new TitledBorder(BorderFactory.createLineBorder(SystemColor.controlText, 1), " Specify Table Filters "), BorderFactory.createEmptyBorder(5, 5, 5, 5)));
buttonApplyTestFilter.setBounds(new Rectangle(1, 1, 115, 19));
buttonApplyTestFilter.setText(rm.getString("button.applyAndTest"));
buttonApplyTestFilter.addActionListener(new PanelProcessColumn_buttonApplyTestFilter_actionAdapter(this));
buttonDeleteFilter.setBounds(new Rectangle(125, 1, 115, 19));
buttonDeleteFilter.setText(rm.getString("button.delete"));
buttonDeleteFilter.addActionListener(new PanelProcessColumn_buttonDeleteFilter_actionAdapter(this));
buttonDeleteFilter.setEnabled(false);
checkBoxProcess.setText(rm.getString("text.column.process"));
checkBoxProcess.addActionListener(new PanelProcessColumn_checkBoxProcess_actionAdapter(this));
tfFilter.setToolTipText(rm.getString("text.column.tableFilter.toolTip"));
labelSelect.setText(SQL_START + "<TABLE>" + WHERE);
labelInfo.setText("");
labelInfo.setBounds(new Rectangle(255, 2, 150, 15));
panelSelection.add(tfFilter, BorderLayout.CENTER);
panelSelection.add(checkBoxProcess, BorderLayout.EAST);
panelControlFilter.add(buttonApplyTestFilter, null);
panelControlFilter.add(buttonDeleteFilter, null);
panelControlFilter.add(labelInfo, null);
panelTableFilters.add(labelSelect, null);
panelTableFilters.add(panelSelection, null);
panelTableFilters.add(panelControlFilter, null);
panelProcessColumns = new JPanel(new BorderLayout());
panelRight.add(panelProcessColumns, BorderLayout.CENTER);
panelRight.add(panelTableFilters, BorderLayout.SOUTH);
panelRight.setBorder(borderRightPanel);
splitPane.setDividerLocation(splitPane.getLastDividerLocation());
scrollPaneTree = new JScrollPane();
scrollPaneTables = new JScrollPane(panelRight);
splitPane.add(scrollPaneTree, JSplitPane.LEFT);
splitPane.add(scrollPaneTables, JSplitPane.RIGHT);
this.setLayout(borderLayout);
this.add(panelOptions, BorderLayout.NORTH);
this.add(splitPane, BorderLayout.CENTER);
enableFilterPanels(false);
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
void buttonApplyTestFilter_actionPerformed(ActionEvent e) {
if (tfFilter.getText().length() > 0) {
if (currentTable != null) {
try {
Element tableFilter = model.getTableFilter(currentTable);
if (tableFilter != null) {
tableFilter.setAttribute(XMLTags.VALUE, tfFilter.getText());
tableFilter.setAttribute(XMLTags.PROCESS, "true");
} else {
tableFilter = new Element(XMLTags.TABLE);
tableFilter.setAttribute(XMLTags.NAME, currentTable);
tableFilter.setAttribute(XMLTags.VALUE, tfFilter.getText());
tableFilter.setAttribute(XMLTags.PROCESS, "true");
model.getFilter().addContent(tableFilter);
}
// now run the test execute with table filter
Element operation = new Element(XMLTags.OPERATION);
operation.setAttribute(XMLTags.NAME, OperationType.TEST_TABLE_FILTER);
operation.setAttribute(XMLTags.TABLE, currentTable);
execute(operation, rm.getString("message.column.filter.successful"));
// now update the gui
loadColumnsAndFilter(currentTable);
} catch (Exception ex) {
postException(ex);
}
}
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
void checkBoxProcess_actionPerformed(ActionEvent e) {
try {
Element tableFilter = model.getTableFilter(currentTable);
if (tableFilter != null) {
if (checkBoxProcess.isSelected()) {
tableFilter.setAttribute(XMLTags.PROCESS, "true");
} else {
tableFilter.setAttribute(XMLTags.PROCESS, "false");
}
}
} catch (Exception ex) {
postException(ex);
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
void buttonDeleteFilter_actionPerformed(ActionEvent e) {
// delete old table filter if exists
try {
model.deleteTableFilter(currentTable);
buttonDeleteFilter.setEnabled(false);
checkBoxProcess.setSelected(false);
tfFilter.setText("");
labelInfo.setText("");
} catch (Exception ex) {
postException(ex);
}
}
/**
* class description
*
* @author Anthony Smith
* @version $Revision$
*/
class ProcessColumnModel extends AbstractTableModel {
private String[] columnNames = { rm.getString("text.column.type"), rm.getString("text.column.sourceColumn"), rm.getString("text.column.process") };
public final Object[] longValues = { "TIMESTAMP(6)", "abcdefghijklmnopqrstuvwxyz", new Boolean(false) };
private List columnsList;
public ProcessColumnModel(List columnsList) {
this.columnsList = columnsList;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final int getColumnCount() {
return columnNames.length;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final int getRowCount() {
return columnsList.size();
}
/**
* DOCUMENT ME!
*
* @param col DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final String getColumnName(int col) {
return columnNames[col];
}
/**
* DOCUMENT ME!
*
* @param row DOCUMENT ME!
* @param col DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final Object getValueAt(int row,
int col) {
Element rowElement = (Element) columnsList.get(row);
switch (col) {
case 0: return rowElement.getAttributeValue(XMLTags.TYPE_NAME);
case 1: return rowElement.getAttributeValue(XMLTags.NAME);
case 2: return Boolean.valueOf(rowElement.getAttributeValue(XMLTags.PROCESS));
}
return "you should'nt be here";
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public final Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
public final boolean isCellEditable(int row,
int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
if (col < 2) {
return false;
} else {
return true;
}
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
public final void setValueAt(Object value,
int row,
int col) {
if (col == 2) {
Element rowElement = (Element) columnsList.get(row);
rowElement.setAttribute(XMLTags.PROCESS, ((Boolean) value).toString());
fireTableCellUpdated(row, col);
}
}
}
}
/**
* class description
*
* @author Anthony Smith
* @version $Revision$
*/
class PanelProcessColumn_buttonApplyTestFilter_actionAdapter implements java.awt.event.ActionListener {
PanelProcessColumn adaptee;
/**
* Creates a new PanelProcessColumn_buttonApplyTestFilter_actionAdapter object.
*
* @param adaptee DOCUMENT ME!
*/
PanelProcessColumn_buttonApplyTestFilter_actionAdapter(PanelProcessColumn adaptee) {
this.adaptee = adaptee;
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public final void actionPerformed(ActionEvent e) {
adaptee.buttonApplyTestFilter_actionPerformed(e);
}
}
/**
* class description
*
* @author Anthony Smith
* @version $Revision$
*/
class PanelProcessColumn_checkBoxProcess_actionAdapter implements java.awt.event.ActionListener {
PanelProcessColumn adaptee;
/**
* Creates a new PanelProcessColumn_checkBoxProcess_actionAdapter object.
*
* @param adaptee DOCUMENT ME!
*/
PanelProcessColumn_checkBoxProcess_actionAdapter(PanelProcessColumn adaptee) {
this.adaptee = adaptee;
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public final void actionPerformed(ActionEvent e) {
adaptee.checkBoxProcess_actionPerformed(e);
}
}
/**
* class description
*
* @author Anthony Smith
* @version $Revision$
*/
class PanelProcessColumn_buttonDeleteFilter_actionAdapter implements java.awt.event.ActionListener {
PanelProcessColumn adaptee;
/**
* Creates a new PanelProcessColumn_buttonDeleteFilter_actionAdapter object.
*
* @param adaptee DOCUMENT ME!
*/
PanelProcessColumn_buttonDeleteFilter_actionAdapter(PanelProcessColumn adaptee) {
this.adaptee = adaptee;
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public final void actionPerformed(ActionEvent e) {
adaptee.buttonDeleteFilter_actionPerformed(e);
}
}