org.splevo.ui.dashboard.ProcessControlTab.java Source code

Java tutorial

Introduction

Here is the source code for org.splevo.ui.dashboard.ProcessControlTab.java

Source

/*******************************************************************************
 * Copyright (c) 2014
 *
 * All rights reserved. This program and the accompanying materials
 * are 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:
 *    Benjamin Klatt
 *******************************************************************************/
package org.splevo.ui.dashboard;

import java.io.File;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.io.FilenameUtils;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wb.swt.ResourceManager;
import org.mihalis.opal.header.Header;
import org.splevo.project.SPLevoProject;
import org.splevo.project.VPMModelReference;
import org.splevo.ui.SPLevoUIPlugin;
import org.splevo.ui.commons.util.WorkspaceUtil;
import org.splevo.ui.editors.SPLevoProjectEditor;
import org.splevo.ui.jobs.SPLevoBlackBoard;
import org.splevo.ui.listeners.GenerateFeatureModelListener;
import org.splevo.ui.listeners.InitVPMListener;
import org.splevo.ui.listeners.OpenVPMListener;
import org.splevo.ui.listeners.StartRefactoringListener;
import org.splevo.ui.listeners.VPMAnalysisListener;
import org.splevo.ui.listeners.WorkflowListenerUtil;
import org.splevo.ui.vpexplorer.util.VPMUIUtil;
import org.splevo.ui.workflow.BuildSPLWorkflowConfiguration;
import org.splevo.ui.workflow.SnapshotSPLWorkflowDelegate;

import com.google.common.collect.Iterables;

import de.uka.ipd.sdq.workflow.jobs.JobFailedException;

/**
 * The tab to control the consolidation process.
 */
public class ProcessControlTab extends AbstractDashboardTab {

    /** Button Init VPM. */
    private Button initVpmBtn;

    /** Button Analyze VPM. */
    private Button analyzeVPMBtn;

    /** Button Start Refactoring. */
    private Button startRefactoringBtn;

    /** Button Generate feature model. */
    private Button generateFMBtn;

    /** Button Open VPM. */
    private Button openVPMBtn;

    /** Shows the VPMs. */
    private TableViewer tableViewer;

    /** Input of the tableViewer. */
    private List<VPMModelReference> vpmInput;

    /** The reverse buttons in the VPM Table. */
    private Map<Object, Button> reverseButtons;

    /**
     * Create the tab to handle the SPL profile configuration.
     * 
     * @param splevoProjectEditor
     *            The editor to access when configuration is modified.
     * @param tabFolder
     *            The folder to add the tab to.
     * 
     * @param tabIndex
     *            The index of the tab within the parent tab folder.
     */
    public ProcessControlTab(SPLevoProjectEditor splevoProjectEditor, TabFolder tabFolder, int tabIndex) {
        super(splevoProjectEditor);
        createTab(tabFolder, tabIndex);
    }

    /**
     * Create the tab.
     * 
     * @param tabFolder
     *            The folder to add the tab to.
     * @param tabIndex
     *            The index of the tab within the parent tab folder.
     */
    private void createTab(TabFolder tabFolder, int tabIndex) {

        TabItem tbtmProcessControl = new TabItem(tabFolder, SWT.NONE, tabIndex);
        tbtmProcessControl.setText("Process Control");

        ScrolledComposite scrolledComposite = new ScrolledComposite(tabFolder, SWT.V_SCROLL);
        scrolledComposite.setExpandHorizontal(true);
        scrolledComposite.setExpandVertical(true);
        tbtmProcessControl.setControl(scrolledComposite);

        Composite composite = new Composite(scrolledComposite, SWT.FILL);
        composite.setLayout(new GridLayout(1, false));
        composite.setLayoutData(new GridData(GridData.FILL, GridData.VERTICAL_ALIGN_BEGINNING, true, false));

        scrolledComposite.setContent(composite);

        createHeader(composite);
        createActions(composite);
        createVPMTable(composite);
        createSnapshot(composite);
    }

    private void createVPMTable(Composite composite) {
        final Group vpmGroup = new Group(composite, SWT.FILL);
        vpmGroup.setText("Variation Point Models");
        vpmGroup.setLayout(new GridLayout(1, false));
        vpmGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));

        final Table table = new Table(vpmGroup, SWT.BORDER | SWT.V_SCROLL);
        table.setLinesVisible(true);
        table.setHeaderVisible(true);
        // set row height
        table.addListener(SWT.MeasureItem, new Listener() {
            public void handleEvent(Event event) {
                event.height = 25;
            }
        });
        reverseButtons = new HashMap<Object, Button>();

        vpmGroup.addControlListener(new ControlAdapter() {
            @Override
            public void controlResized(ControlEvent e) {
                Rectangle area = vpmGroup.getClientArea();
                Point oldSize = table.getSize();
                int buttonPrefferedWidth = -1;
                if (reverseButtons != null && reverseButtons.values().toArray().length > 0) {
                    buttonPrefferedWidth = ((Button) reverseButtons.values().toArray()[0]).computeSize(SWT.DEFAULT,
                            SWT.DEFAULT).x;
                }
                if (oldSize.x > area.width) {
                    // table is getting smaller so make the columns
                    // smaller first and then resize the table to
                    // match the client area width
                    setColumnSize(buttonPrefferedWidth);
                    table.setSize(area.width, area.height);
                } else {
                    // table is getting bigger so make the table
                    // bigger first and then make the columns wider
                    // to match the client area width
                    table.setSize(area.width, area.height);
                    setColumnSize(buttonPrefferedWidth);

                }
            }

            private void setColumnSize(int buttonPrefferedWidth) {
                table.getColumns()[0].pack();
                table.getColumns()[1].pack();
                if (buttonPrefferedWidth < 0) {
                    table.getColumns()[2].pack();
                } else {
                    table.getColumns()[2].setWidth(buttonPrefferedWidth);
                }
            }
        });

        createTable(table);

    }

    private void createTable(Table exampleTable) {
        tableViewer = new TableViewer(exampleTable);
        tableViewer.getTable().setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
        TableViewerColumn vpmColumn = new TableViewerColumn(tableViewer, SWT.NONE);
        vpmColumn.getColumn().setText("VPM");
        vpmColumn.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (!(element instanceof VPMModelReference)) {
                    return "";
                }
                VPMModelReference vpm = (VPMModelReference) element;
                return FilenameUtils.getBaseName(vpm.getPath());
            }
        });
        TableViewerColumn dateColumn = new TableViewerColumn(tableViewer, SWT.NONE);
        dateColumn.getColumn().setText("Date");
        dateColumn.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (!(element instanceof VPMModelReference)) {
                    return "";
                }
                VPMModelReference vpm = (VPMModelReference) element;

                IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
                IResource resource = root.findMember(vpm.getPath());
                File file = new File(resource.getLocationURI());

                DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT,
                        Locale.getDefault());
                return dateFormat.format(file.lastModified());
            }
        });
        TableViewerColumn actionColumn = new TableViewerColumn(tableViewer, SWT.NONE);
        actionColumn.getColumn().setText("Action");
        actionColumn.setLabelProvider(new CellButtonLabelProvider());

        tableViewer.setContentProvider(new ArrayContentProvider());
        vpmInput = getSPLevoProject().getVpmModelReferences();
        tableViewer.setInput(vpmInput);
    }

    private void createSnapshot(Composite composite) {
        Group snapGroup = new Group(composite, SWT.FILL);
        snapGroup.setText("Create Variation Point Model Snapshot");
        snapGroup.setLayout(new GridLayout(3, false));
        snapGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));

        Label nameLabel = new Label(snapGroup, SWT.NONE);
        nameLabel.setText("Name");

        final Text nameText = new Text(snapGroup, SWT.BORDER);
        nameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));

        final Button nameButton = new Button(snapGroup, SWT.NONE);
        nameButton.setText("Create");
        nameButton.setEnabled(false);
        nameButton.addMouseListener(new MouseListener() {

            @Override
            public void mouseUp(MouseEvent e) {
                SPLevoBlackBoard spLevoBlackBoard = new SPLevoBlackBoard();

                String splPath = getSPLevoProject().getWorkspace() + "RefactoredSPL";

                BuildSPLWorkflowConfiguration configuration = new BuildSPLWorkflowConfiguration(splPath);
                configuration.setSplevoProjectEditor(getSplevoProjectEditor());

                String name = nameText.getText().trim();
                SnapshotSPLWorkflowDelegate buildSPLWorkflowConfiguration = null;
                try {
                    buildSPLWorkflowConfiguration = new SnapshotSPLWorkflowDelegate(configuration, spLevoBlackBoard,
                            name);
                    WorkflowListenerUtil.runWorkflowAndUpdateUI(buildSPLWorkflowConfiguration, "Save VPM",
                            getSplevoProjectEditor());
                    nameText.setText("");
                } catch (JobFailedException e1) {
                    Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
                    MessageDialog.openError(shell, "Error", e1.getMessage());
                }
            }

            @Override
            public void mouseDown(MouseEvent e) {
            }

            @Override
            public void mouseDoubleClick(MouseEvent e) {
            }
        });

        nameText.addModifyListener(new ModifyListener() {

            @Override
            public void modifyText(ModifyEvent e) {
                if (nameText.getText().trim().equals("")) {
                    nameButton.setEnabled(false);
                } else {
                    nameButton.setEnabled(true);
                }

            }
        });
    }

    /**
     * A LabelProvider to display buttons and removing them if they are not needed anymore.
     */
    private class CellButtonLabelProvider extends CellLabelProvider {
        private static final String VPM_DATA = "vpm_data";
        private static final String BUTTON_EDITOR = "button_editor";

        @Override
        public void update(final ViewerCell cell) {

            TableItem item = (TableItem) cell.getItem();

            final Button button;

            if (reverseButtons.containsKey(cell.getElement())) {
                button = reverseButtons.get(cell.getElement());
            } else {
                button = new Button((Composite) cell.getViewerRow().getControl(), SWT.NONE);
                button.setData(VPM_DATA, item.getData());
                button.setText("Revert to this version");
                button.addMouseListener(new MouseListener() {

                    @Override
                    public void mouseUp(MouseEvent event) {
                        Shell shell = event.widget.getDisplay().getActiveShell();
                        if (!(event.getSource() instanceof Button)) {
                            return;
                        }
                        Button button = (Button) event.getSource();
                        if (!(button.getData(VPM_DATA) instanceof VPMModelReference)) {
                            return;
                        }
                        VPMModelReference vpm = (VPMModelReference) button.getData(VPM_DATA);
                        boolean confirmed = MessageDialog.openQuestion(shell, "Switch Back VPM Version",
                                String.format(
                                        "You want to switch back to %s, which removes all later versions. "
                                                + "Do you want to continue?",
                                        FilenameUtils.getBaseName(vpm.getPath())));
                        if (confirmed) {
                            try {
                                VPMUIUtil.switchBackVPMVersion(getSPLevoProject(), vpm).join();
                            } catch (InterruptedException e) {
                            }
                            tableViewer.setInput(vpmInput);
                            tableViewer.refresh();
                            disposeButtons();
                        }
                    }

                    private void disposeButtons() {
                        for (Button button : reverseButtons.values()) {
                            if (button.isDisposed()) {
                                continue;
                            }
                            Object o = button.getData(VPM_DATA);
                            if (!vpmInput.contains(o)) {
                                TableEditor e = (TableEditor) button.getData(BUTTON_EDITOR);
                                e.getEditor().dispose();
                                e.dispose();
                                reverseButtons.remove(cell.getElement());
                            }
                        }
                    }

                    @Override
                    public void mouseDown(MouseEvent e) {
                    }

                    @Override
                    public void mouseDoubleClick(MouseEvent e) {
                    }
                });
                reverseButtons.put(cell.getElement(), button);
            }
            TableEditor editor = new TableEditor(item.getParent());
            editor.grabHorizontal = true;
            editor.grabVertical = true;
            editor.setEditor(button, item, cell.getColumnIndex());
            button.setData(BUTTON_EDITOR, editor);
            editor.layout();
        }
    }

    /**
     * Refreshes the table after data changes.
     */
    public void refreshViewer() {
        if (tableViewer != null) {
            tableViewer.refresh();
            tableViewer.getControl().getParent().layout();
            tableViewer.getControl().getParent().getParent().layout();
        }
    }

    private void createActions(Composite composite) {

        Group g = new Group(composite, SWT.FILL);
        g.setText("Actions");
        g.setLayout(new GridLayout(9, false));
        g.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));

        Composite filler1 = new Composite(g, SWT.NONE);
        GridData layoutData = new GridData(SWT.CENTER, SWT.CENTER, false, false, 4, 1);
        layoutData.heightHint = 0;
        filler1.setLayoutData(layoutData);

        final Image circleImage = ResourceManager.getPluginImage("org.splevo.ui", "icons/arrow_circle.png");
        Label circleLbl = new Label(g, SWT.NONE);
        circleLbl.setImage(circleImage);
        circleLbl.setLayoutData(new GridData(SWT.CENTER, SWT.BOTTOM, false, false));

        Composite filler2 = new Composite(g, SWT.NONE);
        filler2.setLayoutData(layoutData);

        Label activityStart = new Label(g, SWT.NONE);
        activityStart.setImage(ResourceManager.getPluginImage("org.splevo.ui", "icons/bullet_green.png"));

        addActivityFlowButton(g);

        initVpmBtn = new Button(g, SWT.WRAP);
        initVpmBtn.addMouseListener(new InitVPMListener(getSplevoProjectEditor()));
        initVpmBtn.setText("Init\nVPM");
        initVpmBtn.setToolTipText("Your product copies will be analyzed for differences between them "
                + "and a variation point model (VPM) will be opened.");
        getGridDataForButtons(initVpmBtn);

        addActivityFlowButton(g);

        analyzeVPMBtn = new Button(g, SWT.WRAP);
        analyzeVPMBtn.addMouseListener(new VPMAnalysisListener(getSplevoProjectEditor()));
        analyzeVPMBtn.setText("Refine\nVPM");
        analyzeVPMBtn.setToolTipText(
                "Analyze the identified variation points (differences) " + "for any relationships between them.");
        getGridDataForButtons(analyzeVPMBtn);

        addActivityFlowButton(g);

        startRefactoringBtn = new Button(g, SWT.WRAP);
        startRefactoringBtn.addMouseListener(new StartRefactoringListener(getSplevoProjectEditor()));
        startRefactoringBtn.setText("Refactor\nCopies");
        startRefactoringBtn.setToolTipText(
                "Integrate the changes identified by variation points " + "into the leading projects.");
        getGridDataForButtons(startRefactoringBtn);

        addActivityFlowButton(g);

        generateFMBtn = new Button(g, SWT.WRAP);
        generateFMBtn.addMouseListener(new GenerateFeatureModelListener(getSplevoProjectEditor()));
        generateFMBtn.setText("Export\nSPL");
        generateFMBtn
                .setToolTipText("At any time, the designed software product line can be exportet to the format "
                        + "specified in the Configuration section of the dashboard.");
        getGridDataForButtons(generateFMBtn);

        Composite filler3 = new Composite(g, SWT.NONE);
        filler3.setLayoutData(layoutData);

        openVPMBtn = new Button(g, SWT.NONE);
        openVPMBtn.setImage(ResourceManager.getPluginImage("org.splevo.ui", "icons/splevo.gif"));
        openVPMBtn.addMouseListener(new OpenVPMListener(getSplevoProjectEditor()));
        openVPMBtn.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, true));
        openVPMBtn.setAlignment(SWT.CENTER);
    }

    private void getGridDataForButtons(Button button) {
        GridData gridData = new GridData();
        gridData.widthHint = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
        button.setLayoutData(gridData);
    }

    private void addActivityFlowButton(Composite container) {
        Label iconLabel = new Label(container, SWT.NONE);
        iconLabel.setImage(ResourceManager.getPluginImage("org.splevo.ui", "icons/arrow_right.png"));
        iconLabel.setAlignment(SWT.CENTER);
    }

    /**
     * Enable Buttons if the information for the action is available.
     */
    public void enableButtonsIfInformationAvailable() {
        disableAllButtonsExceptProjectSelection();

        if (projectsSelected()) {
            initVpmBtn.setEnabled(true);
        } else {
            return;
        }

        if (vpmAvailable()) {
            openVPMBtn.setEnabled(true);
            analyzeVPMBtn.setEnabled(true);
            startRefactoringBtn.setEnabled(true);
            generateFMBtn.setEnabled(true);
        } else {
            return;
        }
    }

    /**
     * Check if at least one variation point model is set and can be accessed.
     * 
     * @return True if an accessible vpm exists.
     */
    private boolean vpmAvailable() {
        SPLevoProject splevoProject = getSPLevoProject();
        if (splevoProject.getVpmModelReferences().size() > 0) {
            String vpmPath = WorkspaceUtil.getAbsoluteFromWorkspaceRelativePath(
                    Iterables.getLast(splevoProject.getVpmModelReferences()).getPath());
            return new File(vpmPath).canRead();
        }
        return false;
    }

    /**
     * Checks if both input models have more than one project.
     * 
     * @return true, if both input models have more than one project, else false
     */
    private boolean projectsSelected() {
        SPLevoProject splevoProject = getSPLevoProject();
        return splevoProject.getLeadingProjects().size() > 0 && splevoProject.getIntegrationProjects().size() > 0;
    }

    /**
     * Disable all buttons except the Project Selection button.
     */
    private void disableAllButtonsExceptProjectSelection() {
        List<Control> buttons = new ArrayList<Control>();
        buttons.add(generateFMBtn);
        buttons.add(initVpmBtn);
        buttons.add(analyzeVPMBtn);
        buttons.add(startRefactoringBtn);
        buttons.add(openVPMBtn);

        for (Control button : buttons) {
            button.setEnabled(false);
        }
    }

    private void createHeader(Composite composite) {
        final Header header = new Header(composite, SWT.NONE);
        header.setTitle("SPLevo Dashboard");
        header.setImage(ResourceManager.getPluginImage(SPLevoUIPlugin.PLUGIN_ID, "icons/kopl_dash.png"));
        header.setDescription("Control the consolidation process.");
        header.setLayoutData(new GridData(GridData.FILL, GridData.VERTICAL_ALIGN_BEGINNING, true, false));
    }
}