ch.hsr.ifs.cutelauncher.ui.TestViewer.java Source code

Java tutorial

Introduction

Here is the source code for ch.hsr.ifs.cutelauncher.ui.TestViewer.java

Source

/*******************************************************************************
 * Copyright (c) 2007 Institute for Software, HSR Hochschule fr Technik
 * Rapperswil, University of applied sciences
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 * Emanuel Graf - initial API and implementation
 ******************************************************************************/
package ch.hsr.ifs.cutelauncher.ui;

import java.util.AbstractList;
import java.util.ListIterator;
import java.util.Vector;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.progress.UIJob;

import ch.hsr.ifs.cutelauncher.CuteLauncherPlugin;
import ch.hsr.ifs.cutelauncher.model.ISessionListener;
import ch.hsr.ifs.cutelauncher.model.ITestComposite;
import ch.hsr.ifs.cutelauncher.model.ITestCompositeListener;
import ch.hsr.ifs.cutelauncher.model.ITestElementListener;
import ch.hsr.ifs.cutelauncher.model.NotifyEvent;
import ch.hsr.ifs.cutelauncher.model.TestCase;
import ch.hsr.ifs.cutelauncher.model.TestElement;
import ch.hsr.ifs.cutelauncher.model.TestSession;
import ch.hsr.ifs.cutelauncher.model.TestStatus;
import ch.hsr.ifs.cutelauncher.model.TestSuite;

