Java tutorial
/* * 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(); } }