ca.sqlpower.architect.swingui.ArchitectPropertiesDataSourceTypeOptionPanel.java Source code

Java tutorial

Introduction

Here is the source code for ca.sqlpower.architect.swingui.ArchitectPropertiesDataSourceTypeOptionPanel.java

Source

/*
 * Copyright (c) 2008, SQL Power Group Inc.
 *
 * This file is part of Power*Architect.
 *
 * Power*Architect 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 3 of the License, or
 * (at your option) any later version.
 *
 * Power*Architect 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, see <http://www.gnu.org/licenses/>. 
 */

package ca.sqlpower.architect.swingui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import ca.sqlpower.architect.ddl.DB2DDLGenerator;
import ca.sqlpower.architect.ddl.GenericDDLGenerator;
import ca.sqlpower.architect.ddl.HSQLDBDDLGenerator;
import ca.sqlpower.architect.ddl.MySqlDDLGenerator;
import ca.sqlpower.architect.ddl.OracleDDLGenerator;
import ca.sqlpower.architect.ddl.PostgresDDLGenerator;
import ca.sqlpower.architect.ddl.SQLServer2000DDLGenerator;
import ca.sqlpower.architect.ddl.SQLServer2005DDLGenerator;
import ca.sqlpower.architect.ddl.SQLServerDDLGenerator;
import ca.sqlpower.architect.profile.ColumnProfileResult;
import ca.sqlpower.architect.profile.ProfileFunctionDescriptor;
import ca.sqlpower.architect.profile.RemoteDatabaseProfileCreator;
import ca.sqlpower.architect.profile.RemoteDatabaseProfileCreator.AverageSQLFunction;
import ca.sqlpower.architect.profile.RemoteDatabaseProfileCreator.CaseWhenNullSQLFunction;
import ca.sqlpower.architect.profile.RemoteDatabaseProfileCreator.StringLengthSQLFunction;
import ca.sqlpower.sql.JDBCDataSourceType;
import ca.sqlpower.sqlobject.SQLIndex;
import ca.sqlpower.sqlobject.SQLType;
import ca.sqlpower.swingui.AddRemoveIcon;
import ca.sqlpower.swingui.db.DataSourceTypeEditorTabPanel;
import ca.sqlpower.swingui.table.TableUtils;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.FormLayout;

/**
 * This properties panel will allow users to modify all of the architect specific properties in
 * one tab panel.
 *
 * This name beats the {@link KettleDataSourceTypeOptionPanel} name for length.
 */
public class ArchitectPropertiesDataSourceTypeOptionPanel implements DataSourceTypeEditorTabPanel {

    /**
     * This stores the known DDL generator types. This list will need to be increased 
     * as more DDL Generators are added if we want users to be able to select them
     * from this menu. 
     */
    private enum KnownDDLGenerators {
        GENERIC("Generic", GenericDDLGenerator.class.getName()), DB2("DB2",
                DB2DDLGenerator.class.getName()), HSQLDB("HSQLDB", HSQLDBDDLGenerator.class.getName()), MY_SQL(
                        "My SQL", MySqlDDLGenerator.class.getName()), ORACLE("Oracle",
                                OracleDDLGenerator.class.getName()), POSTGRES("Postgres",
                                        PostgresDDLGenerator.class.getName()), SQL_SERVER_2000("SQL Server 2000",
                                                SQLServer2000DDLGenerator.class.getName()), SQL_SERVER_2005(
                                                        "SQL Server 2005",
                                                        SQLServer2005DDLGenerator.class.getName()), SQL_SERVER(
                                                                "SQL Server",
                                                                SQLServerDDLGenerator.class.getName());

        private String name;
        private String ddlClassName;

        private KnownDDLGenerators(String name, String ddlClassName) {
            this.name = name;
            this.ddlClassName = ddlClassName;
        }

        public String getName() {
            return name;
        }

        public String getDDLClassName() {
            return ddlClassName;
        }

        @Override
        public String toString() {
            return name;
        }
    }

    private class ProfileFunctionTableModel implements TableModel {

        private final List<ProfileFunctionDescriptor> descriptors = new ArrayList<ProfileFunctionDescriptor>();
        private final List<TableModelListener> listeners = new ArrayList<TableModelListener>();

        public void addTableModelListener(TableModelListener l) {
            listeners.add(l);
        }

        public Class<?> getColumnClass(int columnIndex) {
            if (columnIndex == 0 || columnIndex == 1) {
                return String.class;
            } else if (columnIndex == 2) {
                return JComboBox.class;
            } else if (columnIndex >= 3 && columnIndex <= 10) {
                return Boolean.class;
            } else {
                return null;
            }
        }

        public int getColumnCount() {
            return 11;
        }

        public String getColumnName(int columnIndex) {
            if (columnIndex == 0) {
                return "Architect Name";
            } else if (columnIndex == 1) {
                return "Data Type Name";
            } else if (columnIndex == 2) {
                return "Java Code";
            } else if (columnIndex == 3) {
                return "Count Distinct";
            } else if (columnIndex == 4) {
                return "Max Value";
            } else if (columnIndex == 5) {
                return "Min Value";
            } else if (columnIndex == 6) {
                return "Avg Value";
            } else if (columnIndex == 7) {
                return "Max Length";
            } else if (columnIndex == 8) {
                return "Min Length";
            } else if (columnIndex == 9) {
                return "Avg Length";
            } else if (columnIndex == 10) {
                return "Sum Decode";
            } else {
                return null;
            }
        }

        public int getRowCount() {
            return descriptors.size();
        }

        public Object getValueAt(int rowIndex, int columnIndex) {
            ProfileFunctionDescriptor pfd = descriptors.get(rowIndex);
            if (columnIndex == 0) {
                return pfd.getArchitectSpecificName();
            } else if (columnIndex == 1) {
                return pfd.getDataTypeName();
            } else if (columnIndex == 2) {
                return SQLType.getType(pfd.getDataTypeCode());
            } else if (columnIndex == 3) {
                return pfd.isCountDist();
            } else if (columnIndex == 4) {
                return pfd.isMaxValue();
            } else if (columnIndex == 5) {
                return pfd.isMinValue();
            } else if (columnIndex == 6) {
                return pfd.isAvgValue();
            } else if (columnIndex == 7) {
                return pfd.isMaxLength();
            } else if (columnIndex == 8) {
                return pfd.isMinLength();
            } else if (columnIndex == 9) {
                return pfd.isAvgLength();
            } else if (columnIndex == 10) {
                return pfd.isSumDecode();
            } else {
                return null;
            }
        }

        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return true;
        }

        public void removeTableModelListener(TableModelListener l) {
            listeners.remove(l);
        }

        public void setValueAt(Object value, int rowIndex, int columnIndex) {
            ProfileFunctionDescriptor pfd = descriptors.get(rowIndex);
            if (columnIndex == 0) {
                pfd.setArchitectSpecificName((String) value);
            } else if (columnIndex == 1) {
                pfd.setDataTypeName((String) value);
            } else if (columnIndex == 2) {
                pfd.setDataTypeCode(((SQLType) value).getType());
            } else if (columnIndex == 3) {
                pfd.setCountDist((Boolean) value);
            } else if (columnIndex == 4) {
                pfd.setMaxValue((Boolean) value);
            } else if (columnIndex == 5) {
                pfd.setMinValue((Boolean) value);
            } else if (columnIndex == 6) {
                pfd.setAvgValue((Boolean) value);
            } else if (columnIndex == 7) {
                pfd.setMaxLength((Boolean) value);
            } else if (columnIndex == 8) {
                pfd.setMinLength((Boolean) value);
            } else if (columnIndex == 9) {
                pfd.setAvgLength((Boolean) value);
            } else if (columnIndex == 10) {
                pfd.setSumDecode((Boolean) value);
            }
            for (int i = listeners.size() - 1; i >= 0; i--) {
                listeners.get(i).tableChanged(new TableModelEvent(this, rowIndex));
            }
        }

        public void addProfileFunctionDescriptor(ProfileFunctionDescriptor pfd) {
            descriptors.add(pfd);
            for (int i = listeners.size() - 1; i >= 0; i--) {
                listeners.get(i).tableChanged(new TableModelEvent(this));
            }
        }

        public ProfileFunctionDescriptor removeProfileFunctionDescriptor(int rowIndex) {
            ProfileFunctionDescriptor pfd = descriptors.remove(rowIndex);
            for (int i = listeners.size() - 1; i >= 0; i--) {
                listeners.get(i).tableChanged(new TableModelEvent(this));
            }
            return pfd;
        }

        public List<ProfileFunctionDescriptor> getProfileFunctionDescriptors() {
            return Collections.unmodifiableList(descriptors);
        }

    }

    private JPanel panel;

    private JDBCDataSourceType currentDSType;

    private final JTextField averageSQLFunctionField = new JTextField();
    private final JTextField stringLengthSQLFuncField = new JTextField();
    private final JTextField caseWhenNullSQLFuncField = new JTextField();
    private final JCheckBox updatableRSField = new JCheckBox("Supports Updatable Result Sets");
    private final JCheckBox quotesNameCheckBox = new JCheckBox(
            Messages.getString("ArchitectPropertiesDataSourceTypeOptionPanel.quotingNameLabel"));
    private final JComboBox ddlGeneratorCombo = new JComboBox(KnownDDLGenerators.values());

    /**
     * This is the table model displaying all of the profile function descriptors for editing.
     */
    private ProfileFunctionTableModel profileFunctionTableModel;

    /**
     * This is the table model displaying all of the index types for the current database type
     * for editing.
     */
    private DefaultTableModel indexTableModel;

    private String ddlGeneratorClass;

    public ArchitectPropertiesDataSourceTypeOptionPanel() {
        panel = new JPanel(new BorderLayout());
    }

    public void editDsType(JDBCDataSourceType dsType) {
        if (dsType == null) {
            panel.removeAll();
            return;
        }

        averageSQLFunctionField.setText("");
        stringLengthSQLFuncField.setText("");
        caseWhenNullSQLFuncField.setText("");
        updatableRSField.setSelected(false);
        quotesNameCheckBox.setVisible(false);
        ddlGeneratorCombo.setSelectedItem(KnownDDLGenerators.GENERIC);
        ddlGeneratorClass = dsType.getDDLGeneratorClass();
        ddlGeneratorCombo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (ddlGeneratorClass != null && ddlGeneratorClass.equals(PostgresDDLGenerator.class.getName())) {
                    quotesNameCheckBox.setVisible(true);
                } else {
                    quotesNameCheckBox.setVisible(false);
                    quotesNameCheckBox.setSelected(false);
                }
            }

        });

        currentDSType = dsType;
        profileFunctionTableModel = new ProfileFunctionTableModel();
        final JTable profileFunctionTable = new JTable(profileFunctionTableModel);
        TableUtils.fitColumnWidths(profileFunctionTable, 0);
        profileFunctionTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        profileFunctionTable.getColumnModel().getColumn(2)
                .setCellEditor(new DefaultCellEditor(new JComboBox(SQLType.getTypes())));

        indexTableModel = new DefaultTableModel();
        indexTableModel.addColumn("Index Type");
        final JTable indexTypeJTable = new JTable(indexTableModel);
        indexTypeJTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

        for (String property : dsType.getPropertyNames()) {
            if (property.contains("architect")) {
                if (property.contains("ca.sqlpower.architect.etl.kettle")) {
                    //Kettle has it's own tab so we will let those properties be defined there.
                } else if (property.contains(ProfileFunctionDescriptor.class.getName())) {
                    String descriptorString = dsType.getProperty(property);
                    final ProfileFunctionDescriptor pfd = ProfileFunctionDescriptor
                            .parseDescriptorString(descriptorString);
                    profileFunctionTableModel.addProfileFunctionDescriptor(pfd);
                } else if (property.contains(ColumnProfileResult.class.getName())) {
                    if (property.equals(RemoteDatabaseProfileCreator.propName(AverageSQLFunction.class))) {
                        averageSQLFunctionField.setText(dsType.getProperty(property));
                    } else if (property
                            .equals(RemoteDatabaseProfileCreator.propName(StringLengthSQLFunction.class))) {
                        stringLengthSQLFuncField.setText(dsType.getProperty(property));
                    } else if (property
                            .equals(RemoteDatabaseProfileCreator.propName(CaseWhenNullSQLFunction.class))) {
                        caseWhenNullSQLFuncField.setText(dsType.getProperty(property));
                    } else {
                        throw new IllegalStateException(
                                "No editor defined for the data source type property " + property);
                    }
                } else if (property.contains(SQLIndex.INDEX_TYPE_DESCRIPTOR)) {
                    indexTableModel.addRow(new String[] { dsType.getProperty(property) });
                } else {
                    throw new IllegalStateException(
                            "No editor defined for the data source type property " + property);
                }
            } else if (property.equals(JDBCDataSourceType.SUPPORTS_UPDATEABLE_RESULT_SETS)) {
                updatableRSField.setSelected(Boolean.parseBoolean(dsType.getProperty(property)));
            } else if (property.equals(JDBCDataSourceType.SUPPORTS_QUOTING_NAME)) {
                quotesNameCheckBox.setSelected(Boolean.parseBoolean(dsType.getProperty(property)));
            } else if (property.equals(JDBCDataSourceType.DDL_GENERATOR)) {
                ddlGeneratorCombo.setSelectedItem(KnownDDLGenerators.GENERIC);
                for (KnownDDLGenerators ddlg : KnownDDLGenerators.values()) {
                    if (dsType.getProperty(property).equals(ddlg.getDDLClassName())) {
                        ddlGeneratorCombo.setSelectedItem(ddlg);
                        break;
                    }
                }
            }
        }

        JComponent addRemoveProfileFunctionBar = new JPanel(new FlowLayout(FlowLayout.LEFT));
        addRemoveProfileFunctionBar
                .add(new JButton(new AbstractAction("", new AddRemoveIcon(AddRemoveIcon.Type.ADD)) {
                    public void actionPerformed(ActionEvent e) {
                        ProfileFunctionDescriptor pfd = new ProfileFunctionDescriptor("",
                                SQLType.getTypes()[0].getType(), false, false, false, false, false, false, false,
                                false);
                        pfd.setArchitectSpecificName("");
                        profileFunctionTableModel.addProfileFunctionDescriptor(pfd);
                    }
                }));
        addRemoveProfileFunctionBar
                .add(new JButton(new AbstractAction("", new AddRemoveIcon(AddRemoveIcon.Type.REMOVE)) {
                    public void actionPerformed(ActionEvent e) {
                        int[] selectedRows = profileFunctionTable.getSelectedRows();
                        for (int i = selectedRows.length - 1; i >= 0; i--) {
                            profileFunctionTableModel.removeProfileFunctionDescriptor(selectedRows[i]);
                        }
                    }
                }));

        JComponent addRemoveIndexBar = new JPanel(new FlowLayout(FlowLayout.LEFT));
        addRemoveIndexBar.add(new JButton(new AbstractAction("", new AddRemoveIcon(AddRemoveIcon.Type.ADD)) {
            public void actionPerformed(ActionEvent e) {
                indexTableModel.addRow(new String[] { "" });
            }
        }));
        addRemoveIndexBar.add(new JButton(new AbstractAction("", new AddRemoveIcon(AddRemoveIcon.Type.REMOVE)) {
            public void actionPerformed(ActionEvent e) {
                int[] selectedRows = indexTypeJTable.getSelectedRows();
                for (int i = selectedRows.length - 1; i >= 0; i--) {
                    indexTableModel.removeRow(selectedRows[i]);
                }
            }
        }));

        panel.removeAll();
        DefaultFormBuilder fb = new DefaultFormBuilder(new FormLayout("4dlu, pref, 4dlu, pref:grow, 4dlu",
                "pref, 4dlu, pref, 4dlu, pref, 2dlu, pref, 2dlu, pref, 4dlu, fill:min:grow, 2dlu, pref, 4dlu, pref, 2dlu, pref,2dlu, pref"));
        fb.nextColumn();
        fb.append(updatableRSField, quotesNameCheckBox);
        fb.nextLine();
        fb.nextLine();
        fb.nextColumn();
        fb.append("DDL Generator", ddlGeneratorCombo);
        fb.nextLine();
        fb.nextLine();
        fb.nextColumn();
        fb.append("Average SQL Function", averageSQLFunctionField);
        fb.nextLine();
        fb.nextLine();
        fb.nextColumn();
        fb.append("String Length SQL Function", stringLengthSQLFuncField);
        fb.nextLine();
        fb.nextLine();
        fb.nextColumn();
        fb.append("Case When Null SQL Function", caseWhenNullSQLFuncField);
        fb.nextLine();
        fb.nextLine();
        fb.nextColumn();
        fb.append(new JScrollPane(profileFunctionTable), 3);
        fb.nextLine();
        fb.nextLine();
        fb.nextColumn();
        fb.append(addRemoveProfileFunctionBar, 3);
        fb.nextLine();
        fb.nextLine();
        fb.nextColumn();
        JScrollPane indexScrollPane = new JScrollPane(indexTypeJTable);
        indexScrollPane.setPreferredSize(new Dimension((int) indexScrollPane.getPreferredSize().getWidth(),
                indexTypeJTable.getRowHeight() * 5));
        fb.append(indexScrollPane, 3);
        fb.nextLine();
        fb.nextLine();
        fb.nextColumn();
        fb.append(addRemoveIndexBar, 3);
        panel.add(fb.getPanel(), BorderLayout.CENTER);
    }

    public boolean applyChanges() {
        if (currentDSType == null) {
            return true;
        }

        currentDSType.putProperty(JDBCDataSourceType.DDL_GENERATOR,
                ((KnownDDLGenerators) ddlGeneratorCombo.getSelectedItem()).getDDLClassName());
        currentDSType.putProperty(JDBCDataSourceType.SUPPORTS_UPDATEABLE_RESULT_SETS,
                String.valueOf(updatableRSField.isSelected()));
        currentDSType.putProperty(JDBCDataSourceType.SUPPORTS_QUOTING_NAME,
                String.valueOf(quotesNameCheckBox.isSelected()));
        currentDSType.putProperty(RemoteDatabaseProfileCreator.propName(AverageSQLFunction.class),
                averageSQLFunctionField.getText());
        currentDSType.putProperty(RemoteDatabaseProfileCreator.propName(StringLengthSQLFunction.class),
                stringLengthSQLFuncField.getText());
        currentDSType.putProperty(RemoteDatabaseProfileCreator.propName(CaseWhenNullSQLFunction.class),
                caseWhenNullSQLFuncField.getText());

        for (int i = 0; i < profileFunctionTableModel.getProfileFunctionDescriptors().size(); i++) {
            currentDSType.putProperty(ProfileFunctionDescriptor.class.getName() + "_" + i, ProfileFunctionDescriptor
                    .createDescriptorString(profileFunctionTableModel.getProfileFunctionDescriptors().get(i)));
        }

        for (int i = 0; i < indexTableModel.getRowCount(); i++) {
            currentDSType.putProperty(SQLIndex.INDEX_TYPE_DESCRIPTOR + "_" + i,
                    (String) indexTableModel.getValueAt(i, 0));
        }

        return true;
    }

    public void discardChanges() {
        editDsType(currentDSType);
    }

    public JComponent getPanel() {
        return panel;
    }

    public boolean hasUnsavedChanges() {
        return true;
    }

}