com.salesforce.ide.ui.views.runtest.ProjectConfigurationTab.java Source code

Java tutorial

Introduction

Here is the source code for com.salesforce.ide.ui.views.runtest.ProjectConfigurationTab.java

Source

/*******************************************************************************
 * Copyright (c) 2016 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.runtest;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Group;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;

import com.google.common.annotations.VisibleForTesting;
import com.salesforce.ide.core.internal.context.ContainerDelegate;
import com.salesforce.ide.core.internal.utils.Utils;
import com.salesforce.ide.core.project.DefaultNature;
import com.sforce.soap.tooling.ApexLogLevel;

/**
 * Apex Test launch configuration tab to select project & log levels
 * 
 * @author jwidjaja
 *
 */
public class ProjectConfigurationTab extends RunTestsTab {

    private TestConfigurationTab testTab;

    @VisibleForTesting
    public Text projectText;
    @VisibleForTesting
    public Button projectButton;
    @VisibleForTesting
    public Button logStatus;
    @VisibleForTesting
    public LinkedHashMap<String, Combo> logSettings;

    @VisibleForTesting
    public static final String[] logCategories = new String[] { Messages.Tab_LogCategoryDatabase,
            Messages.Tab_LogCategoryWorkflow, Messages.Tab_LogCategoryValidation, Messages.Tab_LogCategoryCallout,
            Messages.Tab_LogCategoryApexCode, Messages.Tab_LogCategoryApexProfiling,
            Messages.Tab_LogCategoryVisualforce, Messages.Tab_LogCategorySystem };

    private static final LinkedHashMap<String, String> defaultLogLevels;
    static {
        defaultLogLevels = new LinkedHashMap<String, String>();
        for (String logCategory : logCategories) {
            if (logCategory.equals(Messages.Tab_LogCategoryApexCode)
                    || logCategory.equals(Messages.Tab_LogCategorySystem)) {
                defaultLogLevels.put(logCategory, ApexLogLevel.DEBUG.name());
            } else {
                defaultLogLevels.put(logCategory, ApexLogLevel.INFO.name());
            }
        }
    }

    /**
     * Need to be able to get some stuff from TestConfigurationTab,
     * so this is probably better than doing
     * getLaunchConfigurationDialog().getTabs() and instanceof.
     */
    @VisibleForTesting
    public void saveSiblingTab(RunTestsTab testTab) {
        this.testTab = (TestConfigurationTab) testTab;
    }

    @VisibleForTesting
    public TestConfigurationTab getSiblingTab() {
        return this.testTab;
    }

    @VisibleForTesting
    public String getProjectName() {
        return (Utils.isEmpty(projectText) ? "" : projectText.getText());
    }

    /**
      * Get the project from the name in project text field.
      */
    @VisibleForTesting
    public IProject getProjectFromName() {
        String projectName = getProjectName();
        if (StringUtils.isNotBlank(projectName)) {
            return ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
        }

        return null;
    }

    @VisibleForTesting
    @Override
    public void createControl(Composite parent) {
        if (Utils.isEmpty(parent))
            return;

        Composite comp = createComposite(parent, SWT.NONE);
        setControl(comp);
        colorGray = comp.getDisplay().getSystemColor(SWT.COLOR_GRAY);
        colorBlack = comp.getDisplay().getSystemColor(SWT.COLOR_BLACK);

        GridLayout grid = new GridLayout();
        comp.setLayout(grid);

        // This tab allows project & log selections
        createProjectSelector(comp);
        createLogEditor(comp);
    }

    @VisibleForTesting
    public void createProjectSelector(Composite parent) {
        Group group = createGroup(parent, SWT.NONE);
        group.setText(Messages.Tab_ProjectGroupTitle);
        group.setLayout(new GridLayout(2, false));
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        // Get user's selected project as a backup. If none is selected, user
        // has to select one.
        projectText = makeDefaultText(group, "", colorBlack);
        projectButton = makeDefaultButton(group, Messages.Tab_SearchButtonText, true);
        projectButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                handleProjectButtonSelected();
                validatePage();
                updateLaunchConfigurationDialog();
            }
        });
    }

    /**
      * Create log settings editor with checkbox,
      * log categories, and log levels.
      */
    @VisibleForTesting
    public void createLogEditor(Composite parent) {
        Group logGroup = createGroup(parent, SWT.NONE);
        logGroup.setText(Messages.Tab_LogGroupTitle);
        logGroup.setLayout(new GridLayout(4, true));
        logGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        logStatus = makeDefaultCheckbox(logGroup, Messages.Tab_LogEnableLogging, true, true);
        GridData gridData = new GridData();
        gridData.horizontalAlignment = GridData.FILL;
        gridData.horizontalSpan = 4;
        logStatus.setLayoutData(gridData);
        logStatus.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                Button btn = (Button) e.getSource();
                shouldEnableLevels(btn.getSelection());
                validatePage();
                updateLaunchConfigurationDialog();
            }
        });

        String[] logLevels = new String[] { ApexLogLevel.NONE.name(), ApexLogLevel.ERROR.name(),
                ApexLogLevel.WARN.name(), ApexLogLevel.INFO.name(), ApexLogLevel.DEBUG.name(),
                ApexLogLevel.FINE.name(), ApexLogLevel.FINER.name(), ApexLogLevel.FINEST.name() };

        logSettings = new LinkedHashMap<String, Combo>();

        for (String logCategory : logCategories) {
            makeDefaultLabel(logGroup, logCategory);
            Combo logCategoryCombo = new Combo(logGroup, SWT.READ_ONLY);
            logCategoryCombo.setVisible(true);
            logCategoryCombo.setEnabled(true);
            logCategoryCombo.setItems(logLevels);
            logCategoryCombo.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    validatePage();
                    updateLaunchConfigurationDialog();
                }
            });

            logSettings.put(logCategory, logCategoryCombo);
        }

        setLogLevels(defaultLogLevels);
    }

    /**
      * Enable or disable the log categories
      */
    @VisibleForTesting
    public void shouldEnableLevels(boolean shouldEnable) {
        if (Utils.isEmpty(logStatus) || Utils.isEmpty(logSettings)) {
            return;
        }

        logStatus.setSelection(shouldEnable);

        for (Combo logCategoryCombo : logSettings.values()) {
            logCategoryCombo.setEnabled(shouldEnable);
        }
    }

    /**
      * Set the log level combo boxes
      */
    @VisibleForTesting
    public void setLogLevels(Map<String, String> logLevels) {
        if (Utils.isEmpty(logLevels)) {
            return;
        }

        for (String logCategory : logLevels.keySet()) {
            String desiredLogLevelName = logLevels.get(logCategory);
            Combo logCombo = logSettings.get(logCategory);
            if (Utils.isNotEmpty(logCombo)) {
                logCombo.setText(desiredLogLevelName);
            }
        }
    }

    /**
     * Find projects in the workspace and update other widgets when
     * project is chosen.
     */
    @VisibleForTesting
    public void handleProjectButtonSelected() {
        IProject selectedProject = chooseProject();

        if (Utils.isEmpty(selectedProject) || Utils.isEmpty(projectText))
            return;

        String projectName = selectedProject.getName();
        if (StringUtils.isBlank(projectName) || Utils.isEmpty(projectText))
            return;

        // Reset test class, test method, and suites if user changed projects
        if (!projectName.equals(projectText.getText())) {
            testTab.resetTestSelection();
            testTab.fetchSuites(selectedProject);
        }

        // Display newest selected project name
        projectText = setTextProperties(projectText, projectName, colorBlack);
    }

    /**
      * Display a list of projects in the workspace and return the selected one.
      */
    @VisibleForTesting
    public IProject chooseProject() {
        // Get all projects in workspace
        ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), new LabelProvider() {
            @Override
            public String getText(Object element) {
                if (Utils.isNotEmpty(element) && element instanceof IProject) {
                    return ((IProject) element).getName();
                }
                return "";
            }
        });

        // Display the projects in dialog. If there is none, user cannot launch config.
        dialog.setTitle(Messages.Tab_ProjectDialogTitle);
        dialog.setMessage(Messages.Tab_ProjectDialogInstruction);
        dialog.setHelpAvailable(false);
        dialog.setElements(ContainerDelegate.getInstance().getServiceLocator().getProjectService()
                .getForceProjects().toArray());

        if (dialog.open() == Window.OK) {
            return (IProject) dialog.getFirstResult();
        }

        return null;
    }

    /**
      * Reset messages and validate project selection.
      * @return True if all is okay. False otherwise.
      */
    @VisibleForTesting
    public boolean validatePage() {
        // Reset the messages first to a clean slate
        setErrorMessage(null);
        setMessage(null);

        return validateProjectSelection() && testTab.validateSuiteSelection();
    }

    /**
      * Validate project selection.
      * @return True if all is okay. False otherwise.
      */
    @VisibleForTesting
    public boolean validateProjectSelection() {
        if (getProjectName() == null || getProjectName().length() == 0) {
            setErrorMessage(Messages.Tab_EmptyProjectErrorMessage);
            return false;
        }

        IProject project = getProjectFromName();
        if (Utils.isEmpty(project)) {
            setErrorMessage(Messages.Tab_NonExistingProjectErrorMessage);
            return false;
        }

        try {
            if (!project.hasNature(DefaultNature.NATURE_ID)) {
                setErrorMessage(Messages.Tab_InvalidForceProjectErrorMessage);
                return false;
            }
        } catch (CoreException e) {
        }

        return true;
    }

    @VisibleForTesting
    @Override
    public boolean isValid(ILaunchConfiguration launchConfig) {
        validatePage();
        return getErrorMessage() == null;
    }

    @VisibleForTesting
    public boolean isLoggingEnabled() {
        return (Utils.isNotEmpty(logStatus) && logStatus.getSelection());
    }

    @VisibleForTesting
    public Map<String, String> getLogLevels() {
        Map<String, String> logLevels = new LinkedHashMap<String, String>();

        if (Utils.isEmpty(logSettings)) {
            return logLevels;
        }

        for (String logCategory : logSettings.keySet()) {
            Combo selectedCombo = logSettings.get(logCategory);
            if (Utils.isEmpty(selectedCombo)) {
                continue;
            }

            ApexLogLevel logLevel = ApexLogLevel.valueOf(selectedCombo.getText());
            if (Utils.isNotEmpty(logLevel)) {
                String logLevelName = logLevel.name();
                logLevels.put(logCategory, logLevelName);
            }
        }

        return logLevels;
    }

    @VisibleForTesting
    @Override
    public void initializeFrom(ILaunchConfiguration configuration) {
        try {
            // Populate project from saved config
            String projectName = configuration.getAttribute(RunTestsConstants.ATTR_PROJECT_NAME, "");
            setTextProperties(projectText, projectName, colorBlack);

            // Set log levels
            boolean shouldEnableLogging = configuration.getAttribute(RunTestsConstants.ATTR_ENABLE_LOGGING, false);
            shouldEnableLevels(shouldEnableLogging);
            Map<String, String> logLevels = configuration.getAttribute(RunTestsConstants.ATTR_LOG_LEVELS,
                    Collections.emptyMap());
            setLogLevels(logLevels);
        } catch (CoreException e) {
        }
    }

    @VisibleForTesting
    @Override
    public void performApply(ILaunchConfigurationWorkingCopy configuration) {
        configuration.setAttribute(RunTestsConstants.ATTR_PROJECT_NAME, getProjectName());
        configuration.setAttribute(RunTestsConstants.ATTR_ENABLE_LOGGING, isLoggingEnabled());
        configuration.setAttribute(RunTestsConstants.ATTR_LOG_LEVELS, getLogLevels());
    }

    @VisibleForTesting
    @Override
    public String getName() {
        return Messages.Tab_ProjectTabTitle;
    }

    @Override
    public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
    }
}