co.turnus.ui.profiling.wizard.AbstractWeightsGeneratorWizard.java Source code

Java tutorial

Introduction

Here is the source code for co.turnus.ui.profiling.wizard.AbstractWeightsGeneratorWizard.java

Source

/* 
 * TURNUS, the co-exploration framework
 * 
 * Copyright (C) 2015 EPFL SCI STI MM
 *
 * This file is part of TURNUS.
 *
 * TURNUS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * TURNUS 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with TURNUS.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Additional permission under GNU GPL version 3 section 7
 * 
 * If you modify this Program, or any covered work, by linking or combining it
 * with Eclipse (or a modified version of Eclipse or an Eclipse plugin or 
 * an Eclipse library), containing parts covered by the terms of the 
 * Eclipse Public License (EPL), the licensors of this Program grant you 
 * additional permission to convey the resulting work.  Corresponding Source 
 * for a non-source form of such a combination shall include the source code 
 * for the parts of Eclipse libraries used as well as that of the  covered work.
 * 
 */
package co.turnus.ui.profiling.wizard;

import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
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.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
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.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.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWizard;

import co.turnus.TurnusException;
import co.turnus.TurnusExtension;
import co.turnus.common.Operator;
import co.turnus.profiling.ProfilingData;
import co.turnus.profiling.ProfilingWeights;
import co.turnus.profiling.io.XmlProfilingWeightsWriter;
import co.turnus.profiling.util.ProfilingWeightsEstimator;
import co.turnus.ui.profiling.wizard.page.LoadOperatorCostsFilePage;
import co.turnus.ui.profiling.wizard.page.StoreOperatorCostsFilePage;
import co.turnus.ui.util.EclipseHelper;
import co.turnus.ui.widgets.SelectFile;
import co.turnus.util.EcoreHelper;
import co.turnus.util.TurnusLogger;
import co.turnus.util.TurnusUtils;
import co.turnus.widgets.Images;

public class AbstractWeightsGeneratorWizard extends Wizard implements IWorkbenchWizard {

    private class OperatorsCostPage extends WizardPage {

        private class OperatorCost {

            private final Operator op;
            private double cost;

            public OperatorCost(Operator op) {
                this.op = op;
                cost = 1.0;
            }
        }

        /**
         * This class defines the cell modifier
         * 
         * @author Simone Casale Brunet
         * 
         */
        private class CellModifier implements ICellModifier {

            @Override
            public boolean canModify(Object element, String property) {
                return property.equals(columnNames[COST]);
            }

            @Override
            public Object getValue(Object element, String property) {
                // Find the index of the column
                int columnIndex = Arrays.asList(columnNames).indexOf(property);

                Object result = "";
                OperatorCost oc = (OperatorCost) element;

                switch (columnIndex) {
                case OPERATOR:
                    result = oc.op.getName();
                    break;
                case COST:
                    result = Double.toString(oc.cost);
                    break;
                default:
                    break;

                }

                return result;
            }

            @Override
            public void modify(Object element, String property, Object value) {
                if (property.equals(columnNames[COST])) {
                    String intString = (String) value;
                    if (intString.matches("[+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?")) {
                        TableItem item = (TableItem) element;
                        OperatorCost oc = (OperatorCost) item.getData();
                        oc.cost = Double.parseDouble(intString);
                        viewer.refresh();
                    }
                }
            }
        }

        /**
         * This class defines the label provider for the Instances Mapping Tab
         * 
         * @author Simone Casale Brunet
         * 
         */
        private class TableLabelProvider extends LabelProvider implements ITableLabelProvider {

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

            @Override
            public String getColumnText(Object element, int columnIndex) {
                String result = "";
                OperatorCost oc = (OperatorCost) element;
                switch (columnIndex) {
                case OPERATOR:
                    result = oc.op.getName();
                    break;
                case COST:
                    result = Double.toString(oc.cost);
                    break;
                default:
                    break;
                }
                return result;
            }
        }

        /**
         * This class defines the content provider
         * 
         * @author Simone Casale Brunet
         * 
         */
        private class ContentProvider implements IStructuredContentProvider {

            @Override
            public void dispose() {
            }

            @Override
            @SuppressWarnings("unchecked")
            public Object[] getElements(Object inputElement) {
                if (inputElement instanceof HashSet<?>) {
                    return ((Collection<OperatorCost>) inputElement).toArray(new OperatorCost[0]);
                } else {
                    return new Object[0];
                }
            }

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

        /**
         * This class defines a content comparator for sorting instances by the
         * selected column values.
         * 
         * @author Simone Casale Brunet
         * 
         */
        private class ContentComparator extends ViewerComparator {
            private int propertyIndex;
            private static final int DESCENDING = 1;
            private int direction = DESCENDING;

            public ContentComparator() {
                this.propertyIndex = 0;
                direction = DESCENDING;
            }

