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