org.pentaho.reporting.ui.datasources.kettle.KettleDataSourceDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.reporting.ui.datasources.kettle.KettleDataSourceDialog.java

Source

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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.
*
* Copyright (c) 2002-2017 Hitachi Vantara..  All rights reserved.
*/

package org.pentaho.reporting.ui.datasources.kettle;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.openformula.ui.DefaultFieldDefinition;
import org.pentaho.openformula.ui.FieldDefinition;
import org.pentaho.reporting.engine.classic.core.DataFactoryContext;
import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException;
import org.pentaho.reporting.engine.classic.core.designtime.DesignTimeContext;
import org.pentaho.reporting.engine.classic.core.designtime.DesignTimeUtil;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.DataFactoryEditorSupport;
import org.pentaho.reporting.engine.classic.core.modules.gui.commonswing.ExceptionDialog;
import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchemaModel;
import org.pentaho.reporting.engine.classic.extensions.datasources.kettle.FormulaArgument;
import org.pentaho.reporting.engine.classic.extensions.datasources.kettle.FormulaParameter;
import org.pentaho.reporting.engine.classic.extensions.datasources.kettle.KettleDataFactory;
import org.pentaho.reporting.engine.classic.extensions.datasources.kettle.KettleTransformationProducer;
import org.pentaho.reporting.libraries.base.util.FilesystemFilter;
import org.pentaho.reporting.libraries.base.util.IOUtils;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.designtime.swing.BorderlessButton;
import org.pentaho.reporting.libraries.designtime.swing.CommonDialog;
import org.pentaho.reporting.libraries.designtime.swing.background.CancelEvent;
import org.pentaho.reporting.libraries.designtime.swing.background.DataPreviewDialog;
import org.pentaho.reporting.libraries.designtime.swing.background.PreviewWorker;
import org.pentaho.reporting.libraries.designtime.swing.filechooser.CommonFileChooser;
import org.pentaho.reporting.libraries.designtime.swing.filechooser.FileChooserService;
import org.pentaho.reporting.libraries.designtime.swing.icons.IconLoader;
import org.pentaho.reporting.ui.datasources.kettle.embedded.KettleParameterInfo;
import org.pentaho.reporting.ui.datasources.kettle.parameter.FormulaParameterDialog;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.HashSet;
import java.util.List;

/**
 * @author Ezequiel Cuellar
 */
public class KettleDataSourceDialog extends CommonDialog {

    private class BrowseAction extends AbstractAction implements ListSelectionListener {
        private BrowseAction() {
            putValue(Action.NAME, Messages.getString("KettleDataSourceDialog.Browse.Name"));
            setEnabled(false);
        }

        public void actionPerformed(final ActionEvent e) {
            final FileFilter[] fileFilters = new FileFilter[] { new FilesystemFilter(new String[] { ".ktr" },
                    Messages.getString("KettleDataSourceDialog.KtrFileDescription") + " (*.ktr)", true) };

            final File reportContextFile = DesignTimeUtil.getContextAsFile(designTimeContext.getReport());

            final CommonFileChooser fileChooser = FileChooserService.getInstance().getFileChooser("kettle");
            final String fileText = fileTextField.getText();
            if (StringUtils.isEmpty(fileText) == false) {
                if (reportContextFile != null) {
                    fileChooser
                            .setSelectedFile(new File(reportContextFile.getParentFile(), fileTextField.getText()));
                } else {
                    fileChooser.setSelectedFile(new File(fileTextField.getText()));
                }
            }
            fileChooser.setFilters(fileFilters);
            if (fileChooser.showDialog(KettleDataSourceDialog.this, JFileChooser.OPEN_DIALOG) == false) {
                return;
            }

            final File file = fileChooser.getSelectedFile();
            if (file == null) {
                return;
            }

            final String path;
            if (reportContextFile != null) {
                path = IOUtils.getInstance().createRelativePath(file.getPath(),
                        reportContextFile.getAbsolutePath());
            } else {
                path = file.getPath();
            }
            final KettleQueryEntry queryEntry = (KettleQueryEntry) queryNameList.getSelectedValue();
            if (queryEntry instanceof FileKettleQueryEntry) {
                FileKettleQueryEntry fe = (FileKettleQueryEntry) queryEntry;
                fe.setFile(path);
            }
            fileTextField.setText(path);
        }

