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.ui.editor; import static co.turnus.profiling.io.XmlProfilingWeightsMarkup.ACTION; import static co.turnus.profiling.io.XmlProfilingWeightsMarkup.ACTION_ID; import static co.turnus.profiling.io.XmlProfilingWeightsMarkup.ACTOR; import static co.turnus.profiling.io.XmlProfilingWeightsMarkup.ACTOR_ID; import static co.turnus.profiling.io.XmlProfilingWeightsMarkup.CLOCKCYCLES_MAX; import static co.turnus.profiling.io.XmlProfilingWeightsMarkup.CLOCKCYCLES_MEAN; import static co.turnus.profiling.io.XmlProfilingWeightsMarkup.CLOCKCYCLES_MIN; import static co.turnus.profiling.io.XmlProfilingWeightsMarkup.WORKLOAD; import java.util.Collection; import java.util.HashSet; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TreeViewer; 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.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.EditorPart; import org.eclipse.ui.part.FileEditorInput; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import co.turnus.TurnusExtension; import co.turnus.TurnusRuntimeException; import co.turnus.util.TurnusUtils; public class ProfilingWeightsEditor extends EditorPart { /** * 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 o1, Object o2) { Element e1 = (Element) o1; Element e2 = (Element) o2; int rc = 0; if (e1.getNodeName().equals(e2.getNodeName())) { if (e1.getNodeName().equals(ACTOR)) { switch (propertyIndex) { case T_ACTOR_ACTION: rc = e1.getAttribute(ACTOR_ID).compareTo(e2.getAttribute(ACTOR_ID)); break; case T_WORKLOAD: rc = e1.getAttribute(WORKLOAD).compareTo(e2.getAttribute(WORKLOAD)); break; default: break; } } else if (e1.getNodeName().equals(ACTION)) { switch (propertyIndex) { case T_ACTOR_ACTION: rc = e1.getAttribute(ACTION_ID).compareTo(e2.getAttribute(ACTION_ID)); break; case T_CLOCKCYCLES_MEAN: rc = e1.getAttribute(CLOCKCYCLES_MEAN).compareTo(e2.getAttribute(CLOCKCYCLES_MEAN)); break; case T_CLOCKCYCLES_MIN: rc = e1.getAttribute(CLOCKCYCLES_MIN).compareTo(e2.getAttribute(CLOCKCYCLES_MIN)); break; case T_CLOCKCYCLES_MAX: rc = e1.getAttribute(CLOCKCYCLES_MAX).compareTo(e2.getAttribute(CLOCKCYCLES_MAX)); break; case T_WORKLOAD: rc = e1.getAttribute(WORKLOAD).compareTo(e2.getAttribute(WORKLOAD)); break; default: break; } } } // 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; } } } /** * This class defines the content provider * * @author Simone Casale Brunet * */ private class ContentProvider implements ITreeContentProvider { @Override public void dispose() { } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @Override public Object[] getChildren(Object obj) { if (obj instanceof Element) { Element element = (Element) obj; if (element.getNodeName().equals(ACTOR)) { NodeList nList = element.getElementsByTagName(ACTION); Collection<Element> elements = new HashSet<Element>(); for (int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; elements.add(eElement); } } return elements.toArray(new Element[0]); } } return null; } @Override public Object getParent(Object obj) { return null; } @Override public boolean hasChildren(Object obj) { if (obj instanceof Element) { Element element = (Element) obj; return element.getNodeName().equals(ACTOR); } return false; } @Override public Object[] getElements(Object inputElement) { if (inputElement instanceof Document) { Document element = (Document) inputElement; NodeList nList = element.getElementsByTagName(ACTOR); Collection<Element> elements = new HashSet<Element>(); for (int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; elements.add(eElement); } } return elements.toArray(new Element[0]); } else if (inputElement instanceof Element) { Element element = (Element) inputElement; if (element.getNodeName().equals(ACTOR)) { NodeList nList = element.getElementsByTagName(ACTION); Collection<Element> elements = new HashSet<Element>(); for (int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; elements.add(eElement); } } return elements.toArray(new Element[0]); } } return new Object[0]; } } /** * This class defines the label provider for the Instances Mapping Tab * * @author Simone Casale Brunet * */ private class TreeLabelProvider extends LabelProvider implements ITableLabelProvider { @Override public Image getColumnImage(Object element, int columnIndex) { return null; } @Override public String getColumnText(Object obj, int columnIndex) { String result = ""; if (obj instanceof Element) { Element element = (Element) obj; if (element.getNodeName().equals(ACTOR)) { switch (columnIndex) { case T_ACTOR_ACTION: result = element.getAttribute(ACTOR_ID); break; case T_WORKLOAD: result = element.getAttribute(WORKLOAD); break; default: break; } } else if (element.getNodeName().equals(ACTION)) { switch (columnIndex) { case T_ACTOR_ACTION: result = element.getAttribute(ACTION_ID); break; case T_CLOCKCYCLES_MEAN: result = element.getAttribute(CLOCKCYCLES_MEAN); break; case T_CLOCKCYCLES_MIN: result = element.getAttribute(CLOCKCYCLES_MIN); break; case T_CLOCKCYCLES_MAX: result = element.getAttribute(CLOCKCYCLES_MAX); break; case T_WORKLOAD: result = element.getAttribute(WORKLOAD); break; default: break; } } } return result; } } public static final String ID = "co.turnus.ui.editor.profilingWeights"; private final int T_ACTOR_ACTION = 0; private final int T_CLOCKCYCLES_MEAN = 1; private final int T_CLOCKCYCLES_MIN = 2; private final int T_CLOCKCYCLES_MAX = 3; private final int T_WORKLOAD = 4; private Document document; private final String[] columnNames = new String[] { "Actor, Action", "CC (mean)", "CC (min)", "CC (max)", "Workload (%)" }; private Tree tree; private TreeViewer viewer; private ContentComparator comparator; @Override public void doSave(IProgressMonitor monitor) { // TODO Auto-generated method stub } @Override public void doSaveAs() { // TODO Auto-generated method stub } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { IFile file = null; if (input instanceof FileEditorInput) { file = ((FileEditorInput) input).getFile(); if (file.getFileExtension().equals(TurnusExtension.PROFILING_WEIGHTS)) { try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); document = dBuilder.parse(TurnusUtils.getFrom(file)); } catch (Exception e) { throw new TurnusRuntimeException("Input file is corrupted"); } } else { throw new TurnusRuntimeException("Invalid input"); } } setSite(site); setInput(input); setPartName(file.getName()); } @Override public boolean isDirty() { return false; } @Override public boolean isSaveAsAllowed() { return false; } @Override public void createPartControl(Composite parent) { tree = new Tree(parent, SWT.FILL); tree.setHeaderVisible(true); tree.setLinesVisible(true); viewer = new TreeViewer(tree); comparator = new ContentComparator(); viewer.setComparator(comparator); // Actor, Action TreeColumn column = new TreeColumn(tree, SWT.LEFT); column.setText(columnNames[T_ACTOR_ACTION]); column.setWidth(200); column.addSelectionListener(getSelectionAdapter(column, T_ACTOR_ACTION)); // Clock Cycles column = new TreeColumn(tree, SWT.LEFT); column.setText(columnNames[T_CLOCKCYCLES_MEAN]); column.setWidth(100); column.addSelectionListener(getSelectionAdapter(column, T_CLOCKCYCLES_MEAN)); column = new TreeColumn(tree, SWT.LEFT); column.setText(columnNames[T_CLOCKCYCLES_MIN]); column.setWidth(100); column.addSelectionListener(getSelectionAdapter(column, T_CLOCKCYCLES_MIN)); column = new TreeColumn(tree, SWT.LEFT); column.setText(columnNames[T_CLOCKCYCLES_MAX]); column.setWidth(100); column.addSelectionListener(getSelectionAdapter(column, T_CLOCKCYCLES_MAX)); // Workload column = new TreeColumn(tree, SWT.LEFT); column.setText(columnNames[T_WORKLOAD]); column.setWidth(200); column.addSelectionListener(getSelectionAdapter(column, T_WORKLOAD)); viewer.setContentProvider(new ContentProvider()); viewer.setLabelProvider(new TreeLabelProvider()); viewer.setInput(document); } /** * 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 TreeColumn column, final int index) { SelectionAdapter selectionAdapter = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { comparator.setColumn(index); int dir = comparator.getDirection(); viewer.getTree().setSortDirection(dir); viewer.getTree().setSortColumn(column); viewer.refresh(); } }; return selectionAdapter; } @Override public void setFocus() { if (tree != null) tree.setFocus(); } }