org.jboss.tools.openshift.internal.ui.wizard.common.EnvironmentVariablePage.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.openshift.internal.ui.wizard.common.EnvironmentVariablePage.java

Source

/*******************************************************************************
 * Copyright (c) 2016 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package org.jboss.tools.openshift.internal.ui.wizard.common;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.jboss.tools.common.ui.databinding.ValueBindingBuilder;
import org.jboss.tools.openshift.internal.common.ui.databinding.IsNotNull2BooleanConverter;
import org.jboss.tools.openshift.internal.common.ui.utils.TableViewerBuilder;
import org.jboss.tools.openshift.internal.common.ui.utils.UIUtils;
import org.jboss.tools.openshift.internal.common.ui.utils.TableViewerBuilder.IColumnLabelProvider;
import org.jboss.tools.openshift.internal.common.ui.wizard.AbstractOpenShiftWizardPage;
import org.jboss.tools.openshift.internal.common.ui.wizard.IKeyValueItem;
import org.jboss.tools.openshift.internal.common.ui.wizard.IKeyValueWizardModel;
import org.jboss.tools.openshift.internal.common.ui.wizard.KeyValueItem;
import org.jboss.tools.openshift.internal.common.ui.wizard.KeyValueWizard;
import org.jboss.tools.openshift.internal.common.ui.wizard.KeyValueWizardModelBuilder;
import org.jboss.tools.openshift.internal.common.ui.wizard.OkCancelButtonWizardDialog;
import org.jboss.tools.openshift.internal.ui.validator.EnvironmentVarKeyValidator;
import org.jboss.tools.openshift.internal.ui.wizard.deployimage.IDeploymentConfigPageModel;

/**
 * Base for adding env variable section to a page
 * @author jeff.cantrill
 *
 */
public abstract class EnvironmentVariablePage extends AbstractOpenShiftWizardPage {

    private static final String ENVIRONMENT_VARIABLE_LABEL = "Environment Variable";
    private static final String ENVIRONMENT_VARIABLE_KEY_LABEL = "Name";
    public static final String TABLE_LABEL = "Environment variables:";
    public static final String TABLE_LABEL_TOOLTIP = "Environment variables are passed to running pods for consumption by the pod containers";
    private IEnvironmentVariablesPageModel model;
    private TableViewer envViewer;

    protected int heightScale = 30;
    protected Composite envTableContainer;

    protected boolean canDeleteAnyVar = false;

    protected EnvironmentVariablePage(String title, String description, String name, IWizard wizard,
            IEnvironmentVariablesPageModel model) {
        super(title, description, name, wizard);
        this.model = model;
    }

    protected void createEnvVariableControl(Composite parent, DataBindingContext dbc) {
        createEnvVariableControl(parent, dbc, TABLE_LABEL, TABLE_LABEL_TOOLTIP);
    }

    @SuppressWarnings("unchecked")
    protected void createEnvVariableControl(Composite parent, DataBindingContext dbc, String label,
            String tooltip) {
        Composite envContainer = new Composite(parent, SWT.NONE);
        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(envContainer);
        GridLayoutFactory.fillDefaults().numColumns(2).margins(2, 2).applyTo(envContainer);

        Label lblEnvVars = new Label(envContainer, SWT.NONE);
        lblEnvVars.setText(label);
        lblEnvVars.setToolTipText(tooltip);
        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(2, 1).applyTo(lblEnvVars);
        Composite tableContainer = envTableContainer = new Composite(envContainer, SWT.NONE);

        this.envViewer = createEnvVarTable(tableContainer);
        GridDataFactory.fillDefaults().span(1, 5).align(SWT.FILL, SWT.FILL).grab(true, true).hint(SWT.DEFAULT, 150)
                .applyTo(tableContainer);
        ValueBindingBuilder
                .bind(ViewerProperties.singleSelection().observe(envViewer)).to(BeanProperties
                        .value(IDeploymentConfigPageModel.PROPERTY_SELECTED_ENVIRONMENT_VARIABLE).observe(model))
                .in(dbc);
        envViewer.setContentProvider(new ObservableListContentProvider());
        envViewer.setInput(
                BeanProperties.list(IDeploymentConfigPageModel.PROPERTY_ENVIRONMENT_VARIABLES).observe(model));

        Button addButton = new Button(envContainer, SWT.PUSH);
        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).applyTo(addButton);
        addButton.setText("Add...");
        addButton.setToolTipText("Add an environment variable declared by the docker image.");
        addButton.addSelectionListener(onAdd());
        UIUtils.setDefaultButtonWidth(addButton);
        heightScale = addButton.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;

        Button editExistingButton = new Button(envContainer, SWT.PUSH);
        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).applyTo(editExistingButton);
        editExistingButton.setText("Edit...");
        editExistingButton.setToolTipText("Edit the environment variable declared by the docker image.");
        editExistingButton.addSelectionListener(new EditHandler());
        ValueBindingBuilder.bind(WidgetProperties.enabled().observe(editExistingButton)).notUpdatingParticipant()
                .to(BeanProperties.value(IDeploymentConfigPageModel.PROPERTY_SELECTED_ENVIRONMENT_VARIABLE)
                        .observe(model))
                .converting(new IsNotNull2BooleanConverter()).in(dbc);
        UIUtils.setDefaultButtonWidth(editExistingButton);

        Button btnReset = new Button(envContainer, SWT.PUSH);
        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).applyTo(btnReset);
        btnReset.setText("Reset");
        btnReset.setToolTipText("Reset to the value declared by the docker image.");
        btnReset.addSelectionListener(onResetEnvVar());
        ValueBindingBuilder
                .bind(WidgetProperties.enabled().observe(btnReset)).notUpdatingParticipant().to(BeanProperties
                        .value(IDeploymentConfigPageModel.PROPERTY_SELECTED_ENVIRONMENT_VARIABLE).observe(model))
                .converting(new IsNotNull2BooleanConverter() {

                    @Override
                    public Object convert(Object fromObject) {
                        Boolean notNull = (Boolean) super.convert(fromObject);
                        return notNull && !((EnvironmentVariable) fromObject).isNew()
                                && model.isEnvironmentVariableModified((EnvironmentVariable) fromObject);
                    }

                }).in(dbc);
        UIUtils.setDefaultButtonWidth(btnReset);

        Button btnResetAll = new Button(envContainer, SWT.PUSH);
        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).applyTo(btnResetAll);
        btnResetAll.setText("Reset All");
        btnResetAll.setToolTipText("Reset all variables to the value declared by the docker image.");
        btnResetAll.addSelectionListener(onResetEnvVars());
        ValueBindingBuilder.bind(WidgetProperties.enabled().observe(btnResetAll)).notUpdatingParticipant()
                //This may look like a hack, but this property do change at each change to variables, so that button refresh will be consistent. 
                .to(BeanProperties.value(IDeploymentConfigPageModel.PROPERTY_SELECTED_ENVIRONMENT_VARIABLE)
                        .observe(model))
                .converting(new IsNotNull2BooleanConverter() {

                    @Override
                    public Object convert(Object fromObject) {
                        List<EnvironmentVariable> vars = model.getEnvironmentVariables();
                        return vars != null && !vars.isEmpty() && vars.stream()
                                .anyMatch(v -> !v.isNew() && model.isEnvironmentVariableModified(v));
                    }

                }).in(dbc);
        UIUtils.setDefaultButtonWidth(btnResetAll);

        Button btnRemove = new Button(envContainer, SWT.PUSH);
        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).applyTo(btnRemove);
        btnRemove.setText("Remove");
        btnRemove.setToolTipText("Remove the environment variable added here.");
        btnRemove.addSelectionListener(onRemoveEnvVar());
        ValueBindingBuilder
                .bind(WidgetProperties.enabled().observe(btnRemove)).notUpdatingParticipant().to(BeanProperties
                        .value(IDeploymentConfigPageModel.PROPERTY_SELECTED_ENVIRONMENT_VARIABLE).observe(model))
                .converting(new IsNotNull2BooleanConverter() {

                    @Override
                    public Object convert(Object fromObject) {
                        Boolean notNull = (Boolean) super.convert(fromObject);
                        return notNull && (canDeleteAnyVar || ((EnvironmentVariable) fromObject).isNew())
                                && !model.isEnvironmentVariableDeleted((EnvironmentVariable) fromObject);
                    }

                }).in(dbc);
        UIUtils.setDefaultButtonWidth(btnRemove);
    }

    private SelectionListener onResetEnvVar() {
        return new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                EnvironmentVariable envVar = UIUtils.getFirstElement(envViewer.getSelection(),
                        EnvironmentVariable.class);
                if (MessageDialog.openQuestion(getShell(), "Reset " + ENVIRONMENT_VARIABLE_LABEL,
                        NLS.bind("Are you sure you want to reset the {0} {1}?",
                                ENVIRONMENT_VARIABLE_LABEL.toLowerCase(), envVar.getKey()))) {
                    String key = envVar.getKey();
                    model.resetEnvironmentVariable(envVar);
                    selectEnvVarByKey(key);
                }
            }

        };
    }

    private SelectionListener onResetEnvVars() {
        return new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                List<EnvironmentVariable> vars = model.getEnvironmentVariables();
                EnvironmentVariable envVar = UIUtils.getFirstElement(envViewer.getSelection(),
                        EnvironmentVariable.class);
                if (MessageDialog.openQuestion(getShell(), "Reset " + ENVIRONMENT_VARIABLE_LABEL, NLS.bind(
                        "Are you sure you want to reset all {0}s?", ENVIRONMENT_VARIABLE_LABEL.toLowerCase()))) {
                    vars.stream().forEach(v -> model.resetEnvironmentVariable(v));
                    if (envVar != null) {
                        selectEnvVarByKey(envVar.getKey());
                    }
                }
            }

        };
    }

    private SelectionListener onRemoveEnvVar() {
        return new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                EnvironmentVariable envVar = UIUtils.getFirstElement(envViewer.getSelection(),
                        EnvironmentVariable.class);
                if (MessageDialog.openQuestion(getShell(), "Remove " + ENVIRONMENT_VARIABLE_LABEL,
                        NLS.bind("Are you sure you want to remove the {0} {1}?",
                                ENVIRONMENT_VARIABLE_LABEL.toLowerCase(), envVar.getKey()))) {
                    model.removeEnvironmentVariable(envVar);
                    envViewer.refresh();
                }
            }

        };
    }

    private class EditHandler extends SelectionAdapter implements IDoubleClickListener {
        @Override
        public void widgetSelected(SelectionEvent e) {
            handleEvent();
        }

        @Override
        public void doubleClick(DoubleClickEvent event) {
            handleEvent();
        }

        private void handleEvent() {
            EnvironmentVariable var = UIUtils.getFirstElement(envViewer.getSelection(), EnvironmentVariable.class);
            Set<String> usedKeys = model.getEnvironmentVariables().stream()
                    .filter(v -> !model.isEnvironmentVariableDeleted(v)).map(v -> v.getKey())
                    .collect(Collectors.toSet());
            usedKeys.remove(var.getKey());
            EnvironmentVariable copy = new EnvironmentVariable(var.getKey(),
                    model.isEnvironmentVariableDeleted(var) ? "" : var.getValue(), var.isNew());
            IKeyValueWizardModel<IKeyValueItem> dialogModel = new KeyValueWizardModelBuilder<IKeyValueItem>(copy)
                    .windowTitle(ENVIRONMENT_VARIABLE_LABEL).title("Edit " + ENVIRONMENT_VARIABLE_LABEL)
                    .description(NLS.bind("Edit the {0}.", ENVIRONMENT_VARIABLE_LABEL.toLowerCase()))
                    .keyLabel(ENVIRONMENT_VARIABLE_KEY_LABEL).editableKey(var.isNew() || canDeleteAnyVar)
                    .groupLabel(ENVIRONMENT_VARIABLE_LABEL)
                    .keyAfterConvertValidator(new EnvironmentVarKeyValidator(usedKeys)).build();
            OkCancelButtonWizardDialog dialog = new OkCancelButtonWizardDialog(getShell(),
                    new KeyValueWizard<>(var, dialogModel));
            if (OkCancelButtonWizardDialog.OK == dialog.open()) {
                model.updateEnvironmentVariable(var, dialogModel.getKey(), dialogModel.getValue());
                selectEnvVarByKey(dialogModel.getKey());
            }
        }

    }

    private SelectionListener onAdd() {
        return new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                Set<String> usedKeys = model.getEnvironmentVariables().stream()
                        .filter(v -> !model.isEnvironmentVariableDeleted(v)).map(v -> v.getKey())
                        .collect(Collectors.toSet());
                IKeyValueWizardModel<KeyValueItem> dialogModel = new KeyValueWizardModelBuilder<KeyValueItem>()
                        .windowTitle(ENVIRONMENT_VARIABLE_LABEL).title("Add " + ENVIRONMENT_VARIABLE_LABEL)
                        .description(NLS.bind("Add an {0}.", ENVIRONMENT_VARIABLE_LABEL.toLowerCase()))
                        .keyLabel(ENVIRONMENT_VARIABLE_KEY_LABEL).groupLabel(ENVIRONMENT_VARIABLE_LABEL)
                        .keyAfterConvertValidator(new EnvironmentVarKeyValidator(usedKeys)).build();
                OkCancelButtonWizardDialog dialog = new OkCancelButtonWizardDialog(getShell(),
                        new KeyValueWizard<>(dialogModel));
                if (OkCancelButtonWizardDialog.OK == dialog.open()) {
                    model.addEnvironmentVariable(dialogModel.getKey(), dialogModel.getValue());
                    selectEnvVarByKey(dialogModel.getKey());
                }
            }
        };
    }

    private void selectEnvVarByKey(String key) {
        EnvironmentVariable envVar = model.getEnvironmentVariable(key);
        if (envVar != null) {
            envViewer.setSelection(new StructuredSelection(envVar));
            envViewer.reveal(envVar);
        }
    }

    protected TableViewer createEnvVarTable(Composite tableContainer) {
        Table table = new Table(tableContainer, SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL);
        table.setLinesVisible(true);
        table.setHeaderVisible(true);
        this.envViewer = new TableViewerBuilder(table, tableContainer)
                .column(new IColumnLabelProvider<IKeyValueItem>() {
                    @Override
                    public String getValue(IKeyValueItem label) {
                        boolean isDeleted = model.isEnvironmentVariableDeleted(label);
                        return !isDeleted ? label.getKey() : "[deleted] " + label.getKey();
                    }

                    @Override
                    public boolean isModified(IKeyValueItem e) {
                        return ((EnvironmentVariable) e).isNew() || model.isEnvironmentVariableDeleted(e);
                    }
                }).name("Name").align(SWT.LEFT).weight(2).minWidth(75).buildColumn()
                .column(new IColumnLabelProvider<IKeyValueItem>() {
                    @Override
                    public String getValue(IKeyValueItem label) {
                        if (model.isEnvironmentVariableDeleted(label)) {
                            return "";
                        }
                        return label.getValue();
                    }

                    @Override
                    public boolean isModified(IKeyValueItem e) {
                        return model.isEnvironmentVariableModified((EnvironmentVariable) e);
                    }
                }).name("Value").align(SWT.LEFT).weight(2).minWidth(100).buildColumn().buildViewer();
        envViewer.setComparator(new ViewerComparator() {

            @Override
            public int compare(Viewer viewer, Object e1, Object e2) {
                IKeyValueItem first = (IKeyValueItem) e1;
                IKeyValueItem other = (IKeyValueItem) e2;
                return first.getKey().compareTo(other.getKey());
            }

        });
        envViewer.addDoubleClickListener(new EditHandler());
        return envViewer;
    }

}