            @Override
            public int compare(Viewer viewer, Object e1, Object e2) {
                OperatorCost oc1 = (OperatorCost) e1;
                OperatorCost oc2 = (OperatorCost) e2;
                int rc = 0;
                switch (propertyIndex) {
                case OPERATOR:
                    rc = oc1.op.getName().compareTo(oc2.op.getName());
                    break;
                case COST:
                    rc = Double.compare(oc1.cost, oc2.cost);
                    break;
                default:
                    rc = 0;
                }
                // If descending order, flip the direction
                if (direction == DESCENDING) {
                    rc = -rc;
                }
                return rc;
            }

            public int getDirection() {
                return direction == 1 ? SWT.DOWN : SWT.UP;
            }

            public void setColumn(int column) {
                if (column == this.propertyIndex) {
                    // Same sorting column: toggle the direction
                    direction = 1 - direction;
                } else {
                    // New sorting column: ascending sort
                    this.propertyIndex = column;
                    direction = DESCENDING;
                }
            }
        }

        private final int OPERATOR = 0;
        private final int COST = 1;
        private final String[] columnNames = new String[] { "Operator", "Cost" };

        private Collection<OperatorCost> operatorCosts;

        private Table table;
        private TableViewer viewer;
        private ContentComparator comparator;

        private OperatorsCostPage() {
            super("Operators Cost Page");
            setTitle("Abstract Weights Generator");
            setDescription("Configure the cost of each operator");

            // create the operators
            operatorCosts = new HashSet<>();
            for (Operator o : Operator.values()) {
                operatorCosts.add(new OperatorCost(o));
            }
        }

        private Map<Operator, Double> getOperatorsCostMap() {
            Map<Operator, Double> map = new HashMap<Operator, Double>();
            for (OperatorCost o : operatorCosts) {
                map.put(o.op, o.cost);
            }
            return map;
        }

        private void loadOperatorsCost(Map<Operator, Double> map) {
            for (OperatorCost o : operatorCosts) {
                if (map.containsKey(o.op)) {
                    o.cost = map.get(o.op);
                } else {
                    o.cost = 0;
                }
            }
        }

        private void resetOperatorsCost() {
            for (OperatorCost o : operatorCosts) {
                o.cost = 1.0;
            }
        }

        @Override
        public void createControl(Composite parent) {
            final Composite tContainer = new Composite(parent, SWT.NONE);
            GridLayout layout = new GridLayout();
            tContainer.setLayout(layout);
            layout.numColumns = 1;

            // build the table and its accessories
            table = new Table(tContainer, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
            viewer = new TableViewer(table);
            comparator = new ContentComparator();
            viewer.setComparator(comparator);

            // set table layout
            GridData gridData = new GridData(GridData.FILL_BOTH);
            gridData.grabExcessVerticalSpace = true;
            gridData.horizontalSpan = 3;
            gridData.heightHint = 300;
            table.setLayoutData(gridData);
            table.setLinesVisible(true);
            table.setHeaderVisible(true);

            // add table column: operator
            TableColumn column = new TableColumn(table, SWT.LEFT, OPERATOR);
            column.setText(columnNames[OPERATOR]);
            column.setWidth(300);
            column.addSelectionListener(getSelectionAdapter(column, OPERATOR));

            // add table column: cost
            column = new TableColumn(table, SWT.LEFT, COST);
            column.setText(columnNames[COST]);
            column.setWidth(100);
            column.addSelectionListener(getSelectionAdapter(column, COST));

            // create the table viewer
            viewer.setUseHashlookup(true);
            viewer.setColumnProperties(columnNames);
            viewer.setContentProvider(new ContentProvider());
            viewer.setLabelProvider(new TableLabelProvider());

            // Create the cell editors
            CellEditor[] editors = new CellEditor[columnNames.length];
            editors[COST] = new TextCellEditor(table);
            // set the editors
            viewer.setCellEditors(editors);
            viewer.setCellModifier(new CellModifier());
            viewer.setInput(operatorCosts);

            GridData gdata = new GridData(SWT.BORDER, SWT.CENTER, false, false);

            final Composite bContainer = new Composite(tContainer, SWT.NONE);
            layout = new GridLayout();
            bContainer.setLayout(layout);
            layout.numColumns = 3;

            Button button = new Button(bContainer, SWT.PUSH);
            button.setFont(getFont());
            button.setLayoutData(gdata);
            button.setText("Load costs");
            button.setImage(Images.get(Images.ARROW_090));
            button.addSelectionListener(new LoadButtonListener());

            button = new Button(bContainer, SWT.PUSH);
            button.setFont(getFont());
            button.setLayoutData(gdata);
            button.setText("Save costs");
            button.setImage(Images.get(Images.ARROW_270));
            button.addSelectionListener(new StoreButtonListener());

            button = new Button(bContainer, SWT.PUSH);
            button.setFont(getFont());
            button.setLayoutData(gdata);
            button.setText("Reset costs");
            button.setImage(Images.get(Images.ARROW_CIRCLE));
            button.addSelectionListener(new ClearButtonListener());

            // finally, set the container
            setControl(tContainer);

        }

        public boolean isPageComplete() {
            return true;
        }

        private class StoreButtonListener implements SelectionListener {

            @Override
            public void widgetSelected(SelectionEvent e) {
                StoreOperatorCostsFilePage page = new StoreOperatorCostsFilePage(getOperatorsCostMap(), getShell());
                page.open();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }

        }

        private class LoadButtonListener implements SelectionListener {

            @Override
            public void widgetSelected(SelectionEvent e) {
                LoadOperatorCostsFilePage page = new LoadOperatorCostsFilePage(getShell());
                page.open();

                Map<Operator, Double> map = page.getOperatorCostsMap();
                if (map != null) {
                    loadOperatorsCost(map);
                    viewer.refresh();
                }

            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }

        }

        private class ClearButtonListener implements SelectionListener {

            @Override
            public void widgetSelected(SelectionEvent e) {
                resetOperatorsCost();
                viewer.refresh();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }

        }

        /**
         * Create a new {@link SelectionAdapter} for adding the sorting facility
         * to the column
         * 
         * @param column
         *            the table column
         * @param index
         *            the column number index
         * @return
         */
        private SelectionAdapter getSelectionAdapter(final TableColumn column, final int index) {
            SelectionAdapter selectionAdapter = new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    comparator.setColumn(index);
                    int dir = comparator.getDirection();
                    viewer.getTable().setSortDirection(dir);
                    viewer.getTable().setSortColumn(column);
                    viewer.refresh();
                }
            };
            return selectionAdapter;
        }

    }

