com.motorola.studio.android.generatemenucode.ui.GenerateMenuCodeHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.motorola.studio.android.generatemenucode.ui.GenerateMenuCodeHandler.java

Source

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.motorola.studio.android.generatemenucode.ui;

import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.texteditor.ITextEditor;

import com.motorola.studio.android.codeutils.CodeUtilsActivator;
import com.motorola.studio.android.codeutils.i18n.CodeUtilsNLS;
import com.motorola.studio.android.common.log.StudioLogger;
import com.motorola.studio.android.common.log.UsageDataConstants;
import com.motorola.studio.android.common.utilities.EclipseUtils;
import com.motorola.studio.android.generatecode.JDTUtils;
import com.motorola.studio.android.generatemenucode.model.codegenerators.JavaModifierBasedOnMenu;
import com.motorola.studio.android.generateviewbylayout.ui.AbstractCodeGeneratorHandler;

/**
 * Command handler to start code generation based on menu
 */
public class GenerateMenuCodeHandler extends AbstractHandler implements IHandler {

    private static final String WIZARD_IMAGE_PATH = "icons/wizban/fill_activity_ban.png"; //$NON-NLS-1$

    /**
     * Open {@link GenerateMenuCodeDialog} and use {@link JavaModifierBasedOnMenu} to insert code into Android source code (Activity/Fragment).
     */
    public Object execute(ExecutionEvent event) throws ExecutionException {
        SelectionBean selectionBean = resolveSelection(event);

        if (selectionBean.isProject() || selectionBean.isAllowedClassInstance()) {

            final IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);

            GenerateMenuCodeDialog menuDialog = new GenerateMenuCodeDialog(window.getShell(),
                    CodeUtilsNLS.GenerateMenuCodeDialog_DefaultMessage, CodeUtilsNLS.GenerateMenuCodeDialog_Title,
                    CodeUtilsNLS.GenerateMenuCodeDialog_ShellTitle,
                    CodeUtilsActivator.getImageDescriptor(WIZARD_IMAGE_PATH).createImage());

            final JavaModifierBasedOnMenu modifier = new JavaModifierBasedOnMenu();
            menuDialog.init(modifier, selectionBean.getJavaProject(), selectionBean.getJavaFile());

            int status = menuDialog.open();
            if (status == Window.OK) {
                ICompilationUnit compilationUnit = menuDialog.getJavaFile();
                IEditorPart editor = null;
                try {
                    editor = JavaUI.openInEditor(compilationUnit);
                } catch (Exception e) {
                    StudioLogger.warn(GenerateMenuCodeHandler.class,
                            "Unable to open editor or bring it to front for Java file while trying to generate menu code based on xml file", //$NON-NLS-1$
                            e);
                }
                final ProgressMonitorDialog dialog = new ProgressMonitorDialog(menuDialog.getShell());
                final IEditorPart editorPart = editor;

                PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

                    public void run() {
                        try {

                            dialog.run(true, false, new IRunnableWithProgress() {

                                public void run(IProgressMonitor monitor)
                                        throws InvocationTargetException, InterruptedException {
                                    try {
                                        // collect usage data - UDC
                                        StudioLogger.collectUsageData(UsageDataConstants.WHAT_VIEW_BY_MENU_EXEC,
                                                UsageDataConstants.KIND_VIEW_BY_MENU_EXEC,
                                                "View by menu feature executed.", //$NON-NLS-1$
                                                CodeUtilsActivator.PLUGIN_ID, CodeUtilsActivator.getDefault()
                                                        .getBundle().getVersion().toString());
                                        modifier.insertCode(monitor, editorPart);
                                    } catch (final JavaModelException e) {
                                        final MultiStatus errorStatus = new MultiStatus(
                                                CodeUtilsActivator.PLUGIN_ID, IStatus.ERROR,
                                                "Error inserting code on activity/fragment based on menu", //$NON-NLS-1$
                                                null);
                                        errorStatus.merge(e.getStatus());

                                        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

                                            public void run() {
                                                IStatus mostSevere = EclipseUtils.findMostSevereError(errorStatus);
                                                ErrorDialog.openError(
                                                        PlatformUI.getWorkbench().getDisplay().getActiveShell(),
                                                        "Error inserting code on activity/fragment based on menu", //$NON-NLS-1$
                                                        e.getMessage(), mostSevere);
                                            }
                                        });
                                        StudioLogger.error(this.getClass(),
                                                "Error inserting code on activity/fragment based on menu" //$NON-NLS-1$
                                                        + ": " + e.getMessage()); //$NON-NLS-1$
                                    }
                                }
                            });
                        } catch (Exception e) {
                            StudioLogger.error(this.getClass(),
                                    "Error inserting code on activity/fragment based on menu" //$NON-NLS-1$
                                            + ": " + e.getMessage()); //$NON-NLS-1$
                        }
                    }
                });
            }
        } else {
            EclipseUtils.showErrorDialog(CodeUtilsNLS.GenerateMenuCodeDialog_Title,
                    CodeUtilsNLS.GenerateMenuCodeHandler_SelectedClassNeitherActivityFragment);//GenerateMenuCodeHandler_SelectedClassNeitherActivityFragment
        }

        return null;
    }

    protected static SelectionBean resolveSelection(ExecutionEvent event) throws ExecutionException {
        SelectionBean selectionBean = new SelectionBean();
        ITextEditor editor = null;
        IFileEditorInput fileEditorInput = null;

        ISelection selection = HandlerUtil.getCurrentSelection(event);

        // case where the selection comes from the Text Editor
        if (selection instanceof TextSelection) {
            editor = (ITextEditor) HandlerUtil.getActiveEditorChecked(event);
            if (editor.getEditorInput() instanceof IFileEditorInput) {
                fileEditorInput = (IFileEditorInput) editor.getEditorInput();
                selectionBean.setJavaFile(fileEditorInput.getFile());
            }
        } else if (selection instanceof IStructuredSelection) {
            Iterator<?> selectionIterator = ((IStructuredSelection) selection).iterator();
            Object selectedObject = selectionIterator.next();

            // case where the selection comes from the package explorer
            if (selectedObject instanceof IFile) {
                selectionBean.setJavaFile((IFile) selectedObject);
            }

            // again, case where the selection comes from the package explorer
            else if (selectedObject instanceof ICompilationUnit) {
                ICompilationUnit compilationUnit = (ICompilationUnit) selectedObject;
                selectionBean.setJavaFile((IFile) compilationUnit.getResource());
            }

            // case where the selection comes from a project
            else if (selectedObject instanceof IAdaptable) {
                try {
                    IResource resource = (IResource) ((IAdaptable) selectedObject).getAdapter(IResource.class);
                    selectionBean.setJavaProject(resource.getProject());
                    selectionBean.setProject(true);
                } catch (Exception ex) {
                    StudioLogger.error(AbstractCodeGeneratorHandler.class, "Error retrieving class information", //$NON-NLS-1$
                            ex);
                    throw new RuntimeException(
                            CodeUtilsNLS.GenerateMenuCodeHandler_Error_CannotRetrieveClassInformation, ex);
                }
            }
        }

        // just check classes in case classes were selected, not project
        if (!selectionBean.isProject()) {
            try {
                // the selected class must be either an Activity or a Fragment
                selectionBean.setAllowedClassInstance(
                        JDTUtils.isSubclass(selectionBean.getJavaFile(), "android.app.Activity") //$NON-NLS-1$
                                || JDTUtils.isFragmentSubclass(selectionBean.getJavaFile())
                                || JDTUtils.isCompatibilityFragmentSubclass(selectionBean.getJavaFile()));
            } catch (JavaModelException jme) {
                StudioLogger.error(AbstractCodeGeneratorHandler.class, "Error retrieving class information", jme); //$NON-NLS-1$
                throw new RuntimeException(
                        CodeUtilsNLS.GenerateMenuCodeHandler_Error_CannotRetrieveClassInformation, jme);
            }
        }
        return selectionBean;
    }
}

class SelectionBean {
    private boolean isProject = false;

    private boolean isAllowedClassInstance = false;

    private IFile javaFile = null;

    private IProject javaProject = null;

    public boolean isProject() {
        return isProject;
    }

    public void setProject(boolean isProject) {
        this.isProject = isProject;
    }

    /**
     * @return true if activity or fragment, false otherwise
     */
    public boolean isAllowedClassInstance() {
        return isAllowedClassInstance;
    }

    public void setAllowedClassInstance(boolean isAllowedClassInstance) {
        this.isAllowedClassInstance = isAllowedClassInstance;
    }

    /**    
     * @return selected Android file (Activity or Fragment)
     */
    public IFile getJavaFile() {
        return javaFile;
    }

    /**
     * Sets the Android file selected (Activity or Fragment)
     * @param javaFile
     */
    public void setJavaFile(IFile javaFile) {
        this.javaFile = javaFile;
        javaProject = javaFile.getProject();
    }

    /**
     * @return the project where the Android file (Activity or Fragment) is located
     */
    public IProject getJavaProject() {
        return javaProject;
    }

    public void setJavaProject(IProject javaProject) {
        this.javaProject = javaProject;
    }
}