com.salesforce.ide.ui.views.executeanonymous.ExecuteAnonymousViewComposite.java Source code

Java tutorial

Introduction

Here is the source code for com.salesforce.ide.ui.views.executeanonymous.ExecuteAnonymousViewComposite.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Salesforce.com, 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:
 *     Salesforce.com, inc. - initial API and implementation
 ******************************************************************************/
package com.salesforce.ide.ui.views.executeanonymous;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
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.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.progress.UIJob;

import com.salesforce.ide.core.ForceIdeCorePlugin;
import com.salesforce.ide.core.internal.context.ContainerDelegate;
import com.salesforce.ide.core.internal.utils.LoggingInfo;
import com.salesforce.ide.core.internal.utils.Utils;
import com.salesforce.ide.core.remote.apex.ExecuteAnonymousResultExt;
import com.salesforce.ide.ui.internal.composite.BaseComposite;
import com.salesforce.ide.ui.internal.utils.UIUtils;
import com.salesforce.ide.ui.views.LoggingComposite;

/**
 * Legacy class
 * 
 * @author dcarroll
 */
public class ExecuteAnonymousViewComposite extends BaseComposite {

    protected SashForm sashForm = null;
    protected Composite cmpSource = null;
    protected Button btnExecute = null;
    protected StyledText txtSourceInput = null;
    protected StyledText txtResult = null;
    protected Composite projectAndLoggingContainerComposite = null;
    protected Composite projectComposite = null;
    protected LoggingComposite loggingComposite = null;
    protected Combo projectCombo = null;
    protected ExecuteAnonymousController executeAnonymousController = null;
    protected StyledText txtUserDebugLogs = null;
    private static final int DEFAULT_PROJ_SELECTION = 0;
    protected IResourceChangeListener resourceListener = null;
    private static final Logger logger = Logger.getLogger(ExecuteAnonymousView.class);

    Color color = new Color(Display.getCurrent(), 240, 240, 240);

    public ExecuteAnonymousViewComposite(Composite parent, int style,
            ExecuteAnonymousController executeAnonymousController) {
        super(parent, style);
        this.executeAnonymousController = executeAnonymousController;

        addDisposeListener(new DisposeListener() {
            @Override
            public void widgetDisposed(DisposeEvent e) {
                color.dispose();
            }
        });
        initialize();
    }

    public void enableComposite(boolean enable) {
        if (txtSourceInput != null) {
            txtSourceInput.setEnabled(enable);
        }

        if (loggingComposite != null) {
            loggingComposite.enable(enable);
        }
    }

    protected void initialize() {
        GridLayout gridLayout = new GridLayout();
        setLayout(gridLayout);
        setSize(new Point(566, 1200));

        createLoggingComposite();
        createInputAndOutputComposite();

        loadProjects();
        setActiveProject(executeAnonymousController.getProject());
    }

    private void createInputAndOutputComposite() {
        GridData gridData = new GridData();
        gridData.horizontalAlignment = GridData.FILL;
        gridData.verticalAlignment = GridData.FILL;
        gridData.grabExcessHorizontalSpace = true;
        gridData.grabExcessVerticalSpace = true;
        gridData.heightHint = 650;

        sashForm = new SashForm(this, SWT.BORDER | SWT.HORIZONTAL);
        sashForm.setSashWidth(5);
        sashForm.setLayoutData(gridData);
        createSourceComposite(sashForm);

        Composite composite = new Composite(sashForm, SWT.NONE);
        composite.setLayout(new GridLayout(1, false));
        createResultComposite(composite);
        createUserLogsComposite(composite);
    }

    private void createLoggingComposite() {
        projectAndLoggingContainerComposite = new Composite(this, SWT.NONE);
        projectAndLoggingContainerComposite.setLayout(new GridLayout(3, false));
        createProjectComposite(projectAndLoggingContainerComposite);
        loggingComposite = new LoggingComposite(projectAndLoggingContainerComposite,
                ContainerDelegate.getInstance().getServiceLocator().getLoggingService(), SWT.NONE, false,
                LoggingInfo.SupportedFeatureEnum.ExecuteAnonymous);
    }

    protected void createSourceComposite(Composite parent) {
        cmpSource = new Composite(parent, SWT.NONE);
        cmpSource.setLayout(new GridLayout(2, false));

        // Source to execute: label
        CLabel lblSource = new CLabel(cmpSource, SWT.NONE);
        lblSource.setText("Source to execute:");
        lblSource.setLayoutData(new GridData(GridData.CENTER));

        // Execute Anonymous button
        btnExecute = new Button(cmpSource, SWT.NONE);
        btnExecute.setText("Execute Anonymous");
        btnExecute.setEnabled(false);
        btnExecute.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
        btnExecute.addMouseListener(new org.eclipse.swt.events.MouseAdapter() {
            @Override
            public void mouseUp(org.eclipse.swt.events.MouseEvent e) {
                executeExecuteAnonymous();
            }
        });

        // Apex input text field        
        txtSourceInput = new StyledText(cmpSource, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
        txtSourceInput.setEnabled(false);
        txtSourceInput.setLayoutData(getInputResultsGridData(2));
        txtSourceInput.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                if (txtSourceInput != null && btnExecute != null) {
                    btnExecute.setEnabled(Utils.isNotEmpty(txtSourceInput.getText()));
                }
            }
        });

    }

    private GridData getInputResultsGridData(int span) {
        Rectangle rect = UIUtils.getClientArea(getShell());

        GridData gridData = new GridData();
        gridData.horizontalAlignment = GridData.FILL;
        gridData.grabExcessHorizontalSpace = true;
        gridData.grabExcessVerticalSpace = true;
        gridData.horizontalSpan = span;
        gridData.heightHint = (int) (rect.height * .4);
        gridData.verticalAlignment = GridData.FILL;
        return gridData;
    }

    public void executeExecuteAnonymous() {
        if (executeAnonymousController.getProject() == null) {
            Utils.openError("No Project Selected", "Please select a project from which to execute anonymous.");
            return;
        }

        txtResult.setText("Executing code...");
        txtUserDebugLogs.setText("Executing code...");
        txtResult.update();
        txtUserDebugLogs.update();

        final String code = txtSourceInput.getText();
        // Execute the code in a different thread to allow debugging (since DBGP takes up the main thread)
        Job job = new Job("Execute-Anonymous") {
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                ExecuteAnonymousResultExt result = executeAnonymousController.executeExecuteAnonymous(code);
                handleExecuteResults(result);
                return Status.OK_STATUS;
            }
        };
        job.schedule();
    }

    protected void createResultComposite(Composite parent) {
        CLabel lblResult = new CLabel(parent, SWT.NONE);
        lblResult.setLayoutData(new GridData(GridData.BEGINNING));
        lblResult.setText("Results:");

        txtResult = new StyledText(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY | SWT.BORDER);
        txtResult.setBackground(color);
        txtResult.setLayoutData(getInputResultsGridData(1));
    }

    private void createUserLogsComposite(Composite parent) {
        CLabel lblResult = new CLabel(parent, SWT.NONE);
        lblResult.setLayoutData(new GridData(GridData.BEGINNING));
        lblResult.setText("User Debug Logs:");

        txtUserDebugLogs = new StyledText(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY | SWT.BORDER);
        txtUserDebugLogs.setBackground(color);
        txtUserDebugLogs.setLayoutData(getInputResultsGridData(1));
    }

    protected void createProjectComposite(Composite cmpSource) {
        projectComposite = new Composite(cmpSource, SWT.NONE);
        projectComposite.setLayoutData(new GridData(SWT.BEGINNING));
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 3;
        projectComposite.setLayout(gridLayout);

        CLabel lblProject = new CLabel(projectComposite, SWT.NONE);
        lblProject.setLayoutData(new GridData(SWT.BEGINNING));
        lblProject.setText("Active Project:");

        projectCombo = new Combo(projectComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
        projectCombo.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
            @Override
            @SuppressWarnings("unchecked")
            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
                Combo tmpCboProject = (Combo) e.widget;
                if (tmpCboProject.getData() != null && tmpCboProject.getData() instanceof List) {
                    List<IProject> projects = (List<IProject>) tmpCboProject.getData();
                    if (Utils.isNotEmpty(projects)) {
                        int selectionIndex = ((Combo) e.widget).getSelectionIndex();
                        IProject selectedProject = projects.get(selectionIndex);
                        if (selectedProject != null) {
                            setActiveProject(selectedProject);
                        }

                    }
                }
            }

            @Override
            public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
                widgetSelected(e);
            }
        });
    }

    public void setActiveProject(IProject project) {
        if (project == null) {
            project = getFirstProject();
        }

        setSelectedProjectCombo(project);

        executeAnonymousController.setProject(project);

        if (loggingComposite != null) {
            loggingComposite.setProject(project);
        }

        if (project != null && project.getName().equals(projectCombo.getText())) {
            enableComposite(true);
        } else {
            enableComposite(false);
        }
    }

    @SuppressWarnings("unchecked")
    private IProject getFirstProject() {
        IProject firstProject = null;
        if (projectCombo.getData() != null && projectCombo.getData() instanceof List) {
            List<IProject> projects = (List<IProject>) projectCombo.getData();
            firstProject = Utils.isNotEmpty(projects) ? projects.get(0) : null;
        }
        return firstProject;
    }

    public void loadProjects() {
        if (executeAnonymousController == null || projectCombo == null) {
            return;
        }

        List<IProject> projects = executeAnonymousController.getForceProjects();
        if (Utils.isNotEmpty(projects)) {
            loadProjects(projects);
        } else {
            if (projectCombo.getItemCount() > 0)
                projectCombo.removeAll();

            projectCombo.setData(null);
            projectCombo.setEnabled(false);
            enableComposite(false);
        }

        layout(true, true);

        final IResourceDeltaVisitor deltaVisitor = new IResourceDeltaVisitor() {
            @Override
            public boolean visit(IResourceDelta delta) throws CoreException {
                IResource res = delta.getResource();
                if (res instanceof IProject) {
                    final IProject project = (IProject) res;
                    switch (delta.getKind()) {
                    case IResourceDelta.ADDED:
                        if (ContainerDelegate.getInstance().getServiceLocator().getProjectService()
                                .isForceProject(project)) {
                            updateProjectComboProjectedAdded();
                        }
                        break;
                    case IResourceDelta.REMOVED:
                        updateProjectComboProjectRemoved(project);
                        break;
                    case IResourceDelta.CHANGED:
                        if (ContainerDelegate.getInstance().getServiceLocator().getProjectService()
                                .isForceProject(project)) {
                            updateProjectComboProjectedAdded();
                        } else {
                            updateProjectComboProjectRemoved(project);
                        }
                        break;
                    }
                }

                return true;
            }
        };

        resourceListener = new IResourceChangeListener() {
            @Override
            public void resourceChanged(IResourceChangeEvent event) {
                switch (event.getType()) {
                case IResourceChangeEvent.POST_CHANGE:
                    try {
                        event.getDelta().accept(deltaVisitor);
                    } catch (CoreException e) {
                        String logMessage = Utils.generateCoreExceptionLog(e);
                        logger.warn("Unable to process: " + logMessage);
                    }
                    break;
                default:
                    break;

                }
            }
        };

        ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceListener,
                IResourceChangeEvent.POST_CHANGE);
    }

    private void loadProjects(List<IProject> projects) {
        if (projectCombo.getItemCount() > 0)
            projectCombo.removeAll();

        projectCombo.setData(projects);
        Collections.sort(projects, new Comparator<IProject>() {
            @Override
            public int compare(IProject o1, IProject o2) {
                return String.CASE_INSENSITIVE_ORDER.compare(o1.getName(), o2.getName());
            }
        });

        for (IProject project : projects) {
            projectCombo.add(project.getName());
        }

        projectCombo.select(DEFAULT_PROJ_SELECTION);
        projectCombo.setEnabled(true);

        // Sets the width of the combo box to the width of the longest string
        // Layouts everything
        projectAndLoggingContainerComposite.pack();
        projectAndLoggingContainerComposite.layout(true, true);

        enableComposite(true);
    }

    private void updateProjectComboProjectRemoved(final IProject project) {
        UIJob job = new UIJob("Update Exec Anon Projects Combo") {
            @Override
            public IStatus runInUIThread(IProgressMonitor monitor) {
                if (projectCombo.getItemCount() > 0
                        && ArrayUtils.contains(projectCombo.getItems(), project.getName())) {
                    projectCombo.remove(project.getName());
                    if (projectCombo.getItemCount() > 0) {
                        projectCombo.select(DEFAULT_PROJ_SELECTION);
                    } else {
                        projectCombo.setData(null);
                        projectCombo.setEnabled(false);
                        enableComposite(false);
                    }
                }
                return new Status(Status.OK, ForceIdeCorePlugin.PLUGIN_ID, "Successfully updated projects combo");
            }
        };
        job.setSystem(true);
        job.schedule();
    }

    private void updateProjectComboProjectedAdded() {
        UIJob job = new UIJob("Update Exec Anon Projects Combo") {
            @Override
            public IStatus runInUIThread(IProgressMonitor monitor) {
                List<IProject> projects = executeAnonymousController.getForceProjects();
                loadProjects(projects);
                return new Status(Status.OK, ForceIdeCorePlugin.PLUGIN_ID, "Successfully updated projects combo");
            }
        };
        job.setSystem(true);
        job.schedule();
    }

    private void setSelectedProjectCombo(IProject selectedProject) {
        if (projectCombo != null && Utils.isNotEmpty(selectedProject)) {
            selectComboContent(selectedProject.getName(), projectCombo);
        } else {
            projectCombo.select(DEFAULT_PROJ_SELECTION);
        }
    }

    private void handleExecuteResults(final ExecuteAnonymousResultExt executeAnonymousResult) {
        Display.getDefault().asyncExec(new Runnable() {
            @Override
            public void run() {
                if (executeAnonymousResult.getCompiled()) {
                    if (executeAnonymousResult.getSuccess()) {
                        txtResult.setText("Anonymous execution was successful.\n\n");
                        txtUserDebugLogs.setText("Anonymous execution was successful.\n\n");
                        if (executeAnonymousResult.getDebugInfo() != null) {
                            String finalResult = "";
                            String debugResult = executeAnonymousResult.getDebugInfo().getDebugLog();
                            if (debugResult.contains("DEBUG")) {
                                String[] newDateWithSperators = debugResult.split("\\|");
                                for (int index = 0; index < newDateWithSperators.length; index++) {
                                    String newDateWithSperator = newDateWithSperators[index];
                                    if (newDateWithSperator.contains("USER_DEBUG")) {
                                        String debugData = newDateWithSperators[index + 3];
                                        debugData = debugData.substring(0, debugData.lastIndexOf('\n'));
                                        finalResult += "\n" + debugData + "\n";
                                    }

                                }
                            }
                            txtResult.setText(
                                    txtResult.getText() + executeAnonymousResult.getDebugInfo().getDebugLog());
                            txtUserDebugLogs.setText(finalResult);
                        }
                    } else {
                        StringBuffer errorMessage = new StringBuffer("DEBUG LOG\n");
                        if (executeAnonymousResult.getDebugInfo() != null) {
                            errorMessage.append(executeAnonymousResult.getDebugInfo().getDebugLog());
                        }
                        txtResult.setText(errorMessage.toString());
                        txtUserDebugLogs.setText(errorMessage.toString());
                    }
                } else {
                    StringBuilder strBuilder = new StringBuilder("Compile error at line ");
                    strBuilder.append(executeAnonymousResult.getLine()).append(" column ")
                            .append(executeAnonymousResult.getColumn()).append("\n")
                            .append(executeAnonymousResult.getCompileProblem());
                    txtResult.setText(strBuilder.toString());
                    txtUserDebugLogs.setText(strBuilder.toString());
                }
            }
        });
    }

    @Override
    public void validateUserInput() {
    }

    @Override
    public void dispose() {
        ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceListener);
        super.dispose();
    }

}