org.pentaho.di.ui.repository.dialog.SelectObjectDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.di.ui.repository.dialog.SelectObjectDialog.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.repository.dialog;

import org.apache.commons.lang.BooleanUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.graphics.Color;
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.Dialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.repository.ObjectId;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.repository.RepositoryDirectory;
import org.pentaho.di.repository.RepositoryDirectoryInterface;
import org.pentaho.di.repository.RepositoryElementMetaInterface;
import org.pentaho.di.repository.RepositoryExtended;
import org.pentaho.di.repository.RepositoryObjectType;
import org.pentaho.di.ui.core.ConstUI;
import org.pentaho.di.ui.core.PropsUI;
import org.pentaho.di.ui.core.dialog.ErrorDialog;
import org.pentaho.di.ui.core.gui.GUIResource;
import org.pentaho.di.ui.core.gui.WindowProperty;
import org.pentaho.di.ui.repository.RepositoryDirectoryUI;
import org.pentaho.di.ui.trans.step.BaseStepDialog;

import java.util.regex.Pattern;

/**
 * Allows the user to make a selection of an Object in the repository
 *
 * @author Matt
 * @since 19-06-2003
 */
public class SelectObjectDialog extends Dialog {
    private static Class<?> PKG = RepositoryDialogInterface.class; // for
    // i18n
    // purposes,
    // needed
    // by
    // Translator2!!

    private Label wlTree;
    private Tree wTree;
    private FormData fdlTree, fdTree, fdexpandAll;

    private Button wOK, wCancel;
    private Listener lsOK, lsCancel;

    private Shell shell;
    private SelectionAdapter lsDef;

    private String shellText;
    private String lineText;
    private PropsUI props;

    private Color dircolor;
    private Repository rep;

    private String objectName;
    private RepositoryDirectoryInterface objectDirectory;
    private TreeColumn nameColumn;
    private TreeColumn userColumn;
    private TreeColumn changedColumn;
    private int sortColumn;
    private boolean ascending;
    private TreeColumn typeColumn;
    private RepositoryObjectType objectType;
    private boolean showTrans;
    private boolean showJobs;
    private TreeColumn descriptionColumn;

    private ToolItem expandAll, collapseAll, goSearch, wfilter;

    private String filterString = null;
    private Text searchText = null;
    private Pattern pattern = null;

    private RepositoryDirectoryInterface directoryTree;

    // private RepositoryCapabilities capabilities;

    private boolean includeDeleted;

    private ToolItem wbRegex;

    private RepositoryElementMetaInterface repositoryObject;

    private ObjectId objectId;

    public SelectObjectDialog(Shell parent, Repository rep) {
        this(parent, rep, true, true);
    }

    public SelectObjectDialog(Shell parent, Repository rep, boolean showTransformations, boolean showJobs) {
        super(parent, SWT.NONE);

        this.props = PropsUI.getInstance();
        this.rep = rep;
        this.showTrans = showTransformations;
        this.showJobs = showJobs;

        // TODO: make this a configuration option in the dialog!
        //
        this.includeDeleted = false;

        shellText = BaseMessages.getString(PKG, "SelectObjectDialog.Dialog.Main.Title");
        lineText = BaseMessages.getString(PKG, "SelectObjectDialog.Dialog.Object.Title");
        objectName = null;
        objectDirectory = null;

        sortColumn = 0;
        ascending = false;

    }

