co.turnus.analysis.profiler.orcc.ui.widget.BufferSizeTableWidget.java Source code

Java tutorial

Introduction

Here is the source code for co.turnus.analysis.profiler.orcc.ui.widget.BufferSizeTableWidget.java

Source

/* 
 * TURNUS, the co-exploration framework
 * 
 * Copyright (C) 2014 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.analysis.profiler.orcc.ui.widget;

import static co.turnus.analysis.profiler.orcc.dynamic.OrccDynamicProfilerOptions.ORCC_FIFO_MAPPING;
import static co.turnus.analysis.profiler.orcc.dynamic.OrccDynamicProfilerOptions.ORCC_PROJECT;
import static co.turnus.analysis.profiler.orcc.dynamic.OrccDynamicProfilerOptions.ORCC_XDF;

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

import net.sf.orcc.df.Actor;
import net.sf.orcc.df.Connection;
import net.sf.orcc.df.Network;
import net.sf.orcc.df.Port;
import net.sf.orcc.df.transform.Instantiator;
import net.sf.orcc.df.transform.NetworkFlattener;
import net.sf.orcc.graph.Vertex;
import net.sf.orcc.ir.ExprInt;
import net.sf.orcc.util.Attribute;
import net.sf.orcc.util.util.EcoreHelper;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.emf.ecore.resource.ResourceSet;
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.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.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.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

import co.turnus.analysis.profiler.orcc.util.OrccFifoMapping;
import co.turnus.widgets.AbstractWidget;
import co.turnus.widgets.launchconfiguration.AbstractLaunchTab;
import co.turnus.widgets.launchconfiguration.ILaunchWidget;

public class BufferSizeTableWidget extends AbstractWidget<Map<String, String>, AbstractLaunchTab>
        implements ILaunchWidget<Map<String, String>> {

    /**
     * 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[SIZE]);
        }

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

            Object result = "";
            Connection fifo = (Connection) element;

            switch (columnIndex) {
            case SRC_ACTOR:
                result = ((Actor) fifo.getSource()).getName();
                break;
            case SRC_PORT:
                result = ((Port) fifo.getSourcePort()).getName();
                break;
            case TGT_ACTOR:
                result = ((Actor) fifo.getTarget()).getName();
                break;
            case TGT_PORT:
                result = ((Port) fifo.getTargetPort()).getName();
                break;
            case SIZE:
                if (isMapped(fifo)) {
                    result = getSize(fifo);
                }
                break;
            default:
                break;

            }

            return result;
        }

        @Override
        public void modify(Object element, String property, Object value) {
            // int columnIndex = Arrays.asList(columnNames).indexOf(property);
            if (property.equals(columnNames[SIZE])) {
                String intString = (String) value;
                if (intString.matches("[+]?\\d+")) {
                    TableItem item = (TableItem) element;
                    Connection fifo = (Connection) item.getData();
                    setSize(fifo, intString);
                    // FIXME to enable the apply button make a new map copy
                    setValue(new HashMap<String, String>(mapping), true);
                    viewer.refresh();
                    updateLaunchConfigurationDialog();
                }
            }

        }

    }

    /**
     * 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<Connection>) inputElement).toArray(new Connection[0]);
            } else {
                return new Object[0];
            }
        }

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

    /**
     * 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 = "";
            Connection fifo = (Connection) element;
            switch (columnIndex) {
            case SRC_ACTOR:
                result = ((Actor) fifo.getSource()).getName();
                break;
            case SRC_PORT:
                result = ((Port) fifo.getSourcePort()).getName();
                break;
            case TGT_ACTOR:
                result = ((Actor) fifo.getTarget()).getName();
                break;
            case TGT_PORT:
                result = ((Port) fifo.getTargetPort()).getName();
                break;
            case SIZE:
                if (isMapped(fifo)) {
                    result = getSize(fifo);
                }
                break;
            default:
                break;
            }
            return result;
        }
    }

    /**
     * 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) {
            Connection f1 = (Connection) e1;
            Connection f2 = (Connection) e2;
            int rc = 0;
            switch (propertyIndex) {
            case SRC_ACTOR:
                rc = ((Actor) f1.getSource()).getName().compareTo(((Actor) f2.getSource()).getName());
                break;
            case SRC_PORT:
                rc = ((Port) f1.getSourcePort()).getName().compareTo(((Port) f2.getSourcePort()).getName());
                break;
            case TGT_ACTOR:
                rc = ((Actor) f1.getTarget()).getName().compareTo(((Actor) f2.getTarget()).getName());
                break;
            case TGT_PORT:
                rc = ((Port) f1.getTargetPort()).getName().compareTo(((Port) f2.getTargetPort()).getName());
                break;
            case SIZE:
                int size1 = isMapped(f1) ? Integer.parseInt(getSize(f1)) : 0;
                int size2 = isMapped(f2) ? Integer.parseInt(getSize(f2)) : 0;
                rc = size1 - size2;
                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 class RealoadXdfBuffonListener implements SelectionListener {

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

        @Override
        public void widgetDefaultSelected(SelectionEvent e) {
        }

    }

    private class ClearButtonListener implements SelectionListener {

        @Override
        public void widgetSelected(SelectionEvent e) {
            setValue(new HashMap<String, String>(), true);
            viewer.refresh();
            updateLaunchConfigurationDialog();
        }

        @Override
        public void widgetDefaultSelected(SelectionEvent e) {
        }

    }

    private static final String LOADED_CONFIGURATION = "co.turnus.profiler.orcc.sim.ui.orcc.bufferSize.widget.configuration";

    private final int SRC_ACTOR = 0;
    private final int SRC_PORT = 1;
    private final int TGT_ACTOR = 2;
    private final int TGT_PORT = 3;
    private final int SIZE = 4;

    /** the columns names */
    private final String[] columnNames = new String[] { "Src Actor", "Src Port", "Tgt Actor", "Tgt Port",
            "Size (tokens)" };

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

    private String config = "";

    private Map<String, String> mapping;
    private Collection<Connection> connections;

    public BufferSizeTableWidget(Composite parent, AbstractLaunchTab owner) {
        super(ORCC_FIFO_MAPPING, "Buffer Size Mapping Table", "Define the buffer size for each connection",
                new HashMap<String, String>(), 1, parent, owner);

        Label lbl = new Label(getComposite(), SWT.NONE);
        lbl.setFont(getFont());
        lbl.setText("Custum FIFO connections buffer size:");
        lbl.setToolTipText(toolTip);
        lbl.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));

        mapping = getValue();
        connections = new HashSet<Connection>();

        table = new Table(getComposite(), SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
        viewer = new TableViewer(table);
        comparator = new ContentComparator();
        viewer.setComparator(comparator);

        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);

        // column: source actor
        TableColumn column = new TableColumn(table, SWT.LEFT, SRC_ACTOR);
        column.setText(columnNames[SRC_ACTOR]);
        column.setWidth(100);
        column.addSelectionListener(getSelectionAdapter(column, SRC_ACTOR));

        // column: source port
        column = new TableColumn(table, SWT.LEFT, SRC_PORT);
        column.setText(columnNames[SRC_PORT]);
        column.setWidth(100);
        column.addSelectionListener(getSelectionAdapter(column, SRC_PORT));

        // column: target actor
        column = new TableColumn(table, SWT.LEFT, TGT_ACTOR);
        column.setText(columnNames[TGT_ACTOR]);
        column.setWidth(100);
        column.addSelectionListener(getSelectionAdapter(column, TGT_ACTOR));

        // column: target port
        column = new TableColumn(table, SWT.LEFT, TGT_PORT);
        column.setText(columnNames[TGT_PORT]);
        column.setWidth(100);
        column.addSelectionListener(getSelectionAdapter(column, TGT_PORT));

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

        // 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[SIZE] = new TextCellEditor(table);
        // set the editors
        viewer.setCellEditors(editors);
        viewer.setCellModifier(new CellModifier());

        // reload from XDF and clear mapping buttons
        Composite composite = new Composite(getComposite(), SWT.SHADOW_NONE);
        composite.setLayout(new GridLayout(2, false));
        composite.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));

        Button realodXdfMappingButton = new Button(composite, SWT.PUSH);
        realodXdfMappingButton.setFont(getFont());
        realodXdfMappingButton.setLayoutData(new GridData(SWT.BORDER, SWT.CENTER, false, false));
        realodXdfMappingButton.setText("Reload from XDF");
        realodXdfMappingButton.addSelectionListener(new RealoadXdfBuffonListener());

        Button clearButton = new Button(composite, SWT.PUSH);
        clearButton.setFont(getFont());
        clearButton.setLayoutData(new GridData(SWT.BORDER, SWT.CENTER, false, false));
        clearButton.setText("Clear All");
        clearButton.addSelectionListener(new ClearButtonListener());
    }

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

    @Override
    public boolean isValid() {
        return true;
    }

    @Override
    public void redraw() {
    }

    @Override
    public void initializeFrom(ILaunchConfiguration configuration) throws CoreException {
        show(true);
        setValue(configuration.getAttribute(getId(), getValue()), true);

        String newProject = configuration.getAttribute(ORCC_PROJECT, "");
        String newXdf = configuration.getAttribute(ORCC_XDF, "");
        loadConnections(newProject, newXdf);
        viewer.setInput(connections);

        updateLaunchConfigurationDialog();

    }

    public void setValue(Map<String, String> value, boolean redraw) {
        super.setValue(value, redraw);
        mapping = value;
    }

    @Override
    public void performApply(ILaunchConfigurationWorkingCopy configuration) {
        try {
            {// check if a new table must be created
                String newProject = configuration.getAttribute(ORCC_PROJECT, "");
                String newXdf = configuration.getAttribute(ORCC_XDF, "");
                String newConfig = configStamp(newProject, newXdf);

                config = configuration.getAttribute(LOADED_CONFIGURATION, "");

                if (!newConfig.equals(config)) {
                    config = newConfig;
                    configuration.setAttribute(LOADED_CONFIGURATION, config);
                    loadConnections(newProject, newXdf);
                    loadXdfMapping();
                    viewer.setInput(connections);
                }
            }

            configuration.setAttribute(getId(), getValue());

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

    }

    private void loadXdfMapping() {
        mapping = new HashMap<String, String>();
        for (Connection connection : connections) {
            Attribute attribute = connection.getAttribute("bufferSize");
            if (attribute != null) {
                int size = ((ExprInt) attribute.getContainedValue()).getIntValue();
                setSize(connection, Integer.toString(size));
            }
        }
        setValue(mapping, false);

    }

    private void loadConnections(String project, String xdf) {
        connections.clear();

        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        if (!root.getFullPath().isValidSegment(project)) {
            return;
        }

        IProject iproject = root.getProject(project);
        if (!iproject.exists()) {
            return;
        }

        IFile ixdf = iproject.getFile(xdf);
        if (!ixdf.exists()) {
            return;
        }

        ResourceSet set = new ResourceSetImpl();
        Network network = EcoreHelper.getEObject(set, ixdf);
        new Instantiator(true).doSwitch(network);
        new NetworkFlattener().doSwitch(network);

        // parse fifos
        for (Connection fifo : network.getConnections()) {
            Vertex srcVertex = fifo.getSource();
            Vertex tgtVertex = fifo.getTarget();
            if (srcVertex instanceof net.sf.orcc.df.Actor && tgtVertex instanceof net.sf.orcc.df.Actor) {
                // get the communication end-points
                Port srcPort = fifo.getSourcePort();
                Port tgtPort = fifo.getTargetPort();

                // get source and target actors
                if ((srcPort != null) && (tgtPort != null)) {
                    connections.add(fifo);
                }
            }
        }

    }

    private boolean setSize(Connection fifo, String size) {
        if (size.matches("[+]?\\d+")) {
            String strFifo = OrccFifoMapping.getKey(fifo);
            mapping.put(strFifo, size);
            return true;
        } else {
            return false;
        }
    }

    private String getSize(Connection fifo) {
        String strFifo = OrccFifoMapping.getKey(fifo);
        return mapping.get(strFifo);
    }

    private boolean isMapped(Connection fifo) {
        String strFifo = OrccFifoMapping.getKey(fifo);
        return mapping.containsKey(strFifo);
    }

    private static String configStamp(String project, String xdf) {
        return project + xdf;
    }

    @Override
    public void updateLaunchConfigurationDialog() {
        getOwner().updateLaunchConfigurationDialog();
    }

}