        /**
         * Called whenever the value of the selection changes.
         *
         * @param e the event that characterizes the change.
         */
        public void valueChanged(final ListSelectionEvent e) {
            setEnabled(queryNameList.getSelectedValue() != null);
        }
    }

    private class NameSyncHandler implements DocumentListener {
        private NameSyncHandler() {
        }

        /**
         * Gives notification that there was an insert into the document.  The range given by the DocumentEvent bounds the
         * freshly inserted region.
         *
         * @param e the document event
         */
        public void insertUpdate(final DocumentEvent e) {
            update();
        }

        /**
         * Gives notification that a portion of the document has been removed.  The range is given in terms of what the view
         * last saw (that is, before updating sticky positions).
         *
         * @param e the document event
         */
        public void removeUpdate(final DocumentEvent e) {
            update();
        }

        /**
         * Gives notification that an attribute or set of attributes changed.
         *
         * @param e the document event
         */
        public void changedUpdate(final DocumentEvent e) {
            update();
        }

        private void update() {
            if (inUpdateFromList) {
                return;
            }

            final String queryName = nameTextField.getText();
            final KettleQueryEntry selectedQuery = (KettleQueryEntry) queryNameList.getSelectedValue();
            selectedQuery.setName(queryName);
            queryNameList.repaint();
        }
    }

    private class FileSyncHandler implements DocumentListener, Runnable {
        private boolean armed;

        private FileSyncHandler() {
        }

        /**
         * Gives notification that there was an insert into the document.  The range given by the DocumentEvent bounds the
         * freshly inserted region.
         *
         * @param e the document event
         */
        public void insertUpdate(final DocumentEvent e) {
            update();
        }

        /**
         * Gives notification that a portion of the document has been removed.  The range is given in terms of what the view
         * last saw (that is, before updating sticky positions).
         *
         * @param e the document event
         */
        public void removeUpdate(final DocumentEvent e) {
            update();
        }

        /**
         * Gives notification that an attribute or set of attributes changed.
         *
         * @param e the document event
         */
        public void changedUpdate(final DocumentEvent e) {
            update();
        }

        private void update() {
            if (armed) {
                return;
            }
            armed = true;
            SwingUtilities.invokeLater(this);
        }

        public void run() {
            final String fileName = fileTextField.getText();
            final KettleQueryEntry selectedQuery = (KettleQueryEntry) queryNameList.getSelectedValue();
            if (selectedQuery instanceof FileKettleQueryEntry == false) {
                return;
            }
            FileKettleQueryEntry fe = (FileKettleQueryEntry) selectedQuery;
            fe.setFile(fileName);

            try {
                inUpdateFromList = true;
                refreshStepList(fe);
                stepsList.setEnabled(true);
                editParameterAction.setEnabled(true);
                stopOnErrorsCheckBox.setEnabled(true);
            } catch (final ReportDataFactoryException rdfe) {
                logger.warn("Non-critical failure while executing the query", rdfe);
                stepsList.setEnabled(false);
                editParameterAction.setEnabled(false);
                stopOnErrorsCheckBox.setEnabled(false);
            } catch (final Exception e1) {
                designTimeContext.error(e1);
                stepsList.setEnabled(false);
                editParameterAction.setEnabled(false);
                stopOnErrorsCheckBox.setEnabled(false);
            } catch (final Throwable t1) {
                designTimeContext.error(new RuntimeException("Fatal error", t1));
                stepsList.setEnabled(false);
                editParameterAction.setEnabled(false);
                stopOnErrorsCheckBox.setEnabled(false);
            } finally {
                inUpdateFromList = false;
                armed = false;
            }
        }
    }

