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

org.datacleaner.widgets.properties.SingleDatastorePropertyWidget 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.widgets.properties;

import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

import org.datacleaner.connection.Datastore;
import org.datacleaner.connection.DatastoreCatalog;
import org.datacleaner.connection.DatastoreConnection;
import org.datacleaner.connection.DatastoreDescriptor;
import org.datacleaner.connection.DatastoreDescriptors;
import org.datacleaner.database.DatabaseDriverCatalog;
import org.datacleaner.descriptors.ConfiguredPropertyDescriptor;
import org.datacleaner.guice.DCModule;
import org.datacleaner.job.builder.ComponentBuilder;
import org.datacleaner.panels.DCPanel;
import org.datacleaner.user.DatastoreChangeListener;
import org.datacleaner.user.MutableDatastoreCatalog;
import org.datacleaner.util.IconUtils;
import org.datacleaner.util.ReflectionUtils;
import org.datacleaner.util.WidgetFactory;
import org.datacleaner.util.WidgetUtils;
import org.datacleaner.widgets.DCComboBox;
import org.datacleaner.widgets.DCComboBox.Listener;
import org.datacleaner.widgets.PopupButton;
import org.datacleaner.widgets.SchemaStructureComboBoxListRenderer;
import org.datacleaner.windows.AbstractDialog;
import org.datacleaner.windows.JdbcDatastoreDialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Injector;

/**
 * {@link PropertyWidget} for single datastore properties. Shown as a combo box.
 *
 * @author Kasper Sørensen
 */
