Java tutorial
/*! ****************************************************************************** * * 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; } }