    private void refreshStepList(final FileKettleQueryEntry fe) throws KettleException, ReportDataFactoryException {
        DataFactoryContext dataFactoryContext = getDesignTimeContext().getDataFactoryContext();
        final List<StepMeta> data = fe.getSteps(dataFactoryContext);
        stepsList.setListData(data.toArray(new StepMeta[data.size()]));
        final String selectedStepName = fe.getSelectedStep();
        if (selectedStepName != null) {
            for (final StepMeta stepMeta : data) {
                if (selectedStepName.equals(stepMeta.getName())) {
                    stepsList.setSelectedValue(stepMeta, true);
                    break;
                }
            }
        }
    }

    private class StepsListListener implements ListSelectionListener {
        private StepsListListener() {
        }

        public void valueChanged(final ListSelectionEvent aEvt) {
            final KettleQueryEntry queryEntry = (KettleQueryEntry) queryNameList.getSelectedValue();
            if (queryEntry instanceof FileKettleQueryEntry) {
                FileKettleQueryEntry fe = (FileKettleQueryEntry) queryEntry;
                final StepMeta selectedValue = (StepMeta) stepsList.getSelectedValue();
                if (selectedValue != null) {
                    fe.setSelectedStep(selectedValue.getName());
                }
            }
        }
    }

    protected class QueryNameListSelectionListener implements ListSelectionListener {
        protected QueryNameListSelectionListener() {
        }

        public void valueChanged(final ListSelectionEvent e) {
            final KettleQueryEntry value = getSelectedQuery();
            if (value == null) {
                nameTextField.setEnabled(false);
                fileTextField.setEnabled(false);
                stepsList.setEnabled(false);
                editParameterAction.setEnabled(false);
                stopOnErrorsCheckBox.setEnabled(false);
                stopOnErrorsCheckBox.setSelected(false);
                handleSelection(value);
                return;
            }

            inUpdateFromList = true;
            nameTextField.setEnabled(true);
            fileTextField.setEnabled(true);

            try {
                nameTextField.setText(value.getName());
                editParameterAction.setEnabled(true);
                stopOnErrorsCheckBox.setSelected(value.isStopOnErrors());
                stopOnErrorsCheckBox.setEnabled(true);
                handleSelection(value);
            } finally {
                inUpdateFromList = false;
            }
        }

        protected void handleSelection(final KettleQueryEntry value) {
            if (value instanceof FileKettleQueryEntry) {
                handleSelection((FileKettleQueryEntry) value);
            }
        }

        protected void handleSelection(final FileKettleQueryEntry selectedQuery) {
            try {
                fileTextField.setText(selectedQuery.getFile());
                refreshStepList(selectedQuery);
                stepsList.setEnabled(true);
                editParameterAction.setEnabled(true);
                stopOnErrorsCheckBox.setEnabled(true);
            } catch (final ReportDataFactoryException rdfe) {
                logger.warn("Non-critical failure while executing the query", rdfe);
                stepsList.setEnabled(false);
                editParameterAction.setEnabled(false);
                stopOnErrorsCheckBox.setEnabled(false);
            } catch (final Exception e1) {
                designTimeContext.error(e1);
                stepsList.setEnabled(false);
                editParameterAction.setEnabled(false);
                stopOnErrorsCheckBox.setEnabled(false);
            } catch (final Throwable t1) {
                designTimeContext.error(new RuntimeException("Fatal error", t1));
                stepsList.setEnabled(false);
                editParameterAction.setEnabled(false);
                stopOnErrorsCheckBox.setEnabled(false);
            }
        }
    }

    private class AddQueryAction extends AbstractAction {
        public AddQueryAction() {
            putValue(Action.SMALL_ICON, IconLoader.getInstance().getAddIcon());
            putValue(Action.SHORT_DESCRIPTION, Messages.getString("KettleDataSourceDialog.AddQuery.Description"));
        }

        public void actionPerformed(final ActionEvent e) {
            String queryName = findNextName();

            try {
                final KettleQueryEntry newQuery = createNewQueryEntry(queryName);
                queryListModel.addElement(newQuery);
                queryNameList.setSelectedValue(newQuery, true);
            } catch (final KettleException e1) {
                getDesignTimeContext().error(e1);
            }

        }
    }

    private class RemoveQueryAction extends AbstractAction implements ListSelectionListener {
        public RemoveQueryAction() {
            putValue(Action.SMALL_ICON, IconLoader.getInstance().getDeleteIcon());
            putValue(Action.SHORT_DESCRIPTION,
                    Messages.getString("KettleDataSourceDialog.RemoveQuery.Description"));
            setEnabled(false);
        }

        public void actionPerformed(final ActionEvent e) {
            final Object selectedValue = queryNameList.getSelectedValue();
            if (selectedValue == null) {
                return;
            }
            inUpdateFromList = true;
            try {
                clearComponents();
                queryListModel.removeElement(selectedValue);
            } finally {
                inUpdateFromList = false;
            }
        }

        /**
         * Called whenever the value of the selection changes.
         *
         * @param e the event that characterizes the change.
         */
        public void valueChanged(final ListSelectionEvent e) {
            setEnabled(queryNameList.getSelectedValue() != null);
        }
    }

    private class PreviewAction extends AbstractAction implements ListSelectionListener {
        private PreviewAction() {
            putValue(Action.NAME, Messages.getString("KettleDataSourceDialog.Preview.Name"));
            setEnabled(false);
        }

        public void actionPerformed(final ActionEvent e) {
            try {
                final KettleQueryEntry kettleQueryEntry = (KettleQueryEntry) queryNameList.getSelectedValue();
                final KettleTransformationProducer fileProducer = kettleQueryEntry.createProducer();
                final KettleDataFactory dataFactory = new KettleDataFactory();
                dataFactory.setQuery(kettleQueryEntry.getName(), fileProducer);

                DataFactoryEditorSupport.configureDataFactoryForPreview(dataFactory, designTimeContext);

                final DataPreviewDialog previewDialog = new DataPreviewDialog(KettleDataSourceDialog.this);

                final KettlePreviewWorker worker = new KettlePreviewWorker(dataFactory, kettleQueryEntry.getName());
                previewDialog.showData(worker);

                final ReportDataFactoryException factoryException = worker.getException();
                if (factoryException != null) {
                    ExceptionDialog.showExceptionDialog(KettleDataSourceDialog.this,
                            Messages.getString("KettleDataSourceDialog.PreviewError.Title"),
                            Messages.getString("KettleDataSourceDialog.PreviewError.Message"), factoryException);
                }
            } catch (final Exception ex) {
                ExceptionDialog.showExceptionDialog(KettleDataSourceDialog.this,
                        Messages.getString("KettleDataSourceDialog.PreviewError.Title"),
                        Messages.getString("KettleDataSourceDialog.PreviewError.Message"), ex);
            }
        }

        /**
         * Called whenever the value of the selection changes.
         *
         * @param e the event that characterizes the change.
         */
        public void valueChanged(final ListSelectionEvent e) {
            setEnabled(stepsList.getSelectedValue() != null);
        }
    }

    private static class KettlePreviewWorker implements PreviewWorker {
        private KettleDataFactory dataFactory;
        private TableModel resultTableModel;
        private ReportDataFactoryException exception;
        private String query;

        private KettlePreviewWorker(final KettleDataFactory dataFactory, final String query) {
            if (dataFactory == null) {
                throw new NullPointerException();
            }
            this.query = query;
            this.dataFactory = dataFactory;
        }

        public ReportDataFactoryException getException() {
            return exception;
        }

        public TableModel getResultTableModel() {
            return resultTableModel;
        }

        public void close() {
        }

        /**
         * Requests that the thread stop processing as soon as possible.
         */
        public void cancelProcessing(final CancelEvent event) {
            dataFactory.cancelRunningQuery();
        }