public class SingleDatastorePropertyWidget extends AbstractPropertyWidget
        implements DatastoreChangeListener {

    private static final Logger logger = LoggerFactory.getLogger(SingleDatastorePropertyWidget.class);

    private final DatastoreCatalog _datastoreCatalog;
    private final DCComboBox _comboBox;
    private final DCPanel _panelAroundButton;
    private final PopupButton _createDatastoreButton;
    private final Class _datastoreClass;
    private final DCModule _dcModule;
    private volatile DatastoreConnection _connection;
    private boolean _onlyUpdatableDatastores = false;

    @Inject
    public SingleDatastorePropertyWidget(final ComponentBuilder componentBuilder,
            final ConfiguredPropertyDescriptor propertyDescriptor, final DatastoreCatalog datastoreCatalog,
            final DCModule dcModule) {
        super(componentBuilder, propertyDescriptor);
        _datastoreCatalog = datastoreCatalog;
        _dcModule = dcModule;
        _datastoreClass = propertyDescriptor.getBaseType();

        final String[] datastoreNames = _datastoreCatalog.getDatastoreNames();
        final List list = new ArrayList<>();

        if (!propertyDescriptor.isRequired()) {
            list.add(null);
        }

        for (int i = 0; i < datastoreNames.length; i++) {
            final Datastore datastore = _datastoreCatalog.getDatastore(datastoreNames[i]);
            if (ReflectionUtils.is(datastore.getClass(), _datastoreClass)) {
                // only include correct subtypes of datastore, it may be eg. a
                // CsvDatastore property.
                list.add(datastore);
            }
        }
        _comboBox = new DCComboBox<>(list);
        _comboBox.setRenderer(new SchemaStructureComboBoxListRenderer());

        addComboListener(item -> {
            openConnection(item);
            fireValueChanged();
        });

        final Datastore currentValue = (Datastore) componentBuilder.getConfiguredProperty(propertyDescriptor);
        setValue(currentValue);

        _createDatastoreButton = WidgetFactory.createSmallPopupButton("", IconUtils.ACTION_CREATE_TABLE);
        _createDatastoreButton.setToolTipText("Create datastore");
        final JPopupMenu createDatastoreMenu = _createDatastoreButton.getMenu();
        populateCreateDatastoreMenu(createDatastoreMenu);

        _panelAroundButton = DCPanel.around(_createDatastoreButton);
        _panelAroundButton.setBorder(WidgetUtils.BORDER_EMPTY);
        _panelAroundButton.setVisible(true);

        final DCPanel panel = new DCPanel();
        panel.setLayout(new BorderLayout());
        panel.add(_comboBox, BorderLayout.CENTER);
        panel.add(_panelAroundButton, BorderLayout.EAST);

        add(panel);
    }

    public void setOnlyUpdatableDatastores(final boolean onlyUpdatableDatastores) {
        _onlyUpdatableDatastores = onlyUpdatableDatastores;
        final JPopupMenu menu = _createDatastoreButton.getMenu();
        menu.removeAll();
        populateCreateDatastoreMenu(menu);
    }

    private void populateCreateDatastoreMenu(final JPopupMenu createDatastoreMenu) {
        final DatabaseDriverCatalog databaseDriverCatalog =
                _dcModule.createInjectorBuilder().getInstance(DatabaseDriverCatalog.class);

        final List availableDatastoreDescriptors =
                new DatastoreDescriptors(databaseDriverCatalog).getAvailableDatastoreDescriptors();

        for (final DatastoreDescriptor datastoreDescriptor : availableDatastoreDescriptors) {
            if (_onlyUpdatableDatastores) {
                if (!datastoreDescriptor.isUpdatable()) {
                    continue;
                }
            }

            final JMenuItem menuItem =
                    WidgetFactory.createMenuItem(datastoreDescriptor.getName(), datastoreDescriptor.getIconPath());
            menuItem.addActionListener(
                    createActionListener(datastoreDescriptor.getName(), datastoreDescriptor.getDatastoreClass(),
                            datastoreDescriptor.getDatastoreDialogClass()));
            createDatastoreMenu.add(menuItem);
        }
    }

    private ActionListener createActionListener(final String datastoreName,
            final Class datastoreClass,
            final Class datastoreDialogClass) {
        return e -> {
            final Injector injectorWithNullDatastore =
                    _dcModule.createInjectorBuilder().with(datastoreClass, null).createInjector();
            final AbstractDialog dialog = injectorWithNullDatastore.getInstance(datastoreDialogClass);
            if (dialog instanceof JdbcDatastoreDialog) {
                final JdbcDatastoreDialog jdbcDatastoreDialog = (JdbcDatastoreDialog) dialog;
                jdbcDatastoreDialog.setSelectedDatabase(datastoreName);
            }
            dialog.setVisible(true);
        };
    }

    public void addComboListener(final Listener listener) {
        _comboBox.addListener(listener);
    }

    @Override
    public void onPanelAdd() {
        super.onPanelAdd();
        if (_datastoreCatalog instanceof MutableDatastoreCatalog) {
            ((MutableDatastoreCatalog) _datastoreCatalog).addListener(this);
        }
    }

    @Override
    public void onPanelRemove() {
        super.onPanelRemove();
        if (_datastoreCatalog instanceof MutableDatastoreCatalog) {
            ((MutableDatastoreCatalog) _datastoreCatalog).removeListener(this);
        }
        openConnection(null);
    }

    @Override
    public Datastore getValue() {
        final Object selectedItem = _comboBox.getSelectedItem();
        final Datastore datastore = (Datastore) selectedItem;
        openConnection(datastore);
        return datastore;
    }

    @Override
    protected void setValue(final Datastore value) {
        if (value == null) {
            _comboBox.setSelectedItem(null);
            return;
        }

        if (getValue() == value) {
            return;
        }

        openConnection(value);

        _comboBox.setEditable(true);
        _comboBox.setSelectedItem(value);
        _comboBox.setEditable(false);
    }

    private void openConnection(final Datastore datastore) {
        if (_connection != null && _connection.getDatastore() == datastore) {
            return;
        }
        if (_connection != null) {
            _connection.close();
            _connection = null;
        }
        if (datastore != null) {
            try {
                _connection = datastore.openConnection();
            } catch (final Exception e) {
                logger.warn("Could not open connection to datastore: {}", datastore);
            }
        }
    }

    @Override
    public void onAdd(final Datastore datastore) {
        if (ReflectionUtils.is(datastore.getClass(), _datastoreClass)) {
            _comboBox.setEditable(true);
            _comboBox.addItem(datastore);
            _comboBox.setEditable(false);
        }
    }

    @Override
    public void onRemove(final Datastore datastore) {
        _comboBox.setEditable(true);
        _comboBox.removeItem(datastore);
        _comboBox.setEditable(false);
    }

    public void connectToSchemaNamePropertyWidget(final SchemaNamePropertyWidget schemaNamePropertyWidget) {
        addComboListener(schemaNamePropertyWidget::setDatastore);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy