org.pentaho.di.ui.trans.steps.mergejoin.MergeJoinDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.di.ui.trans.steps.mergejoin.MergeJoinDialog.java

Source

/*! ******************************************************************************
 *
 * Pentaho Data Integration
 *
 * Copyright (C) 2002-2017 by Hitachi Vantara : http://www.pentaho.com
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

package org.pentaho.di.ui.trans.steps.mergejoin;

import java.util.List;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDialogInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.errorhandling.StreamInterface;
import org.pentaho.di.trans.steps.mergejoin.MergeJoinMeta;
import org.pentaho.di.ui.core.dialog.ErrorDialog;
import org.pentaho.di.ui.core.gui.GUIResource;
import org.pentaho.di.ui.core.widget.ColumnInfo;
import org.pentaho.di.ui.core.widget.TableView;
import org.pentaho.di.ui.trans.step.BaseStepDialog;

public class MergeJoinDialog extends BaseStepDialog implements StepDialogInterface {
    private static Class<?> PKG = MergeJoinMeta.class; // for i18n purposes, needed by Translator2!!

    public static final String STRING_SORT_WARNING_PARAMETER = "MergeJoinSortWarning";

    private Label wlStep1;
    private CCombo wStep1;
    private FormData fdlStep1, fdStep1;

    private Label wlStep2;
    private CCombo wStep2;
    private FormData fdlStep2, fdStep2;

    private Label wlType;
    private CCombo wType;
    private FormData fdlType, fdType;

    private Label wlKeys1;
    private TableView wKeys1;
    private Button wbKeys1;
    private FormData fdlKeys1, fdKeys1, fdbKeys1;

    private Label wlKeys2;
    private TableView wKeys2;
    private Button wbKeys2;
    private FormData fdlKeys2, fdKeys2, fdbKeys2;

    private MergeJoinMeta input;

    public MergeJoinDialog(Shell parent, Object in, TransMeta tr, String sname) {
        super(parent, (BaseStepMeta) in, tr, sname);
        input = (MergeJoinMeta) in;
    }

    public String open() {
        Shell parent = getParent();
        Display display = parent.getDisplay();

        shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX);
        props.setLook(shell);
        setShellImage(shell, input);

        ModifyListener lsMod = new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                input.setChanged();
            }
        };
        backupChanged = input.hasChanged();

        FormLayout formLayout = new FormLayout();
        formLayout.marginWidth = Const.FORM_MARGIN;
        formLayout.marginHeight = Const.FORM_MARGIN;

        shell.setLayout(formLayout);
        shell.setText(BaseMessages.getString(PKG, "MergeJoinDialog.Shell.Label"));

        int middle = props.getMiddlePct();
        int margin = Const.MARGIN;

        // Stepname line
        wlStepname = new Label(shell, SWT.RIGHT);
        wlStepname.setText(BaseMessages.getString(PKG, "MergeJoinDialog.Stepname.Label"));
        props.setLook(wlStepname);
        fdlStepname = new FormData();
        fdlStepname.left = new FormAttachment(0, 0);
        fdlStepname.right = new FormAttachment(middle, -margin);
        fdlStepname.top = new FormAttachment(0, margin);
        wlStepname.setLayoutData(fdlStepname);
        wStepname = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
        wStepname.setText(stepname);
        props.setLook(wStepname);
        wStepname.addModifyListener(lsMod);
        fdStepname = new FormData();
        fdStepname.left = new FormAttachment(middle, 0);
        fdStepname.top = new FormAttachment(0, margin);
        fdStepname.right = new FormAttachment(100, 0);
        wStepname.setLayoutData(fdStepname);

        // Get the previous steps...
        String[] previousSteps = transMeta.getPrevStepNames(stepname);

        // First step
        wlStep1 = new Label(shell, SWT.RIGHT);
        wlStep1.setText(BaseMessages.getString(PKG, "MergeJoinDialog.Step1.Label"));
        props.setLook(wlStep1);
        fdlStep1 = new FormData();
        fdlStep1.left = new FormAttachment(0, 0);
        fdlStep1.right = new FormAttachment(middle, -margin);
        fdlStep1.top = new FormAttachment(wStepname, margin);
        wlStep1.setLayoutData(fdlStep1);
        wStep1 = new CCombo(shell, SWT.BORDER);
        props.setLook(wStep1);

        if (previousSteps != null) {
            wStep1.setItems(previousSteps);
        }

        wStep1.addModifyListener(lsMod);
        fdStep1 = new FormData();
        fdStep1.left = new FormAttachment(middle, 0);
        fdStep1.top = new FormAttachment(wStepname, margin);
        fdStep1.right = new FormAttachment(100, 0);
        wStep1.setLayoutData(fdStep1);

        // Second step
        wlStep2 = new Label(shell, SWT.RIGHT);
        wlStep2.setText(BaseMessages.getString(PKG, "MergeJoinDialog.Step2.Label"));
        props.setLook(wlStep2);
        fdlStep2 = new FormData();
        fdlStep2.left = new FormAttachment(0, 0);
        fdlStep2.right = new FormAttachment(middle, -margin);
        fdlStep2.top = new FormAttachment(wStep1, margin);
        wlStep2.setLayoutData(fdlStep2);
        wStep2 = new CCombo(shell, SWT.BORDER);
        props.setLook(wStep2);

        if (previousSteps != null) {
            wStep2.setItems(previousSteps);
        }

        wStep2.addModifyListener(lsMod);
        fdStep2 = new FormData();
        fdStep2.top = new FormAttachment(wStep1, margin);
        fdStep2.left = new FormAttachment(middle, 0);
        fdStep2.right = new FormAttachment(100, 0);
        wStep2.setLayoutData(fdStep2);

        // Join type
        wlType = new Label(shell, SWT.RIGHT);
        wlType.setText(BaseMessages.getString(PKG, "MergeJoinDialog.Type.Label"));
        props.setLook(wlType);
        fdlType = new FormData();
        fdlType.left = new FormAttachment(0, 0);
        fdlType.right = new FormAttachment(middle, -margin);
        fdlType.top = new FormAttachment(wStep2, margin);
        wlType.setLayoutData(fdlType);
        wType = new CCombo(shell, SWT.BORDER);
        props.setLook(wType);

        wType.setItems(MergeJoinMeta.join_types);

        wType.addModifyListener(lsMod);
        fdType = new FormData();
        fdType.top = new FormAttachment(wStep2, margin);
        fdType.left = new FormAttachment(middle, 0);
        fdType.right = new FormAttachment(100, 0);
        wType.setLayoutData(fdType);

        // THE KEYS TO MATCH for first step...
        wlKeys1 = new Label(shell, SWT.NONE);
        wlKeys1.setText(BaseMessages.getString(PKG, "MergeJoinDialog.Keys1.Label"));
        props.setLook(wlKeys1);
        fdlKeys1 = new FormData();
        fdlKeys1.left = new FormAttachment(0, 0);
        fdlKeys1.top = new FormAttachment(wType, margin);
        wlKeys1.setLayoutData(fdlKeys1);

        int nrKeyRows1 = (input.getKeyFields1() != null ? input.getKeyFields1().length : 1);

        ColumnInfo[] ciKeys1 = new ColumnInfo[] {
                new ColumnInfo(BaseMessages.getString(PKG, "MergeJoinDialog.ColumnInfo.KeyField1"),
                        ColumnInfo.COLUMN_TYPE_TEXT, false), };

        wKeys1 = new TableView(transMeta, shell,
                SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL, ciKeys1, nrKeyRows1,
                lsMod, props);

        fdKeys1 = new FormData();
        fdKeys1.top = new FormAttachment(wlKeys1, margin);
        fdKeys1.left = new FormAttachment(0, 0);
        fdKeys1.bottom = new FormAttachment(100, -70);
        fdKeys1.right = new FormAttachment(50, -margin);
        wKeys1.setLayoutData(fdKeys1);

        wbKeys1 = new Button(shell, SWT.PUSH);
        wbKeys1.setText(BaseMessages.getString(PKG, "MergeJoinDialog.KeyFields1.Button"));
        fdbKeys1 = new FormData();
        fdbKeys1.top = new FormAttachment(wKeys1, margin);
        fdbKeys1.left = new FormAttachment(0, 0);
        fdbKeys1.right = new FormAttachment(50, -margin);
        wbKeys1.setLayoutData(fdbKeys1);
        wbKeys1.addSelectionListener(new SelectionAdapter() {

            public void widgetSelected(SelectionEvent e) {
                getKeys1();
            }
        });

        // THE KEYS TO MATCH for second step
        wlKeys2 = new Label(shell, SWT.NONE);
        wlKeys2.setText(BaseMessages.getString(PKG, "MergeJoinDialog.Keys2.Label"));
        props.setLook(wlKeys2);
        fdlKeys2 = new FormData();
        fdlKeys2.left = new FormAttachment(50, 0);
        fdlKeys2.top = new FormAttachment(wType, margin);
        wlKeys2.setLayoutData(fdlKeys2);

        int nrKeyRows2 = (input.getKeyFields2() != null ? input.getKeyFields2().length : 1);

        ColumnInfo[] ciKeys2 = new ColumnInfo[] {
                new ColumnInfo(BaseMessages.getString(PKG, "MergeJoinDialog.ColumnInfo.KeyField2"),
                        ColumnInfo.COLUMN_TYPE_TEXT, false), };

        wKeys2 = new TableView(transMeta, shell,
                SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL, ciKeys2, nrKeyRows2,
                lsMod, props);

        fdKeys2 = new FormData();
        fdKeys2.top = new FormAttachment(wlKeys2, margin);
        fdKeys2.left = new FormAttachment(50, 0);
        fdKeys2.bottom = new FormAttachment(100, -70);
        fdKeys2.right = new FormAttachment(100, 0);
        wKeys2.setLayoutData(fdKeys2);

        wbKeys2 = new Button(shell, SWT.PUSH);
        wbKeys2.setText(BaseMessages.getString(PKG, "MergeJoinDialog.KeyFields2.Button"));
        fdbKeys2 = new FormData();
        fdbKeys2.top = new FormAttachment(wKeys2, margin);
        fdbKeys2.left = new FormAttachment(50, 0);
        fdbKeys2.right = new FormAttachment(100, 0);
        wbKeys2.setLayoutData(fdbKeys2);
        wbKeys2.addSelectionListener(new SelectionAdapter() {

            public void widgetSelected(SelectionEvent e) {
                getKeys2();
            }
        });

        // Some buttons
        wOK = new Button(shell, SWT.PUSH);
        wOK.setText(BaseMessages.getString(PKG, "System.Button.OK"));
        wCancel = new Button(shell, SWT.PUSH);
        wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel"));

        setButtonPositions(new Button[] { wOK, wCancel }, margin, wbKeys1);

        // Add listeners
        lsCancel = new Listener() {
            public void handleEvent(Event e) {
                cancel();
            }
        };
        lsOK = new Listener() {
            public void handleEvent(Event e) {
                ok();
            }
        };

        wCancel.addListener(SWT.Selection, lsCancel);
        wOK.addListener(SWT.Selection, lsOK);

        lsDef = new SelectionAdapter() {
            public void widgetDefaultSelected(SelectionEvent e) {
                ok();
            }
        };

        wStepname.addSelectionListener(lsDef);

        // Detect X or ALT-F4 or something that kills this window...
        shell.addShellListener(new ShellAdapter() {
            public void shellClosed(ShellEvent e) {
                cancel();
            }
        });

        // Set the shell size, based upon previous time...
        setSize();

        getData();
        input.setChanged(backupChanged);

        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        return stepname;
    }

    /**
     * Copy information from the meta-data input to the dialog fields.
     */
    public void getData() {
        List<StreamInterface> infoStreams = input.getStepIOMeta().getInfoStreams();

        wStep1.setText(Const.NVL(infoStreams.get(0).getStepname(), ""));
        wStep2.setText(Const.NVL(infoStreams.get(1).getStepname(), ""));
        String joinType = input.getJoinType();
        if (joinType != null && joinType.length() > 0) {
            wType.setText(joinType);
        } else {
            wType.setText(MergeJoinMeta.join_types[0]);
        }

        for (int i = 0; i < input.getKeyFields1().length; i++) {
            TableItem item = wKeys1.table.getItem(i);
            if (input.getKeyFields1()[i] != null) {
                item.setText(1, input.getKeyFields1()[i]);
            }
        }
        for (int i = 0; i < input.getKeyFields2().length; i++) {
            TableItem item = wKeys2.table.getItem(i);
            if (input.getKeyFields2()[i] != null) {
                item.setText(1, input.getKeyFields2()[i]);
            }
        }

        wStepname.selectAll();
        wStepname.setFocus();
    }

    private void cancel() {
        stepname = null;
        input.setChanged(backupChanged);
        dispose();
    }

    private void getMeta(MergeJoinMeta meta) {
        List<StreamInterface> infoStreams = meta.getStepIOMeta().getInfoStreams();

        infoStreams.get(0).setStepMeta(transMeta.findStep(wStep1.getText()));
        infoStreams.get(1).setStepMeta(transMeta.findStep(wStep2.getText()));
        meta.setJoinType(wType.getText());

        int nrKeys1 = wKeys1.nrNonEmpty();
        int nrKeys2 = wKeys2.nrNonEmpty();

        meta.allocate(nrKeys1, nrKeys2);

        //CHECKSTYLE:Indentation:OFF
        for (int i = 0; i < nrKeys1; i++) {
            TableItem item = wKeys1.getNonEmpty(i);
            meta.getKeyFields1()[i] = item.getText(1);
        }

        //CHECKSTYLE:Indentation:OFF
        for (int i = 0; i < nrKeys2; i++) {
            TableItem item = wKeys2.getNonEmpty(i);
            meta.getKeyFields2()[i] = item.getText(1);
        }
    }

    private void ok() {
        if (Utils.isEmpty(wStepname.getText())) {
            return;
        }

        getMeta(input);

        // Show a warning (optional)
        //
        if ("Y".equalsIgnoreCase(props.getCustomParameter(STRING_SORT_WARNING_PARAMETER, "Y"))) {
            MessageDialogWithToggle md = new MessageDialogWithToggle(shell,
                    BaseMessages.getString(PKG, "MergeJoinDialog.InputNeedSort.DialogTitle"), null,
                    BaseMessages.getString(PKG, "MergeJoinDialog.InputNeedSort.DialogMessage", Const.CR) + Const.CR,
                    MessageDialog.WARNING,
                    new String[] { BaseMessages.getString(PKG, "MergeJoinDialog.InputNeedSort.Option1") }, 0,
                    BaseMessages.getString(PKG, "MergeJoinDialog.InputNeedSort.Option2"),
                    "N".equalsIgnoreCase(props.getCustomParameter(STRING_SORT_WARNING_PARAMETER, "Y")));
            MessageDialogWithToggle.setDefaultImage(GUIResource.getInstance().getImageSpoon());
            md.open();
            props.setCustomParameter(STRING_SORT_WARNING_PARAMETER, md.getToggleState() ? "N" : "Y");
            props.saveProps();
        }

        stepname = wStepname.getText(); // return value

        dispose();
    }

    private void getKeys1() {
        MergeJoinMeta joinMeta = new MergeJoinMeta();
        getMeta(joinMeta);

        try {
            List<StreamInterface> infoStreams = joinMeta.getStepIOMeta().getInfoStreams();

            StepMeta stepMeta = infoStreams.get(0).getStepMeta();
            if (stepMeta != null) {
                RowMetaInterface prev = transMeta.getStepFields(stepMeta);
                if (prev != null) {
                    BaseStepDialog.getFieldsFromPrevious(prev, wKeys1, 1, new int[] { 1 }, new int[] {}, -1, -1,
                            null);
                }
            }
        } catch (KettleException e) {
            new ErrorDialog(shell, BaseMessages.getString(PKG, "MergeJoinDialog.ErrorGettingFields.DialogTitle"),
                    BaseMessages.getString(PKG, "MergeJoinDialog.ErrorGettingFields.DialogMessage"), e);
        }
    }

    private void getKeys2() {
        MergeJoinMeta joinMeta = new MergeJoinMeta();
        getMeta(joinMeta);

        try {
            List<StreamInterface> infoStreams = joinMeta.getStepIOMeta().getInfoStreams();

            StepMeta stepMeta = infoStreams.get(1).getStepMeta();
            if (stepMeta != null) {
                RowMetaInterface prev = transMeta.getStepFields(stepMeta);
                if (prev != null) {
                    BaseStepDialog.getFieldsFromPrevious(prev, wKeys2, 1, new int[] { 1 }, new int[] {}, -1, -1,
                            null);
                }
            }
        } catch (KettleException e) {
            new ErrorDialog(shell, BaseMessages.getString(PKG, "MergeJoinDialog.ErrorGettingFields.DialogTitle"),
                    BaseMessages.getString(PKG, "MergeJoinDialog.ErrorGettingFields.DialogMessage"), e);
        }
    }

}