        /**
         * When an object implementing interface <code>Runnable</code> is used to create a thread, starting the thread
         * causes the object's <code>run</code> method to be called in that separately executing thread.
         * <p/>
         * The general contract of the method <code>run</code> is that it may take any action whatsoever.
         *
         * @see Thread#run()
         */
        public void run() {
            try {
                resultTableModel = dataFactory.queryData(query, new ReportParameterValues());
            } catch (final ReportDataFactoryException e) {
                exception = e;
            } finally {
                dataFactory.close();
            }
        }
    }

    private class EditParameterAction extends AbstractAction {
        /**
         * Defines an <code>Action</code> object with a default description string and default icon.
         */
        private EditParameterAction() {
            putValue(Action.NAME, Messages.getString("KettleDataSourceDialog.EditParameter.Name"));
        }

        /**
         * Invoked when an action occurs.
         */
        public void actionPerformed(final ActionEvent e) {
            final KettleQueryEntry queryEntry = (KettleQueryEntry) queryNameList.getSelectedValue();
            if (queryEntry == null) {
                return;
            }

            try {
                final FormulaParameterDialog dialog = new FormulaParameterDialog(KettleDataSourceDialog.this,
                        designTimeContext);
                FieldDefinition[] fields = createFieldDefinitions();
                FormulaParameter[] parameters = queryEntry.getParameters();
                FormulaArgument[] arguments = queryEntry.getArguments();
                KettleParameterInfo[] declaredParameters = queryEntry
                        .getDeclaredParameters(getDesignTimeContext().getDataFactoryContext());
                final FormulaParameterDialog.EditResult editResult = dialog.performEdit(arguments, parameters,
                        fields, declaredParameters);
                if (editResult == null) {
                    return;
                }

                queryEntry.setArguments(editResult.getArgumentNames());
                queryEntry.setParameters(editResult.getParameterMappings());
            } catch (final Exception e1) {
                designTimeContext.error(e1);
            } catch (final Throwable t1) {
                designTimeContext.error(new RuntimeException("Fatal error", t1));
            }
        }

        private FieldDefinition[] createFieldDefinitions() {
            DataSchemaModel dataSchemaModel = designTimeContext.getDataSchemaModel();
            String[] reportFields = dataSchemaModel.getColumnNames();
            FieldDefinition[] fields = new FieldDefinition[reportFields.length];
            for (int i = 0; i < reportFields.length; i++) {
                String reportField = reportFields[i];
                fields[i] = new DefaultFieldDefinition(reportField);
            }
            return fields;
        }
    }

    private class StopOnErrorSync implements ActionListener {
        public void actionPerformed(final ActionEvent e) {
            KettleQueryEntry selectedQuery = getSelectedQuery();
            if (selectedQuery != null) {
                selectedQuery.setStopOnErrors(stopOnErrorsCheckBox.isSelected());
            }
        }
    }

    private static final Log logger = LogFactory.getLog(KettleDataSourceDialog.class);

    private DesignTimeContext designTimeContext;
    private JTextField fileTextField;
    private JTextField nameTextField;
    private JList stepsList;
    private JList queryNameList;
    private DefaultListModel queryListModel;
    private boolean inUpdateFromList;
    private Action editParameterAction;
    private PreviewAction previewAction;
    private JCheckBox stopOnErrorsCheckBox;

    public KettleDataSourceDialog(final DesignTimeContext designTimeContext, final JDialog parent) {
        super(parent);
        initDialog(designTimeContext);
    }

    public KettleDataSourceDialog(final DesignTimeContext designTimeContext, final JFrame parent) {
        super(parent);
        initDialog(designTimeContext);

    }

    public KettleDataSourceDialog(final DesignTimeContext designTimeContext) {
        initDialog(designTimeContext);
    }

    private void initDialog(final DesignTimeContext designTimeContext) {
        if (designTimeContext == null) {
            throw new NullPointerException();
        }

        this.designTimeContext = designTimeContext;

        stopOnErrorsCheckBox = new JCheckBox(Messages.getString("KettleDataSourceDialog.StopOnErrors"));
        stopOnErrorsCheckBox.setEnabled(false);
        stopOnErrorsCheckBox.addActionListener(new StopOnErrorSync());

        editParameterAction = new EditParameterAction();
        editParameterAction.setEnabled(false);

        queryListModel = new DefaultListModel();

        queryNameList = new JList(queryListModel);
        queryNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        queryNameList.setVisibleRowCount(5);
        queryNameList.addListSelectionListener(getQueryNameListener());

        previewAction = new PreviewAction();

        fileTextField = new JTextField(30);
        fileTextField.setEnabled(false);
        fileTextField.getDocument().addDocumentListener(new FileSyncHandler());

        stepsList = new JList();
        stepsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        stepsList.addListSelectionListener(new StepsListListener());
        stepsList.addListSelectionListener(previewAction);

        nameTextField = new JTextField(30);
        nameTextField.setEnabled(false);
        nameTextField.getDocument().addDocumentListener(new NameSyncHandler());

        setTitle(getDialogTitle());
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        setModal(true);

        super.init();
    }

    protected JCheckBox getStopOnErrorsCheckBox() {
        return stopOnErrorsCheckBox;
    }

    protected Action getPreviewAction() {
        return previewAction;
    }

    protected Action getEditParameterAction() {
        return editParameterAction;
    }

    protected DesignTimeContext getDesignTimeContext() {
        return designTimeContext;
    }

    protected KettleQueryEntry getSelectedQuery() {
        return (KettleQueryEntry) queryNameList.getSelectedValue();
    }

    protected void updateQueryName(final String name) {
        nameTextField.setText(name);
    }

    protected String getDialogTitle() {
        return Messages.getString("KettleDataSourceDialog.Title");
    }

    protected String getDialogId() {
        return "KettleDataSourceDialog";
    }

    protected Component createContentPane() {
        final JPanel previewAndParameterPanel = createTransformParameterPanel();
        final JPanel queryListPanel = createQueryListPanel();

        final JPanel mainPanel = new JPanel(new GridBagLayout());
        mainPanel.setBorder(new EmptyBorder(5, 5, 0, 5));
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.WEST;
        mainPanel.add(new JLabel(Messages.getString("KettleDataSourceDialog.QueryName")), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.weightx = 1;
        mainPanel.add(nameTextField, gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.gridwidth = 3;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.anchor = GridBagConstraints.WEST;
        mainPanel.add(createDatasourcePanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.gridwidth = 3;
        gbc.anchor = GridBagConstraints.WEST;
        mainPanel.add(previewAndParameterPanel, gbc);

        final JSplitPane panel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        panel.setLeftComponent(queryListPanel);
        panel.setRightComponent(mainPanel);
        panel.setDividerLocation(250);
        return panel;
    }

    private JPanel createQueryListPanel() {
        final RemoveQueryAction removeQueryAction = new RemoveQueryAction();
        queryNameList.addListSelectionListener(removeQueryAction);

        final JPanel queryListButtonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        queryListButtonsPanel.add(new BorderlessButton(new AddQueryAction()));
        queryListButtonsPanel.add(new BorderlessButton(removeQueryAction));

        final JPanel queryListPanel = new JPanel(new BorderLayout());
        queryListPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 0));
        queryListPanel.add(new JScrollPane(queryNameList), BorderLayout.CENTER);
        queryListPanel.add(queryListButtonsPanel, BorderLayout.NORTH);
        return queryListPanel;
    }

    private JPanel createTransformParameterPanel() {
        final JPanel stopOnErrorsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5));
        stopOnErrorsPanel.add(stopOnErrorsCheckBox);

