All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.datacleaner.windows.CreateTableDialog Maven / Gradle / Ivy

There is a newer version: 6.0.0
Show newest version
/**
 * DataCleaner (community edition)
 * Copyright (C) 2014 Free Software Foundation, Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * 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 Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.datacleaner.windows;

import java.awt.GridBagConstraints;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComponent;

import org.apache.metamodel.MetaModelHelper;
import org.apache.metamodel.UpdateableDataContext;
import org.apache.metamodel.create.CreateTable;
import org.apache.metamodel.schema.Column;
import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.schema.ColumnTypeImpl;
import org.apache.metamodel.schema.Schema;
import org.datacleaner.api.InputColumn;
import org.datacleaner.bootstrap.WindowContext;
import org.datacleaner.connection.CsvDatastore;
import org.datacleaner.connection.Datastore;
import org.datacleaner.connection.UpdateableDatastore;
import org.datacleaner.connection.UpdateableDatastoreConnection;
import org.datacleaner.panels.CreateTableColumnDefintionPanel;
import org.datacleaner.panels.DCPanel;
import org.datacleaner.util.IconUtils;
import org.datacleaner.util.ImageManager;
import org.datacleaner.util.WidgetFactory;
import org.datacleaner.util.WidgetUtils;
import org.datacleaner.widgets.DCLabel;
import org.jdesktop.swingx.JXTextField;
import org.jdesktop.swingx.VerticalLayout;

/**
 * A dialog which gives the user the ability to create a table in a datastore.
 */
public class CreateTableDialog extends AbstractDialog {

    public interface Listener {
        void onTableCreated(UpdateableDatastore datastore, Schema schema, String tableName);
    }

    private static final long serialVersionUID = 1L;
    private final UpdateableDatastore _datastore;
    private final Schema _schema;
    private final DCPanel _columnsListPanel;
    private final List _columnDefinitionPanels;
    private final List _listeners;

    public CreateTableDialog(final WindowContext windowContext, final UpdateableDatastore datastore,
            final Schema schema) {
        this(windowContext, datastore, schema, null);
    }

    public CreateTableDialog(final WindowContext windowContext, final UpdateableDatastore datastore,
            final Schema schema, final Collection> columnSuggestions) {
        super(windowContext, ImageManager.get().getImage("images/window/banner-tabledef.png"));

        _datastore = datastore;
        _schema = schema;
        _listeners = new ArrayList<>(1);

        _columnDefinitionPanels = new ArrayList<>();

        _columnsListPanel = new DCPanel();
        _columnsListPanel.setBorder(WidgetUtils.BORDER_EMPTY);
        _columnsListPanel.setLayout(new VerticalLayout());

        if (columnSuggestions != null && !columnSuggestions.isEmpty()) {
            // add columns based on the suggestions
            for (final InputColumn columnSuggestion : columnSuggestions) {
                final String name = columnSuggestion.getName();
                if (columnSuggestion.isPhysicalColumn()) {
                    final Column physicalColumn = columnSuggestion.getPhysicalColumn();
                    final ColumnType columnType = physicalColumn.getType();
                    final boolean isPrimaryKey = physicalColumn.isPrimaryKey();
                    addColumnDefinitionPanel(new CreateTableColumnDefintionPanel(this, name, columnType, isPrimaryKey));
                } else {
                    final ColumnType columnType = ColumnTypeImpl.convertColumnType(columnSuggestion.getDataType());
                    addColumnDefinitionPanel(new CreateTableColumnDefintionPanel(this, name, columnType, false));
                }
            }
        } else {
            // add some columns to begin with
            addColumnDefinitionPanel(new CreateTableColumnDefintionPanel(this, "ID", ColumnType.INTEGER, true));
            addColumnDefinitionPanel();
        }
    }

    /**
     * Determines if it is appropriate/possible to create a table in a
     * particular schema or a particular datastore.
     *
     * @param datastore
     * @param schema
     * @return
     */
    public static boolean isCreateTableAppropriate(final Datastore datastore, final Schema schema) {
        if (datastore == null || schema == null) {
            return false;
        }
        if (!(datastore instanceof UpdateableDatastore)) {
            return false;
        }
        if (datastore instanceof CsvDatastore) {
            // see issue https://issues.apache.org/jira/browse/METAMODEL-31 - as
            // long as this is an issue we do not want to expose "create table"
            // functionality to CSV datastores.
            return false;
        }
        if (MetaModelHelper.isInformationSchema(schema)) {
            return false;
        }
        return true;
    }

    public void addListener(final Listener listener) {
        if (listener == null) {
            return;
        }
        _listeners.add(listener);
    }

    public void removeListener(final Listener listener) {
        _listeners.remove(listener);
    }

    @Override
    public String getWindowTitle() {
        return "Create table";
    }

    @Override
    protected String getBannerTitle() {
        return "Create table\nin schema '" + _schema.getName() + "'";
    }

    @Override
    protected int getDialogWidth() {
        return 700;
    }

    @Override
    protected JComponent getDialogContent() {
        final DCLabel label1 = DCLabel.darkMultiLine(
                "Please fill out the name and describe the columns that should comprise your new table. "
                        + "The table will be created in the schema '" + _schema.getName() + "' of datastore '"
                        + _datastore.getName() + "'");

        final DCLabel label2 = DCLabel.darkMultiLine("Note that the column data types may be adapted/interpreted in "
                + "order to fit the type of datastore, should they not apply to the datastore natively.");

        final JXTextField tableNameTextField = WidgetFactory.createTextField("Table name");

        final JButton createTableButton =
                WidgetFactory.createPrimaryButton("Create table", IconUtils.ACTION_CREATE_TABLE);
        createTableButton.addActionListener(e -> {
            final String tableName = tableNameTextField.getText().trim();
            if (tableName.isEmpty()) {
                WidgetUtils.showErrorMessage("Invalid table name", "Please enter a valid table name.");
                return;
            }

            if (_columnDefinitionPanels.isEmpty()) {
                WidgetUtils.showErrorMessage("No columns defined", "Please add at least one column to the table.");
                return;
            }

            final List columns = new ArrayList<>(_columnDefinitionPanels.size());
            for (final CreateTableColumnDefintionPanel columnDefinitionPanel : _columnDefinitionPanels) {
                columnDefinitionPanel.highlightIssues();
                if (!columnDefinitionPanel.isColumnDefined()) {
                    return;
                }
                columns.add(columnDefinitionPanel.toColumn());
            }

            doCreateTable(tableName, columns);
            for (final Listener listener : _listeners) {
                listener.onTableCreated(_datastore, _schema, tableName);
            }
            CreateTableDialog.this.close();
        });

        final JButton cancelButton = WidgetFactory.createDefaultButton("Cancel", IconUtils.ACTION_CANCEL);
        cancelButton.addActionListener(e -> CreateTableDialog.this.close());

        final JButton addColumnButton = WidgetFactory.createSmallButton("Add column", IconUtils.ACTION_ADD_DARK);
        addColumnButton.addActionListener(e -> addColumnDefinitionPanel());

        final JButton removeAllColumnsButton =
                WidgetFactory.createSmallButton("Remove all columns", IconUtils.ACTION_REMOVE_DARK);
        removeAllColumnsButton.setForeground(WidgetUtils.ADDITIONAL_COLOR_RED_BRIGHT);
        removeAllColumnsButton.addActionListener(e -> removeAllColumns());

        final DCPanel buttonPanel = DCPanel.flow(addColumnButton, removeAllColumnsButton);
        buttonPanel.setBorder(WidgetUtils.BORDER_EMPTY);

        final DCPanel panel = new DCPanel(WidgetUtils.COLOR_WELL_BACKGROUND);
        int row = 0;
        WidgetUtils.addToGridBag(label1, panel, 0, row, 2, 1);
        row++;
        WidgetUtils.addToGridBag(tableNameTextField, panel, 0, row, 2, 1);
        row++;
        WidgetUtils.addToGridBag(label2, panel, 0, row, 2, 1);
        row++;
        WidgetUtils.addToGridBag(buttonPanel, panel, 0, row, 2, 1);
        row++;
        WidgetUtils.addToGridBag(WidgetUtils.scrolleable(_columnsListPanel), panel, 0, row, 2, 1,
                GridBagConstraints.NORTHWEST, 0, 1.0, 1.0, GridBagConstraints.BOTH);
        row++;
        WidgetUtils.addToGridBag(createTableButton, panel, 0, row, 0.5, 0.1);
        WidgetUtils.addToGridBag(cancelButton, panel, 1, row, 0.5, 0.1);

        panel.setPreferredSize(getDialogWidth(), 400);

        return panel;
    }

    protected boolean isWindowResizable() {
        return true;
    }

    protected void doCreateTable(final String tableName, final List columns) {
        try (UpdateableDatastoreConnection con = _datastore.openConnection()) {
            final CreateTable createTable = new CreateTable(_schema, tableName);
            for (final Column column : columns) {
                createTable.withColumn(column.getName()).like(column);
            }
            final UpdateableDataContext dataContext = con.getUpdateableDataContext();
            dataContext.executeUpdate(createTable);
        }
    }

    public void removeColumnDefinitionPanel(final CreateTableColumnDefintionPanel columnDefintionPanel) {
        _columnDefinitionPanels.remove(columnDefintionPanel);
        _columnsListPanel.remove(columnDefintionPanel);
        _columnsListPanel.updateUI();
    }

    public void addColumnDefinitionPanel() {
        final CreateTableColumnDefintionPanel columnDefintionPanel = new CreateTableColumnDefintionPanel(this);
        addColumnDefinitionPanel(columnDefintionPanel);
    }


    protected void removeAllColumns() {
        _columnDefinitionPanels.clear();
        _columnsListPanel.removeAll();
        _columnsListPanel.updateUI();
    }

    private void addColumnDefinitionPanel(final CreateTableColumnDefintionPanel columnDefintionPanel) {
        _columnDefinitionPanels.add(columnDefintionPanel);
        _columnsListPanel.add(columnDefintionPanel);
        _columnsListPanel.updateUI();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy