org.whole.product.lw.launching.EnvironmentBlock.java Source code

Java tutorial

Introduction

Here is the source code for org.whole.product.lw.launching.EnvironmentBlock.java

Source

/**
 * Copyright 2004-2014 Riccardo Solmi. All rights reserved.
 * This file is part of the Whole Platform.
 *
 * The Whole Platform is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The Whole Platform 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.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
 */
package org.whole.product.lw.launching;

import static org.whole.product.lw.launching.IWholeOperationLauncherConstants.ENVIRONMENT;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
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.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.whole.lang.bindings.BindingManagerFactory;
import org.whole.lang.bindings.IBindingScope;
import org.whole.lang.model.IEntity;
import org.whole.lang.reflect.DataKinds;
import org.whole.lang.ui.util.UIUtils;
import org.whole.lang.util.DataTypeUtils;

/**
 * @author Enrico Persiani
 */
public class EnvironmentBlock extends AbstractBlock {
    protected IBindingScope scope;
    protected TableViewer environmentViewer;
    protected Button addButton;
    protected Button editButton;
    protected Button removeButton;

    public EnvironmentBlock(WholeOperationMainTab tab) {
        super("Arguments", tab);
    }

    protected void createContents(Composite composite) {
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        createEnvironmentViewer(composite);
        createEnvironmentViewerButtons(composite);
    }

    protected void createEnvironmentViewer(Composite composite) {
        environmentViewer = new TableViewer(composite, SWT.SINGLE);
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.widthHint = 300;
        environmentViewer.getControl().setLayoutData(gd);
        environmentViewer.setContentProvider(new EnvironmentContentProvider());
        environmentViewer.setLabelProvider(new EnvironmentLabelProvider());
        environmentViewer.setComparator(new ViewerComparator() {
            @Override
            public boolean isSorterProperty(Object element, String property) {
                return true;
            }
        });

        Table table = environmentViewer.getTable();
        TableLayout tableLayout = new TableLayout();
        table.setLayout(tableLayout);
        table.setHeaderVisible(true);

        ColumnWeightData columnWeightData = new ColumnWeightData(20);
        tableLayout.addColumnData(columnWeightData);
        TableColumn tc = new TableColumn(table, SWT.NONE, 0);
        tc.setResizable(columnWeightData.resizable);
        tc.setText("Name");

        columnWeightData = new ColumnWeightData(10);
        tableLayout.addColumnData(columnWeightData);
        tc = new TableColumn(table, SWT.NONE, 1);
        tc.setResizable(columnWeightData.resizable);
        tc.setText("Type");

        columnWeightData = new ColumnWeightData(70);
        tableLayout.addColumnData(columnWeightData);
        tc = new TableColumn(table, SWT.NONE, 2);
        tc.setResizable(columnWeightData.resizable);
        tc.setText("Value");
    }

    protected void createEnvironmentViewerButtons(Composite composite) {
        Composite buttonComposite = new Composite(composite, SWT.NONE);
        GridLayout glayout = new GridLayout();
        glayout.marginHeight = 0;
        glayout.marginWidth = 0;
        glayout.numColumns = 1;
        GridData gdata = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_END);
        buttonComposite.setLayout(glayout);
        buttonComposite.setLayoutData(gdata);
        buttonComposite.setFont(composite.getFont());

        addButton = createButton(buttonComposite, "Add ...");
        editButton = createButton(buttonComposite, "Edit ...");
        removeButton = createButton(buttonComposite, "Remove ...");

        addButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                VariableDialog dialog = new VariableDialog(getTab().getControl().getShell(), "Add variable",
                        "Add a new variable to the operation environment");
                if (dialog.open() == Window.OK) {
                    scope.wDef(dialog.getName(), dialog.getValue());
                    environmentViewer.refresh();
                    updateLaunchConfiguration();
                }
            }
        });

        editButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                IStructuredSelection structuredSelection = (IStructuredSelection) environmentViewer.getSelection();
                String selectedVariableName = (String) ((Object[]) structuredSelection.getFirstElement())[0];

                VariableDialog dialog = new VariableDialog(getTab().getControl().getShell(), "Edit variable",
                        "Edit a variable in the operation environment", selectedVariableName,
                        scope.wGet(selectedVariableName));
                if (dialog.open() == Window.OK) {
                    scope.wUnset(selectedVariableName);
                    scope.wDef(dialog.getName(), dialog.getValue());
                    environmentViewer.refresh();
                    updateLaunchConfiguration();
                }
            }
        });

        removeButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                IStructuredSelection structuredSelection = (IStructuredSelection) environmentViewer.getSelection();
                String selectedVariableName = (String) ((Object[]) structuredSelection.getFirstElement())[0];
                if (MessageDialog.openQuestion(getTab().getControl().getShell(), "Remove variable",
                        "Are you sure you want to remove the variable '" + selectedVariableName + "'?")) {
                    scope.wUnset(selectedVariableName);
                    environmentViewer.refresh();
                    updateLaunchConfiguration();
                }
            }
        });

        // setup buttons enablement on selection uptade
        editButton.setEnabled(false);
        removeButton.setEnabled(false);
        environmentViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                boolean hasSelection = !event.getSelection().isEmpty();
                editButton.setEnabled(hasSelection);
                removeButton.setEnabled(hasSelection);
            }
        });
    }

    private Button createButton(Composite composite, String text) {
        Button button = new Button(composite, SWT.PUSH);
        button.setText(text);
        button.setFont(JFaceResources.getDialogFont());
        int widthHint = UIUtils.getButtonWidthHint(composite);
        GridData gd = new GridData();
        gd.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
        gd.horizontalAlignment = GridData.FILL;
        button.setLayoutData(gd);
        return button;
    }

    @Override
    public void initializeFrom(ILaunchConfiguration configuration) throws CoreException {
        scope = LaunchConfigurationUtils.loadBindingScope(configuration);
        environmentViewer.setInput(scope);
    }

    @Override
    public void performApply(ILaunchConfigurationWorkingCopy configuration) {
        LaunchConfigurationUtils.saveBindingScope(configuration, scope);
    }

    @Override
    public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
        configuration.setAttribute(ENVIRONMENT, new HashMap<String, String>());
    }

    protected class EnvironmentContentProvider implements IStructuredContentProvider {
        public Object[] getElements(Object inputElement) {
            IBindingScope scope = (IBindingScope) inputElement;
            Set<String> localNames = scope.wLocalNames();
            int size = localNames.size();
            Object[][] elements = new Object[size][2];

            int index = 0;
            Iterator<String> iterator = localNames.iterator();
            ;
            while (iterator.hasNext()) {
                String name = iterator.next();
                elements[index][0] = name;
                elements[index++][1] = scope.wGet(name);
            }
            return elements;
        }

        public void dispose() {
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }
    }

    protected class EnvironmentLabelProvider extends LabelProvider implements ITableLabelProvider {
        public String getColumnText(Object element, int columnIndex) {
            String result = null;
            if (element != null) {
                Object[] pair = (Object[]) element;
                switch (columnIndex) {
                case 0:
                    result = (String) pair[0];
                    break;
                case 1:
                    result = DataTypeUtils.getDataKind((IEntity) pair[1]).toString();
                    break;
                case 2:
                    result = ((IEntity) pair[1]).wStringValue();
                    break;
                }
            }
            return result;
        }

        @Override
        public String getText(Object element) {
            return getColumnText(element, 0);
        }

        public Image getColumnImage(Object element, int columnIndex) {
            return null;
        }
    }

    private static class VariableDialog extends Dialog {
        protected String name;
        protected IEntity value;

        protected Text nameText;
        protected Combo typeCombo;
        protected Text valueText;

        protected String title;
        protected String message;
        protected Label errorMessageLabel;

        public VariableDialog(Shell parentShell, String title, String message) {
            this(parentShell, title, message, null, null);
        }

        public VariableDialog(Shell parentShell, String title, String message, String initName, IEntity initValue) {
            super(parentShell);
            setShellStyle(getShellStyle() | SWT.SHELL_TRIM);
            initDefaults(initName, initValue);
            this.title = title;
            this.message = message;
        }

        public String getName() {
            return name;
        }

        public IEntity getValue() {
            return value;
        }

        protected void initDefaults(String initName, IEntity initValue) {
            name = initName != null ? initName : "";
            value = initValue != null ? initValue : BindingManagerFactory.instance.createValue("");
        }

        @Override
        protected void configureShell(Shell newShell) {
            super.configureShell(newShell);
            if (title != null)
                newShell.setText(title);
        }

        @Override
        protected Control createDialogArea(Composite parent) {
            Composite outerComposite = (Composite) super.createDialogArea(parent);

            GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
            Label messageLabel = new Label(outerComposite, SWT.NONE);
            messageLabel.setText(message);
            messageLabel.setLayoutData(gridData);

            Composite innerComposite = new Composite(outerComposite, SWT.NONE);
            GridLayout layout = new GridLayout(2, false);
            innerComposite.setLayout(layout);
            gridData = new GridData(GridData.FILL_BOTH);
            innerComposite.setLayoutData(gridData);

            gridData = new GridData(GridData.FILL_HORIZONTAL);
            gridData.widthHint = 300;

            Label labelControl = new Label(innerComposite, SWT.NONE);
            labelControl.setText("Name:");
            nameText = new Text(innerComposite, SWT.SINGLE | SWT.BORDER);
            nameText.setLayoutData(gridData);

            labelControl = new Label(innerComposite, SWT.NONE);
            labelControl.setText("Type:");
            typeCombo = new Combo(innerComposite, SWT.NONE);
            typeCombo.setLayoutData(gridData);

            labelControl = new Label(innerComposite, SWT.NONE);
            labelControl.setText("Value:");
            valueText = new Text(innerComposite, SWT.SINGLE | SWT.BORDER);
            valueText.setLayoutData(gridData);

            gridData = new GridData(GridData.FILL_HORIZONTAL);
            errorMessageLabel = new Label(outerComposite, SWT.NONE);
            errorMessageLabel.setLayoutData(gridData);

            configureControls();

            applyDialogFont(outerComposite);
            return outerComposite;
        }

        @Override
        protected Control createContents(Composite parent) {
            Control control = super.createContents(parent);

            registerValidation();

            return control;
        }

        private void configureControls() {
            nameText.setText(name);

            DataKinds[] values = DataKinds.values();
            String[] items = new String[values.length - 3];
            for (int i = 0, j = 0; i < values.length; i++)
                if (!values[i].isEnumValue() && !values[i].isObject() && !values[i].isNotAData())
                    items[j++] = values[i].toString();
            typeCombo.setItems(items);
            typeCombo.setText(DataTypeUtils.getDataKind(value).toString());

            valueText.setText(value.wStringValue());
        }

        private void registerValidation() {
            nameText.addModifyListener(new ModifyListener() {
                public void modifyText(ModifyEvent e) {
                    validate();
                }
            });
            typeCombo.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent e) {
                    validate();
                }
            });
            valueText.addModifyListener(new ModifyListener() {
                public void modifyText(ModifyEvent e) {
                    validate();
                }
            });
            validate();
        }

        private void validate() {
            name = nameText.getText();
            if (name.length() == 0)
                setErrorMessage("Invalid variable name");
            else
                try {
                    parseVariable();
                    setErrorMessage(null);
                } catch (Exception e) {
                    setErrorMessage("Invalid value for type " + typeCombo.getText());
                }
        }

        private void parseVariable() {
            IEntity newEntity = null;
            switch (DataKinds.valueOf(typeCombo.getText())) {
            case BOOLEAN:
                newEntity = BindingManagerFactory.instance.createValue(true);
                break;
            case BYTE:
                newEntity = BindingManagerFactory.instance.createValue((byte) 0);
                break;
            case SHORT:
                newEntity = BindingManagerFactory.instance.createValue((short) 0);
                break;
            case INT:
                newEntity = BindingManagerFactory.instance.createValue((int) 0);
                break;
            case LONG:
                newEntity = BindingManagerFactory.instance.createValue((long) 0);
                break;
            case DOUBLE:
                newEntity = BindingManagerFactory.instance.createValue(0.0);
                break;
            case FLOAT:
                newEntity = BindingManagerFactory.instance.createValue(0.0f);
                break;
            case DATE:
                newEntity = BindingManagerFactory.instance.createValue(new Date());
                break;
            case CHAR:
                newEntity = BindingManagerFactory.instance.createValue(' ');
                break;
            case STRING:
                newEntity = BindingManagerFactory.instance.createValue("");
                break;
            //         case OBJECT:
            //         case ENUM_VALUE:
            }
            newEntity.wSetValue(valueText.getText());
            value = newEntity;
        }

        private void setErrorMessage(String errorMessage) {
            if (errorMessage == null) {
                errorMessageLabel.setText("");
                getButton(IDialogConstants.OK_ID).setEnabled(true);
            } else {
                errorMessageLabel.setText(errorMessage);
                getButton(IDialogConstants.OK_ID).setEnabled(false);
            }
        }
    };
}