        final JPanel previewAndParameterPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5));
        previewAndParameterPanel.add(new JButton(editParameterAction));
        previewAndParameterPanel.add(new JButton(previewAction));

        final JPanel transParameterPanel = new JPanel(new BorderLayout());
        transParameterPanel.add(stopOnErrorsPanel, BorderLayout.NORTH);
        transParameterPanel.add(previewAndParameterPanel, BorderLayout.CENTER);
        return transParameterPanel;
    }

    protected JPanel createDatasourcePanel() {
        JPanel panel = new JPanel(new GridBagLayout());

        final BrowseAction browseAction = new BrowseAction();
        queryNameList.addListSelectionListener(browseAction);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 0, 0, 13);
        panel.add(new JLabel(Messages.getString("KettleDataSourceDialog.FileName")), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1;
        panel.add(fileTextField, gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 2;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.WEST;
        panel.add(new JButton(browseAction), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 0, 5, 0);
        panel.add(new JLabel(Messages.getString("KettleDataSourceDialog.Steps")), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.gridwidth = 3;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.anchor = GridBagConstraints.WEST;
        panel.add(new JScrollPane(stepsList), gbc);

        return panel;

    }

    public KettleDataFactory performConfiguration(final DesignTimeContext context,
            final KettleDataFactory dataFactory, final String queryName) throws KettleException {
        configureFromDataFactory(dataFactory, queryName);
        if (performEdit() == false) {
            return null;
        }

        final KettleDataFactory kettleDataFactory = new KettleDataFactory();
        for (final KettleQueryEntry queryEntry : getQueryEntries()) {
            final KettleTransformationProducer producer = queryEntry.createProducer();

            kettleDataFactory.setQuery(queryEntry.getName(), producer);
        }

        return kettleDataFactory;
    }

    protected KettleQueryEntry[] getQueryEntries() {
        final KettleQueryEntry[] data = new KettleQueryEntry[queryListModel.size()];
        queryListModel.copyInto(data);
        return data;
    }

    protected void configureFromDataFactory(final KettleDataFactory dataFactory, final String selectedQueryName)
            throws KettleException {
        queryListModel.clear();
        if (dataFactory == null) {
            return;
        }

        KettleQueryEntry selectedDataSet = null;

        final String[] queryNames = dataFactory.getQueryNames();
        for (int i = 0; i < queryNames.length; i++) {
            final String queryName = queryNames[i];
            final KettleTransformationProducer producer = dataFactory.getQuery(queryName);

            final KettleQueryEntry dataSet = createQueryEntry(queryName, producer);
            queryListModel.addElement(dataSet);
            if (ObjectUtilities.equal(selectedQueryName, queryName)) {
                selectedDataSet = dataSet;
            }
        }

        queryNameList.setSelectedValue(selectedDataSet, true);
    }

    protected boolean validateInputs(final boolean onConfirm) {
        getConfirmAction().setEnabled(queryNameList.getModel().getSize() > 0);
        if (queryNameList.getModel().getSize() == 0) {
            return false;
        }

        return true;
    }

    protected KettleQueryEntry createNewQueryEntry(final String queryName) throws KettleException {
        return new FileKettleQueryEntry(queryName);
    }

    protected KettleQueryEntry createQueryEntry(final String queryName, final KettleTransformationProducer producer)
            throws KettleException {
        return new FileKettleQueryEntry(queryName, producer);
    }

    protected ListSelectionListener getQueryNameListener() {
        return new QueryNameListSelectionListener();
    }

    protected void clearComponents() {
        nameTextField.setText("");
        fileTextField.setText("");
        stepsList.setListData(new StepMeta[0]);
    }

    protected String findNextName() {
        final HashSet<String> names = new HashSet<String>();
        for (int i = 0; i < queryListModel.getSize(); i++) {
            final KettleQueryEntry o = (KettleQueryEntry) queryListModel.getElementAt(i);
            names.add(o.getName());
        }

        String queryName = Messages.getString("KettleDataSourceDialog.Query");
        for (int i = 1; i < 1000; ++i) {
            final String newQuery = Messages.getString("KettleDataSourceDialog.Query") + " " + i;
            if (names.contains(newQuery) == false) {
                queryName = newQuery;
                break;
            }
        }
        return queryName;
    }

}