co.turnus.ui.editor.BufferSizeEditor.java Source code

Java tutorial

Introduction

Here is the source code for co.turnus.ui.editor.BufferSizeEditor.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.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;
    }

}