public class TestViewer extends Composite
        implements ITestElementListener, ISessionListener, ITestCompositeListener {

    private final class UpdateTestElement extends UIJob {
        private UpdateTestElement(String name, TestElement element, boolean reveal) {
            super(name);
            this.element = element;
            this.reveal = reveal;
        }

        private TestElement element;
        private boolean reveal;

        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {
            treeViewer.refresh(element, true);
            if (reveal && viewPart.isAutoScroll()) {
                treeViewer.reveal(element);
            }
            return new Status(IStatus.OK, CuteLauncherPlugin.PLUGIN_ID, IStatus.OK, "OK", null);
        }
    }

    private final class ShowNewTest extends UIJob {
        private ShowNewTest(String name, ITestComposite composite, TestElement newElement) {
            super(name);
            this.parent = composite;
            this.element = newElement;
        }

        private ITestComposite parent;
        private TestElement element;

        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {
            treeViewer.refresh(parent, true);
            if (viewPart.isAutoScroll()) {
                treeViewer.reveal(element);
            }
            return new Status(IStatus.OK, CuteLauncherPlugin.PLUGIN_ID, IStatus.OK, "OK", null);
        }
    }

    private class TestResultViewer extends StyledText {
        private class TestResultDClickListener extends MouseAdapter {

            @Override
            public void mouseDoubleClick(MouseEvent e) {
                TestCase test = getTreeSelection();
                if (test != null) {
                    CuteCompareResultAction action = new CuteCompareResultAction(test, TestViewer.this.getShell());
                    action.run();
                }
            }

        }

        TestCase test;

        public TestResultViewer(Composite parent, int style) {
            super(parent, style);
            addMouseListener(new TestResultDClickListener());
        }

        public void showTestDetail(TestElement test) {
            if (test instanceof TestCase) {
                TestCase tCase = (TestCase) test;
                this.test = tCase;
                testResultViewer.setText(tCase.getMessage());
                redraw();
            } else if (test instanceof TestSuite) {
                testResultViewer.setText("");
                redraw();
            }
        }

    }

    private final class FailuresOnlyFilter extends ViewerFilter {

        @Override
        public boolean select(Viewer viewer, Object parentElement, Object element) {
            if (element instanceof TestElement) {
                TestElement testElement = (TestElement) element;
                switch (testElement.getStatus()) {
                case running:
                case error:
                case failure:
                    return true;
                default:
                    return false;
                }
            } else {
                return true;
            }
        }

    }

    private final class ReverseVector<T> extends Vector<T> {

        private static final long serialVersionUID = -7493342763899946849L;

        private Vector<? extends T> vec;

        public ReverseVector(Vector<? extends T> vec) {
            this.vec = vec;
        }

        @Override
        public synchronized T get(int index) {
            return vec.get(vec.size() - index - 1);
        }

        @Override
        public synchronized int size() {
            return vec.size();
        }

    }

    private SashForm sashForm = null;
    private TreeViewer treeViewer = null;
    private TestResultViewer testResultViewer = null;

    private TestSession session;
    private Vector<TestElement> elemets = new Vector<TestElement>();

    private TestRunnerViewPart viewPart;

    private boolean failureOnly = false;
    private FailuresOnlyFilter failuresOnlyFilter = new FailuresOnlyFilter();
    private CuteTestDClickListener cuteTestDClickListener;;

    public TestViewer(Composite parent, int style, TestRunnerViewPart viewPart) {
        super(parent, style);
        this.viewPart = viewPart;
        CuteLauncherPlugin.getModel().addListener(this);
        initialize();
        addDisposeListener(new DisposeListener() {

            public void widgetDisposed(DisposeEvent e) {
                CuteLauncherPlugin.getModel().removeListener(TestViewer.this);
            }
        });
    }

    public void reset(TestSession session) {
        testResultViewer.setText("");
        treeViewer.setInput(session);
    }

    public void showTestDetails(TestElement testElement) {
        testResultViewer.showTestDetail(testElement);
    }

    private void initialize() {
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 2;
        gridLayout.marginWidth = 0;
        gridLayout.horizontalSpacing = 0;
        gridLayout.marginWidth = 1;
        gridLayout.marginHeight = 0;
        createSashForm();
        this.setLayout(gridLayout);
        //      setSize(new Point(300, 200));
    }

    /**
     * This method initializes sashForm
     *
     */
    private void createSashForm() {
        sashForm = new SashForm(this, SWT.HORIZONTAL);
        sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
        treeViewer = new TreeViewer(sashForm, SWT.FLAT);
        treeViewer.setContentProvider(new CuteTestTreeContentProvieder());
        treeViewer.setLabelProvider(new CuteTestLabelProvider());
        treeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
        treeViewer.addSelectionChangedListener(new CuteTestSelecetionListener(this));
        cuteTestDClickListener = new CuteTestDClickListener(session);
        treeViewer.addDoubleClickListener(cuteTestDClickListener);
        testResultViewer = new TestResultViewer(sashForm, SWT.FLAT);
        testResultViewer.setEditable(false);
        testResultViewer.setIndent(5);
    }

    public void modelCanged(TestElement source, NotifyEvent event) {
        UIJob job = null;
        switch (event.getType()) {
        case suiteFinished:
            job = new UpdateTestElement("Show new Test", event.getElement(), false);
            break;
        case testFinished:
            job = new UpdateTestElement("Update Test", event.getElement(), true);
            break;
        }

        if (job != null) {
            job.schedule();
        }
    }

    public void sessionStarted(TestSession session) {
        this.session = session;
        session.addListener(this);
        cuteTestDClickListener.setSession(session);
        UIJob job = new UIJob("Reset TestViewer") {

            @Override
            public boolean belongsTo(Object family) {
                return CuteLauncherPlugin.PLUGIN_ID.equals(family);
            }

            @Override
            public IStatus runInUIThread(IProgressMonitor monitor) {
                reset(TestViewer.this.session);
                return new Status(IStatus.OK, CuteLauncherPlugin.PLUGIN_ID, IStatus.OK, "OK", null);
            }

        };
        job.schedule();
    }

    public void sessionFinished(TestSession session) {

    }

    public void setFailuresOnly(boolean failureOnly) {
        this.failureOnly = failureOnly;
        updateFilters();
    }

    private void updateFilters() {
        if (failureOnly) {
            treeViewer.addFilter(failuresOnlyFilter);
        } else {
            treeViewer.removeFilter(failuresOnlyFilter);
        }
    }

    public void selectNextFailure() {
        if (getSession().hasErrorOrFailure()) {
            Object firstElement = getSelectedElement();
            if (firstElement instanceof TestCase) {
                TestCase tCase = (TestCase) firstElement;
                treeViewer.setSelection(new StructuredSelection(findNextFailure(tCase)), true);
            } else {
                treeViewer.setSelection(new StructuredSelection(findFirstFailure()));
            }

        }
    }

    private Object getSelectedElement() {
        StructuredSelection selection = (StructuredSelection) treeViewer.getSelection();
        Object firstElement = selection.getFirstElement();
        return firstElement;
    }

    protected TestCase getTreeSelection() {
        ISelection sel = treeViewer.getSelection();
        if (sel instanceof TreeSelection) {
            TreeSelection treeSel = (TreeSelection) sel;
            if (treeSel.getFirstElement() instanceof TestCase) {
                TestCase testCase = (TestCase) treeSel.getFirstElement();
                return testCase;
            }
        }
        return null;
    }

    public void selectFirstFailure() {
        treeViewer.setSelection(new StructuredSelection(findFirstFailure()), true);
    }

    private TestElement findFirstFailure() {
        Vector<TestElement> elements = getSession().getElements();
        for (TestElement element : elements) {
            if (element.getStatus() == TestStatus.failure || element.getStatus() == TestStatus.error) {
                if (element instanceof ITestComposite) {
                    ITestComposite composite = (ITestComposite) element;
                    return findNextChildFailure(composite, false);
                } else {
                    return element;
                }
            }
        }
        return null;
    }

    private TestSession getSession() {
        if (session == null) {
            session = CuteLauncherPlugin.getModel().getSession();
        }
        return session;
    }

    private TestElement findNextChildFailure(ITestComposite composite, boolean revese) {
        Vector<? extends TestElement> elements = composite.getElements();
        if (revese) {
            elements = new ReverseVector<TestElement>(elements);
        }
        for (TestElement element : elements) {
            if (element.getStatus() == TestStatus.failure || element.getStatus() == TestStatus.error) {
                if (element instanceof ITestComposite) {
                    ITestComposite newComposite = (ITestComposite) element;
                    return findNextChildFailure(newComposite, false);
                } else {
                    return element;
                }
            }
        }
        return null;
    }

    private TestElement findNextFailure(TestCase selected) {
        TestElement nextFailure = findNextSiblingFailure(selected, false);
        if (nextFailure != null) {
            return nextFailure;
        } else {
            return findNextFailureInParent(selected.getParent(), selected, false);
        }
    }

    private TestElement findNextFailureInParent(ITestComposite current, TestCase selected, boolean reverse) {
        if (current instanceof TestElement) {
            TestElement tElement = (TestElement) current;
            TestElement nextFailure = findNextSiblingFailure(tElement, reverse);
            if (nextFailure != null) {
                return nextFailure;
            } else {
                return findNextFailureInParent(tElement.getParent(), selected, reverse);
            }
        } else {
            return selected;
        }
    }

    private TestElement findNextSiblingFailure(TestElement tElement, boolean reverse) {
        Vector<? extends TestElement> tests = tElement.getParent().getElements();
        int index = tests.indexOf(tElement) + 1;
        if (reverse) {
            tests = new ReverseVector<TestElement>(tests);
            index = tests.size() - index + 1;
        }
        ListIterator<? extends TestElement> it = ((AbstractList<? extends TestElement>) tests).listIterator(index);
        TestElement nextFailure;
        while (it.hasNext()) {
            nextFailure = it.next();
            if (nextFailure.getStatus() == TestStatus.failure || nextFailure.getStatus() == TestStatus.error) {
                if (nextFailure instanceof ITestComposite) {
                    ITestComposite composite = (ITestComposite) nextFailure;
                    return findNextChildFailure(composite, reverse);
                } else {
                    return nextFailure;
                }
            }
        }
        return null;
    }

    protected void setOrientation(boolean horizontal) {
        if ((sashForm == null) || sashForm.isDisposed())
            return;
        sashForm.setOrientation(horizontal ? SWT.HORIZONTAL : SWT.VERTICAL);
    }

    public void selectPrevFailure() {
        if (getSession().hasErrorOrFailure()) {
            Object firstElement = getSelectedElement();
            if (firstElement instanceof TestCase) {
                TestCase tCase = (TestCase) firstElement;
                treeViewer.setSelection(new StructuredSelection(findPrevFailure(tCase)), true);
            } else { //show first Failure
                treeViewer.setSelection(new StructuredSelection(findFirstFailure()), true);
            }
        }
    }

    private TestElement findPrevFailure(TestCase selected) {
        TestElement nextFailure = findNextSiblingFailure(selected, true);
        if (nextFailure != null) {
            return nextFailure;
        } else {
            return findNextFailureInParent(selected.getParent(), selected, true);
        }
    }

    public void newTestElement(ITestComposite source, TestElement newElement) {
        newElement.addTestElementListener(this);
        if (newElement instanceof ITestComposite) {
            ITestComposite composite = (ITestComposite) newElement;
            composite.addListener(this);
        }
        elemets.add(newElement);
        UIJob job = new ShowNewTest("Show new Test", newElement.getParent(), newElement);
        job.schedule();
    }

}