com.windowtester.eclipse.ui.viewers.EventSequenceDNDSupport.java Source code

Java tutorial

Introduction

Here is the source code for com.windowtester.eclipse.ui.viewers.EventSequenceDNDSupport.java

Source

/*******************************************************************************
 *  Copyright (c) 2012 Google, Inc.
 *  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:
 *  Google, Inc. - initial API and implementation
 *******************************************************************************/
package com.windowtester.eclipse.ui.viewers;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.texteditor.AbstractTextEditor;

import com.windowtester.codegen.assembly.unit.ImportUnit;
import com.windowtester.eclipse.ui.jdt.analysis.util.TypeHierarchyCache;
import com.windowtester.runtime.swing.UITestCaseSwing;
import com.windowtester.runtime.swt.UITestCaseSWT;
import com.windowtester.runtime.swt.internal.finder.eclipse.editors.EditorFinder;

@SuppressWarnings("restriction")
public class EventSequenceDNDSupport {

    //private static final String SNIPPET_TEST_NAME = "Snippet";
    public EventSequenceSnippetBuilder builder;

    private static class DragAdapter implements DragSourceListener {

        private static final String UICONTEXT_ACCESSOR = "getUI";
        private static final String[] UICONTEXT_ACCESSOR_PARAMS = null;
        private final EventSequenceTreeViewer viewer;
        private String generated;
        private StyledText editorWidget;
        private EventSequenceSnippetBuilder builder;
        private TypeHierarchyCache hierarchy = new TypeHierarchyCache();

        public DragAdapter(EventSequenceTreeViewer viewer) {
            this.viewer = viewer;
        }

        public void dragFinished(DragSourceEvent event) {

            try {
                doDragFinished(event);
            } catch (Throwable th) {
                th.printStackTrace();
                //ignore and move on
            }
        }

        private void doDragFinished(DragSourceEvent event) throws NoSuchMethodException, IllegalAccessException,
                InvocationTargetException, JavaModelException {

            if (!currentEditorSelectionMatchesDragContents())
                return;

            addImports();
            updateInsertedContentsIfNecessary();
            formatInsertedContents();

        }

        private void formatInsertedContents() {
            AbstractTextEditor editor = getTextEditor();
            if (editor == null)
                return;

            IAction action = editor.getAction("Format"); //NOTE: this action is registered in the Java editor
            if (action == null)
                return;
            action.run();
        }

        private void updateInsertedContentsIfNecessary()
                throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
            IJavaElement insertHost = getJavaElementAtInsertOffset();
            if (insertHost == null)
                return;

            if (insertHost instanceof IMethod) {
                insertMethodSnippet();
                return;
            }

            if (!hostProvidesContext())
                insertParameterizedMethod();

        }

        private void insertParameterizedMethod() {
            editorWidget.insert(builder.getParameterizedMethod());
        }

        private boolean hostProvidesContext() {
            ICompilationUnit cu = getCompilationUnit();
            IType primaryType = cu.findPrimaryType();
            ITypeHierarchy th = hierarchy.getTypeHierarchy(primaryType, primaryType.getJavaProject());
            IType[] types = th.getAllSupertypes(primaryType);
            for (int i = 0; i < types.length; i++) {
                IType type = types[i];
                //            try {
                //               IMethod[] methods = type.getMethods();
                //               for (int j = 0; j < methods.length; j++) {
                //                  if (methods[j].getElementName().equals(UICONTEXT_ACCESSOR))
                //                     return true;
                //               }
                //            } catch (JavaModelException e) {
                //               e.printStackTrace();
                //            }
                IMethod method = type.getMethod(UICONTEXT_ACCESSOR, UICONTEXT_ACCESSOR_PARAMS);
                //System.out.println("method: " + method + " exists: " + method.exists());

                if (method != null && method.exists())
                    return true;
            }
            return false;
        }

        private void insertMethodSnippet() {
            editorWidget.insert(builder.getMethodSnippet());
        }

        private void addImports() throws JavaModelException {
            ICompilationUnit cu = getCompilationUnit();
            if (cu == null)
                return;
            addImportsTo(cu);
        }

        private void addImportsTo(ICompilationUnit cu) throws JavaModelException {
            ImportUnit[] imports = builder.getImports();
            for (int i = 0; i < imports.length; i++) {
                if (skippedImport(imports[i]))
                    continue;
                cu.createImport(imports[i].getName(), null, null);
            }
        }

        private boolean skippedImport(ImportUnit importUnit) {
            String name = importUnit.getName();
            if (name == null)
                return true;
            if (name.equals(UITestCaseSWT.class.getName()))
                return true;
            if (name.equals(UITestCaseSwing.class.getName()))
                return true;
            return false;
        }

        private ICompilationUnit getCompilationUnit() {
            IJavaElement je = getEditorInputJavaElement();
            return getCompilationUnitFor(je);
        }

        private ICompilationUnit getCompilationUnitFor(IJavaElement je) {
            if (je == null)
                return null;
            if (je instanceof ICompilationUnit)
                return (ICompilationUnit) je;
            if (je instanceof IMember)
                return ((IMember) je).getCompilationUnit();
            return getCompilationUnitFor(je.getParent());
        }

        private IJavaElement getJavaElementAtInsertOffset()
                throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
            int offset = editorWidget.getCaretOffset();

            //System.out.println("widget offset: " + offset);

            ISourceViewer editorSourceViewer = getEditorSourceViewer();

            if (editorSourceViewer instanceof ITextViewerExtension5) {
                offset = ((ITextViewerExtension5) editorSourceViewer).widgetOffset2ModelOffset(offset);
                //System.out.println("model offset: " + offset);
            }

            //IJavaElement je = getEditorInputJavaElement();
            //System.out.println("editor element handle: " + je.getHandleIdentifier());

            Method m = JavaEditor.class.getDeclaredMethod("getElementAt", new Class[] { int.class });
            if (m == null)
                return null;
            m.setAccessible(true);
            AbstractTextEditor editor = getTextEditor();
            if (editor == null)
                return null;
            IJavaElement insertHost = (IJavaElement) m.invoke(editor, new Object[] { new Integer(offset) });
            return insertHost;
        }

        public ISourceViewer getEditorSourceViewer() {
            AbstractTextEditor editor = getTextEditor();
            if (editor == null)
                return null;
            Method m;
            try {
                m = JavaEditor.class.getDeclaredMethod("getViewer", (Class[]) null);
                if (m == null)
                    return null;
                m.setAccessible(true);
                return (ISourceViewer) m.invoke(editor, (Object[]) null);
            } catch (SecurityException e) {
            } catch (NoSuchMethodException e) {
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }
            return null;

        }

        private IJavaElement getEditorInputJavaElement() {
            AbstractTextEditor editor = getTextEditor();
            if (editor == null)
                return null;
            return JavaUI.getEditorInputJavaElement(editor.getEditorInput());
        }

        private boolean currentEditorSelectionMatchesDragContents() throws SecurityException,
                IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
            editorWidget = getCurrentEditorTextWidget();
            if (editorWidget == null)
                return false;
            String selectionText = editorWidget.getSelectionText();
            return matches(generated, selectionText);
        }

        private boolean matches(String expected, String actual) {
            if (expected == null || actual == null)
                return false;
            return expected.compareToIgnoreCase(actual) == 0;
        }

        private StyledText getCurrentEditorTextWidget() throws SecurityException, NoSuchMethodException,
                IllegalArgumentException, IllegalAccessException, InvocationTargetException {
            AbstractTextEditor textEditor = getTextEditor();
            if (textEditor == null)
                return null;
            Method method = AbstractTextEditor.class.getDeclaredMethod("getSourceViewer", (Class[]) null);
            method.setAccessible(true);
            ISourceViewer viewer = (ISourceViewer) method.invoke(textEditor, (Object[]) null);
            if (viewer == null)
                return null;
            return viewer.getTextWidget();
        }

        private AbstractTextEditor getTextEditor() {
            IEditorPart editor = EditorFinder.getActiveEditorPartNoRetries();
            if (!(editor instanceof AbstractTextEditor))
                return null;
            AbstractTextEditor textEditor = (AbstractTextEditor) editor;
            if (editor == null)
                return null;
            return textEditor;
        }

        public void dragSetData(DragSourceEvent event) {
            //System.out.println("set: " + event);
            try {
                builder = new EventSequenceSnippetBuilder(viewer.getSelection());
                generated = builder.getMainMethodString();
                event.data = generated;
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }

        public void dragStart(DragSourceEvent event) {
            event.doit = viewer.getSelection().length != 0;

        }

    }

    EventSequenceSnippetBuilder snippetBuilder;

    public static void addTo(EventSequenceTreeViewer viewer) {
        // int ops = DND.DROP_MOVE | DND.DROP_COPY;
        Transfer[] transfers = new Transfer[] { TextTransfer.getInstance() };
        // viewer.getTreeViewer().addDragSupport(ops, transfers, new DragAdapter
        // (viewer));
        //
        TreeViewer treeViewer = viewer.getTreeViewer();
        DragSource source = new DragSource(treeViewer.getControl(), DND.DROP_COPY);
        source.setTransfer(transfers);
        source.addDragListener(new DragAdapter(viewer));

    }

}