    @SuppressWarnings("deprecation")
    public String open() {
        Shell parent = getParent();
        dircolor = GUIResource.getInstance().getColorDirectory();

        shell = new Shell(parent,
                SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.SHEET | SWT.RESIZE | SWT.MIN | SWT.MAX);
        props.setLook(shell);
        shell.setImage(GUIResource.getInstance().getImageSpoon());

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

        shell.setLayout(formLayout);
        shell.setText(shellText);

        int margin = Const.MARGIN;

        ToolBar treeTb = new ToolBar(shell, SWT.HORIZONTAL | SWT.FLAT);
        props.setLook(treeTb);

        wfilter = new ToolItem(treeTb, SWT.SEPARATOR);
        searchText = new Text(treeTb, SWT.SEARCH | SWT.CANCEL);
        searchText.setToolTipText(
                BaseMessages.getString(PKG, "RepositoryExplorerDialog.Search.FilterString.ToolTip"));
        wfilter.setControl(searchText);
        wfilter.setWidth(100);

        wbRegex = new ToolItem(treeTb, SWT.CHECK);
        wbRegex.setImage(GUIResource.getInstance().getImageRegexSmall());
        wbRegex.setToolTipText(BaseMessages.getString(PKG, "RepositoryExplorerDialog.Search.UseRegex"));

        goSearch = new ToolItem(treeTb, SWT.PUSH);
        goSearch.setImage(GUIResource.getInstance().getImageSearchSmall());
        goSearch.setToolTipText(BaseMessages.getString(PKG, "RepositoryExplorerDialog.Search.Run"));

        expandAll = new ToolItem(treeTb, SWT.PUSH);
        expandAll.setImage(GUIResource.getInstance().getImageExpandAll());
        collapseAll = new ToolItem(treeTb, SWT.PUSH);
        collapseAll.setImage(GUIResource.getInstance().getImageCollapseAll());
        fdexpandAll = new FormData();
        fdexpandAll.right = new FormAttachment(100, -margin);
        fdexpandAll.top = new FormAttachment(0, margin);
        treeTb.setLayoutData(fdexpandAll);

        // From step line
        wlTree = new Label(shell, SWT.NONE);
        wlTree.setText(lineText);
        props.setLook(wlTree);
        fdlTree = new FormData();
        fdlTree.left = new FormAttachment(0, 0);
        fdlTree.top = new FormAttachment(0, margin);
        wlTree.setLayoutData(fdlTree);

        wTree = new Tree(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
        wTree.setHeaderVisible(true);
        props.setLook(wTree);

        // Add some columns to it as well...
        nameColumn = new TreeColumn(wTree, SWT.LEFT);
        nameColumn.setText(BaseMessages.getString(PKG, "RepositoryExplorerDialog.Column.Name"));
        nameColumn.setWidth(350);
        nameColumn.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                setSort(0);
            }
        });

        // No sorting on the type column just yet.
        typeColumn = new TreeColumn(wTree, SWT.LEFT);
        typeColumn.setText(BaseMessages.getString(PKG, "RepositoryExplorerDialog.Column.Type"));
        typeColumn.setWidth(100);
        typeColumn.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                setSort(1);
            }
        });

        userColumn = new TreeColumn(wTree, SWT.LEFT);
        userColumn.setText(BaseMessages.getString(PKG, "RepositoryExplorerDialog.Column.User"));
        userColumn.setWidth(100);
        userColumn.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                setSort(2);
            }
        });

        changedColumn = new TreeColumn(wTree, SWT.LEFT);
        changedColumn.setText(BaseMessages.getString(PKG, "RepositoryExplorerDialog.Column.Changed"));
        changedColumn.setWidth(120);
        changedColumn.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                setSort(3);
            }
        });

        descriptionColumn = new TreeColumn(wTree, SWT.LEFT);
        descriptionColumn.setText(BaseMessages.getString(PKG, "RepositoryExplorerDialog.Column.Description"));
        descriptionColumn.setWidth(120);
        descriptionColumn.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                setSort(4);
            }
        });

        props.setLook(wTree);
        fdTree = new FormData();
        fdTree.left = new FormAttachment(0, 0);
        fdTree.right = new FormAttachment(100, 0);
        fdTree.top = new FormAttachment(treeTb, margin);
        fdTree.bottom = new FormAttachment(100, -30);
        wTree.setLayoutData(fdTree);

        // Some buttons
        wOK = new Button(shell, SWT.PUSH);
        wOK.setText(BaseMessages.getString(PKG, "System.Button.OK"));
        lsOK = new Listener() {
            public void handleEvent(Event e) {
                ok();
            }
        };
        wOK.addListener(SWT.Selection, lsOK);
        wOK.setEnabled(false);

        wCancel = new Button(shell, SWT.PUSH);
        wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel"));
        lsCancel = new Listener() {
            public void handleEvent(Event e) {
                cancel();
            }
        };
        wCancel.addListener(SWT.Selection, lsCancel);

        BaseStepDialog.positionBottomButtons(shell, new Button[] { wOK, wCancel }, margin, null);
        // Add listeners

        lsDef = new SelectionAdapter() {
            public void widgetDefaultSelected(SelectionEvent e) {
                ok();
            }
        };
        wTree.addSelectionListener(lsDef);
        wTree.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if (e.character == SWT.CR) {
                    ok();
                }
            }
        });

        wTree.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                if (wTree.getSelection().length > 0) {
                    wOK.setEnabled(!Boolean.TRUE.equals(wTree.getSelection()[0].getData("isFolder")));
                }
            }
        });

        expandAll.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                expandAllItems(wTree.getItems(), true);
            }
        });

        collapseAll.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                expandAllItems(wTree.getItems(), false);
            }
        });
        goSearch.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                updateFilter();
            }
        });

        searchText.addSelectionListener(new SelectionAdapter() {
            public void widgetDefaultSelected(SelectionEvent e) {
                updateFilter();
            }
        });
        // Detect [X] or ALT-F4 or something that kills this window...
        shell.addShellListener(new ShellAdapter() {
            public void shellClosed(ShellEvent e) {
                cancel();
            }
        });

        try {

            if (rep instanceof RepositoryExtended) {
                RepositoryExtended repositoryExtended = (RepositoryExtended) this.rep;
                directoryTree = repositoryExtended.loadRepositoryDirectoryTree("/", "*.kjb|*.ktr", -1,
                        BooleanUtils.isTrue(repositoryExtended.getUserInfo().isAdmin()), true, false);
            } else {
                directoryTree = this.rep.loadRepositoryDirectoryTree();
            }

        } catch (KettleException e) {
            new ErrorDialog(shell,
                    BaseMessages.getString(PKG, "SelectObjectDialog.Dialog.ErrorRefreshingDirectoryTree.Title"),
                    BaseMessages.getString(PKG, "SelectObjectDialog.Dialog.ErrorRefreshingDirectoryTree.Message"),
                    e);
        } // catch()

        getData();
        wTree.setFocus();
        BaseStepDialog.setSize(shell);

        shell.open();
        while (!shell.isDisposed()) {
            if (!shell.getDisplay().readAndDispatch()) {
                shell.getDisplay().sleep();
            }
        }
        return objectName;
    }

    private void expandAllItems(TreeItem[] treeitems, boolean expand) {
        for (TreeItem item : treeitems) {
            item.setExpanded(expand);
            if (item.getItemCount() > 0) {
                expandAllItems(item.getItems(), expand);
            }
        }
    }

    protected void updateFilter() {
        pattern = null;
        filterString = null;
        if (searchText != null && !searchText.isDisposed() && !Utils.isEmpty(searchText.getText())) {
            if (wbRegex.getSelection()) {
                pattern = Pattern.compile(searchText.getText());
            } else {
                filterString = searchText.getText().toUpperCase();
            }
        }
        refreshTree();
        if ((wbRegex.getSelection() && pattern != null) || (!wbRegex.getSelection() && filterString != null)) {
            while (getNrEmptyFolders(wTree.getItems()) > 0) {
                removeEmptyFolders(wTree.getItems());
                try {
                    Thread.sleep(0, 1);
                } catch (InterruptedException e) {
                    // Ignore errors
                }
            }
            expandAllItems(wTree.getItems(), true);
        }
    }

    private void removeEmptyFolders(TreeItem[] treeitems) {
        for (TreeItem item : treeitems) {
            if (item.getImage().equals(GUIResource.getInstance().getImageArrow()) && item.getItemCount() == 0) {
                item.dispose();
            } else {
                removeEmptyFolders(item.getItems());
            }
        }
    }

    private int getNrEmptyFolders(TreeItem[] treeitems) {
        int retval = 0;
        for (TreeItem item : treeitems) {
            if (item.getImage().equals(GUIResource.getInstance().getImageArrow()) && item.getItemCount() == 0) {
                retval++;
            } else {
                retval += getNrEmptyFolders(item.getItems());
            }
        }
        return retval;
    }

    protected void setSort(int i) {
        if (sortColumn == i) {
            ascending = !ascending;
        } else {
            sortColumn = i;
            ascending = true;
        }

        if (sortColumn >= 0 && sortColumn < 5) {
            TreeColumn column = wTree.getColumn(sortColumn);
            wTree.setSortColumn(column);
            wTree.setSortDirection(ascending ? SWT.UP : SWT.DOWN);
        }
        refreshTree();
    }

    private void refreshTree() {
        try {
            wTree.removeAll();
            TreeItem ti = null;
            // If the directory is a root directory and is visible to the user we will
            // display that on the UI otherwise we will hide it
            if (directoryTree.isRoot() && directoryTree.isVisible()) {
                ti = new TreeItem(wTree, SWT.NONE);
                ti.setImage(GUIResource.getInstance().getImageFolder());
                ti.setExpanded(true);
                RepositoryDirectoryUI.getTreeWithNames(ti, rep, dircolor, sortColumn, includeDeleted, ascending,
                        showTrans, showJobs, directoryTree, filterString, pattern);
            } else {
                for (int i = 0; i < directoryTree.getNrSubdirectories(); i++) {
                    RepositoryDirectory subdir = directoryTree.getSubdirectory(i);
                    ti = new TreeItem(wTree, SWT.NONE);
                    ti.setImage(GUIResource.getInstance().getImageFolder());
                    RepositoryDirectoryUI.getTreeWithNames(ti, rep, dircolor, sortColumn, includeDeleted, ascending,
                            showTrans, showJobs, subdir, filterString, pattern);
                }
            }
        } catch (KettleException e) {
            new ErrorDialog(shell, BaseMessages.getString(PKG, "SelectObjectDialog.Dialog.UnexpectedError.Title"),
                    BaseMessages.getString(PKG, "SelectObjectDialog.Dialog.UnexpectedError.Message"), e);
        }
    }

    public void dispose() {
        props.setScreen(new WindowProperty(shell));
        shell.dispose();
    }

    public void getData() {
        setSort(0);
    }

    private void cancel() {
        objectName = null;
        dispose();
    }

    private void ok() {
        // Something has to be selected!
        if (wTree.getSelectionCount() > 0) {
            TreeItem ti = wTree.getSelection()[0];

            // No directory!
            if (!Boolean.TRUE.equals(wTree.getSelection()[0].getData("isFolder"))) {
                int level = ConstUI.getTreeLevel(ti);
                if (level > 0) {
                    repositoryObject = (RepositoryElementMetaInterface) ti.getData();
                    if (repositoryObject != null) {
                        objectName = repositoryObject.getName();
                        objectDirectory = repositoryObject.getRepositoryDirectory();
                        objectId = repositoryObject.getObjectId();
                        objectType = repositoryObject.getObjectType();
                    } else {
                        // For backward compatibility, we should rarely end up here...
                        //
                        String[] path = ConstUI.getTreeStrings(ti.getParentItem());
                        objectName = ti.getText(0);
                        objectType = null;
                        for (RepositoryObjectType type : RepositoryObjectType.values()) {
                            if (type.getTypeDescription().equalsIgnoreCase(ti.getText(1))) {
                                objectType = type;
                                break;
                            }
                        }
                        objectDirectory = directoryTree.findDirectory(path);
                    }

                    if (objectDirectory != null) {
                        dispose();
                    } else {
                        MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
                        mb.setMessage(
                                BaseMessages.getString(PKG, "SelectObjectDialog.Dialog.DirectoryNotFound.Message"));
                        mb.setText(
                                BaseMessages.getString(PKG, "SelectObjectDialog.Dialog.DirectoryNotFound.Title"));
                        mb.open();
                    }
                }
            }
        }
    }

    public RepositoryDirectoryInterface getDirectory() {
        return objectDirectory;
    }

    /**
     * @return the objectType
     */
    public RepositoryObjectType getObjectType() {
        return objectType;
    }

    /**
     * @return the objectName
     */
    public String getObjectName() {
        return objectName;
    }

    /**
     * @return the repositoryObject
     */
    public RepositoryElementMetaInterface getRepositoryObject() {
        return repositoryObject;
    }

    /**
     * @param repositoryObject the repositoryObject to set
     */
    public void setRepositoryObject(RepositoryElementMetaInterface repositoryObject) {
        this.repositoryObject = repositoryObject;
    }

    /**
     * @return the objectId
     */
    public ObjectId getObjectId() {
        return objectId;
    }

    /**
     * @param objectId the objectId to set
     */
    public void setObjectId(ObjectId objectId) {
        this.objectId = objectId;
    }
}