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.mapping.io.XmlFifosSizeMarkup.BXDF_DEFAULT_SIZE; import static co.turnus.mapping.io.XmlFifosSizeMarkup.BXDF_NETWORK; import static co.turnus.mapping.io.XmlFifosSizeMarkup.CONNECTION; import static co.turnus.mapping.io.XmlFifosSizeMarkup.CONNECTION_SIZE; import static co.turnus.mapping.io.XmlFifosSizeMarkup.CONNECTION_SRC_ACTOR; import static co.turnus.mapping.io.XmlFifosSizeMarkup.CONNECTION_SRC_PORT; import static co.turnus.mapping.io.XmlFifosSizeMarkup.CONNECTION_TGT_ACTOR; import static co.turnus.mapping.io.XmlFifosSizeMarkup.CONNECTION_TGT_PORT; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IProgressMonitor; 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.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; 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 BufferSizeEditor extends EditorPart { /** * 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 o, String property) { // Find the index of the column int columnIndex = Arrays.asList(columnNames).indexOf(property); Object result = ""; Element element = (Element) o; switch (columnIndex) { case SRC_ACTOR: result = element.getAttribute(CONNECTION_SRC_ACTOR); break; case SRC_PORT: result = element.getAttribute(CONNECTION_SRC_PORT); break; case TGT_ACTOR: result = element.getAttribute(CONNECTION_TGT_ACTOR); break; case TGT_PORT: result = element.getAttribute(CONNECTION_TGT_PORT); break; case SIZE: result = element.getAttribute(CONNECTION_SIZE); break; default: break; } return result; } @Override public void modify(Object o, 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) o; Element element = (Element) item.getData(); String oldValue = element.getAttribute(CONNECTION_SIZE); if (!oldValue.equals(intString)) { element.setAttribute(CONNECTION_SIZE, intString); setDirty(true); } viewer.refresh(); } } } } /** * This class defines the content provider * * @author Simone Casale Brunet * */ private class ContentProvider implements IStructuredContentProvider { @Override public void dispose() { } @Override public Object[] getElements(Object inputElement) { Collection<Element> elements = new ArrayList<Element>(); if (inputElement instanceof Document) { NodeList nList = ((Document) inputElement).getElementsByTagName(CONNECTION); for (int temp = 0; temp < nList.getLength(); temp++) { Node nNode = nList.item(temp); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; elements.add(eElement); } } return elements.toArray(new Element[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 o, int columnIndex) { String result = ""; Element element = (Element) o; switch (columnIndex) { case SRC_ACTOR: result = element.getAttribute(CONNECTION_SRC_ACTOR); break; case SRC_PORT: result = element.getAttribute(CONNECTION_SRC_PORT); break; case TGT_ACTOR: result = element.getAttribute(CONNECTION_TGT_ACTOR); break; case TGT_PORT: result = element.getAttribute(CONNECTION_TGT_PORT); break; case SIZE: result = element.getAttribute(CONNECTION_SIZE); 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 o1, Object o2) { Element e1 = (Element) o1; Element e2 = (Element) o2; int rc = 0; switch (propertyIndex) { case SRC_ACTOR: rc = e1.getAttribute(CONNECTION_SRC_ACTOR).compareTo(e2.getAttribute(CONNECTION_SRC_ACTOR)); break; case SRC_PORT: rc = e1.getAttribute(CONNECTION_SRC_PORT).compareTo(e2.getAttribute(CONNECTION_SRC_PORT)); break; case TGT_ACTOR: rc = e1.getAttribute(CONNECTION_TGT_ACTOR).compareTo(e2.getAttribute(CONNECTION_TGT_ACTOR)); break; case TGT_PORT: rc = e1.getAttribute(CONNECTION_TGT_PORT).compareTo(e2.getAttribute(CONNECTION_TGT_PORT)); break; case SIZE: rc = e1.getAttribute(CONNECTION_SIZE).compareTo(e2.getAttribute(CONNECTION_SIZE)); 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; } } } public static final String ID = "co.turnus.ui.editor.bufferSize"; 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 Spinner defaultSize; private boolean isDirty; private Document document; @Override public void doSave(IProgressMonitor monitor) { try { IFile file = ((FileEditorInput) getEditorInput()).getFile(); Transformer transformer = TransformerFactory.newInstance().newTransformer(); Result output = new StreamResult(TurnusUtils.getFrom(file)); Source input = new DOMSource(document); transformer.transform(input, output); setDirty(false); } catch (Exception e) { throw new TurnusRuntimeException("Output file corrupted"); } } @Override public void doSaveAs() { } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { IFile file = null; document = null; isDirty = false; if (input instanceof FileEditorInput) { file = ((FileEditorInput) input).getFile(); if (file.getFileExtension().equals(TurnusExtension.BUFFER_SIZE)) { 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 isSaveAsAllowed() { return false; } @Override public void createPartControl(Composite parent) { GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 1; parent.setLayout(gridLayout); String network = document.getDocumentElement().getAttribute(BXDF_NETWORK); Label lbl = new Label(parent, SWT.NONE); lbl.setFont(parent.getFont()); lbl.setText("Buffer size configuration for the network: \"" + network + "\""); lbl.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(2, false)); lbl = new Label(composite, SWT.NONE); lbl.setFont(parent.getFont()); lbl.setText("Default buffer size: "); lbl.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); int size = Integer.parseInt(document.getDocumentElement().getAttribute(BXDF_DEFAULT_SIZE)); defaultSize = new Spinner(composite, SWT.NONE); defaultSize.setMinimum(0); defaultSize.setMaximum(Integer.MAX_VALUE); defaultSize.setIncrement(1); defaultSize.setSelection(size); defaultSize.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { document.getDocumentElement().setAttribute(BXDF_DEFAULT_SIZE, defaultSize.getText()); setDirty(true); } }); table = new Table(parent, 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()); 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 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 void setFocus() { if (table != null) table.setFocus(); } private void setDirty(boolean value) { isDirty = value; firePropertyChange(IEditorPart.PROP_DIRTY); } @Override public boolean isDirty() { return isDirty; } }