    private class FilesPage extends WizardPage implements SelectionListener {

        private SelectFile inputChooser;
        private SelectFile outputChooser;

        private FilesPage() {
            super("Input and Output File Page");
            setTitle("Abstract Weights Generator");
            setDescription("Generate the abtract weights from the hig-level profiling data");
        }

        @Override
        public void createControl(Composite parent) {
            final Composite container = new Composite(parent, SWT.NONE);
            GridLayout layout = new GridLayout();
            container.setLayout(layout);
            layout.numColumns = 1;

            GridData gd = new GridData(GridData.FILL_HORIZONTAL);
            inputChooser = new SelectFile(container, "Input", "Input File", new String[] { "*.tprof" }, SWT.SINGLE);
            inputChooser.setLayoutData(gd);
            inputChooser.setFile(inputFile);
            inputChooser.addSelectionListener(this);

            outputChooser = new SelectFile(container, "Output", "Output File", new String[] { "*.exdf" }, SWT.SAVE);
            outputChooser.setLayoutData(gd);
            outputChooser.addSelectionListener(this);

            setControl(container);

        }

        @Override
        public void widgetSelected(SelectionEvent e) {
            setPageComplete(isPageComplete());
        }

        @Override
        public void widgetDefaultSelected(SelectionEvent e) {
        }

        public boolean isPageComplete() {
            File input = getInput();
            File output = getOutput();
            return input != null && input.exists() && output != null && output.getParentFile().exists();
        }

        private File getInput() {
            return inputChooser.getFile();
        }

        private File getOutput() {
            return outputChooser.getFile();
        }

        public void configure(File inputFile) {
            if (inputChooser != null) {
                inputChooser.setFile(inputFile);
            }
        }

    }

    private FilesPage filesPage;
    private OperatorsCostPage costsPage;

    private File inputFile = null;

    public AbstractWeightsGeneratorWizard() {
        super();
        setNeedsProgressMonitor(true);
        filesPage = new FilesPage();
        costsPage = new OperatorsCostPage();
    }

    @Override
    public void addPages() {
        addPage(filesPage);
        addPage(costsPage);
    }

    @Override
    public void init(IWorkbench workbench, IStructuredSelection selection) {
        try {
            File file = TurnusUtils.getFrom((IFile) selection.getFirstElement());
            if (file != null) {
                if (TurnusUtils.getExtension(file).equals(TurnusExtension.PROFILING)) {
                    configure(file);
                }
            }

        } catch (TurnusException e) {
            e.printStackTrace();
        }

    }

    public void configure(File inputFile) {
        this.inputFile = inputFile;
        filesPage.configure(inputFile);
    }

    @Override
    public boolean performFinish() {
        try {

            EclipseHelper.openDefaultConsole();
            File input = filesPage.getInput();
            File output = filesPage.getOutput();
            Map<Operator, Double> costMap = costsPage.getOperatorsCostMap();

            ProfilingData data = EcoreHelper.loadEObject(new ResourceSetImpl(), input);

            ProfilingWeightsEstimator estimator = new ProfilingWeightsEstimator();
            estimator.setOperatorCosts(costMap);
            ProfilingWeights weights = estimator.estimate(data);
            new XmlProfilingWeightsWriter().write(output, weights);

            TurnusLogger.info("Abstract weights file exported in: " + output);
            return true;

        } catch (Exception e) {
            TurnusLogger.error(e.getMessage());
        }

        return false;
    }

}