Package com.salesforce.ide.ui.internal.utils

Source Code of com.salesforce.ide.ui.internal.utils.DeployResultsViewAssembler

/*******************************************************************************
* 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.internal.utils;

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

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import com.salesforce.ide.core.factories.FactoryException;
import com.salesforce.ide.core.internal.utils.Constants;
import com.salesforce.ide.core.internal.utils.DeployMessageExtractor;
import com.salesforce.ide.core.internal.utils.Utils;
import com.salesforce.ide.core.model.ApexCodeLocation;
import com.salesforce.ide.core.model.Component;
import com.salesforce.ide.core.remote.ICodeCoverageResultExt;
import com.salesforce.ide.core.remote.ICodeLocationExt;
import com.salesforce.ide.core.remote.IRunTestsResultExt;
import com.salesforce.ide.core.remote.metadata.IDeployResultExt;
import com.salesforce.ide.core.remote.metadata.RunTestsResultExt;
import com.salesforce.ide.core.services.ProjectService;
import com.salesforce.ide.ui.internal.ForceImages;
import com.sforce.soap.metadata.CodeCoverageWarning;
import com.sforce.soap.metadata.DeployMessage;
import com.sforce.soap.metadata.RunTestFailure;

public class DeployResultsViewAssembler {
    private static final Logger logger = Logger.getLogger(DeployResultsViewAssembler.class);

    protected IRunTestsResultExt runTestResult = null;
    protected IDeployResultExt deployResultHandler = null;
    protected Tree resultsTree = null;
    protected IProject project = null;
    private final Image failureIcon = ForceImages.get(ForceImages.IMAGE_FAILURE);
    private final Image warningIcon = ForceImages.get(ForceImages.IMAGE_WARNING);
    private final Image confirmIcon = ForceImages.get(ForceImages.IMAGE_CONFIRM);

    private final ProjectService projectService;

    //    C O N S T R U C T O R S
    public DeployResultsViewAssembler(IDeployResultExt deployResultHandler, Tree resultsTree, IProject project,
            ProjectService projectService) {
        this.deployResultHandler = deployResultHandler;
        this.runTestResult = new RunTestsResultExt(deployResultHandler.getRunTestsResult());
        this.resultsTree = resultsTree;
        this.project = project;
        this.projectService = projectService;
    }

    //   M E T H O D S
    public void assembleDeployResultsTree() {
        if (resultsTree == null || deployResultHandler == null) {
            throw new IllegalArgumentException("Deploy results and/or result tree cannot be null");
        }
        resultsTree.removeAll();
        handleFailureAndWarningResults();
        handleCodeCoverageResults();

        if (resultsTree.getItemCount() == 0) {
            TreeItem noResultsTreeItem = new TreeItem(resultsTree, SWT.NONE);
            setNoResultsText(noResultsTreeItem);
            noResultsTreeItem.setImage(confirmIcon);
        }
    }

    protected void setNoResultsText(TreeItem noResultsTreeItem) {
        if (deployResultHandler != null) {
            noResultsTreeItem.setText(UIMessages.getString("Deployment.ResultsView.NoResults.message"));
        } else {
            noResultsTreeItem.setText(UIMessages.getString("RunTestsAction.ResultsView.NoResults.message"));
        }
    }

    public void assembleRunTestsResultsTree() {
        if (resultsTree == null || runTestResult == null) {
            throw new IllegalArgumentException("Run test results and/or result tree cannot be null");
        }

        resultsTree.removeAll();
        handleFailureAndWarningResults();
        handleCodeCoverageResults();
    }

    protected void handleFailureAndWarningResults() {
        DeployMessageExtractor extractor = new DeployMessageExtractor(deployResultHandler);

        FontRegistry registry = new FontRegistry();
        Font boldFont = registry.getBold(Display.getCurrent().getSystemFont().getFontData()[0].getName());

        Collection<DeployMessage> deploySuccesses = extractor.getDeploySuccesses();
        handleDeploySuccessMessages(deploySuccesses);

        Collection<DeployMessage> deployFailures = extractor.getDeployFailures();
        Collection<RunTestFailure> testFailures = extractor.getTestFailures();
        if (!deployFailures.isEmpty() || !testFailures.isEmpty()) {
            TreeItem rootFailureTreeItem = new TreeItem(resultsTree, SWT.NONE);
            rootFailureTreeItem.setText("Failures");
            rootFailureTreeItem.setImage(failureIcon);
            rootFailureTreeItem.setForeground(rootFailureTreeItem.getDisplay().getSystemColor(SWT.COLOR_RED));
            rootFailureTreeItem.setFont(boldFont);
            rootFailureTreeItem.setExpanded(true);

            handleDeployFailureMessages(deployFailures, rootFailureTreeItem);
            handleDeployTestFailureMessages(testFailures, rootFailureTreeItem);
        }

        Collection<DeployMessage> deployWarnings = extractor.getDeployWarnings();
        List<CodeCoverageWarning> testWarnings = extractor.getTestWarnings();
        if (!deployWarnings.isEmpty()) {
          TreeItem rootWarningTreeItem = new TreeItem(resultsTree, SWT.NONE);
            rootWarningTreeItem.setText("Deploy Warnings");
            rootWarningTreeItem.setImage(warningIcon);
            rootWarningTreeItem.setForeground(rootWarningTreeItem.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));
            rootWarningTreeItem.setFont(boldFont);
            rootWarningTreeItem.setExpanded(true);
            handleDeployWarningMessages(deployWarnings, rootWarningTreeItem);
        }

        if(!testWarnings.isEmpty()) {
          TreeItem rootWarningTreeItem = new TreeItem(resultsTree, SWT.NONE);
          rootWarningTreeItem.setText("Test Warnings");
            rootWarningTreeItem.setImage(warningIcon);
            rootWarningTreeItem.setForeground(rootWarningTreeItem.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));
            rootWarningTreeItem.setFont(boldFont);
            rootWarningTreeItem.setExpanded(true);
          handleCodeCoverageWarnings(testWarnings, rootWarningTreeItem);
        }
    }

    protected void handleDeployFailureMessages(Collection<DeployMessage> messages, TreeItem rootFailureTreeItem) {
        for (DeployMessage deployMessage : messages) {
            if (logger.isDebugEnabled()) {
                logger.debug("Deployment of '" + getDisplayName(deployMessage) + "' FAILED - "
                        + deployMessage.getProblem());
            }

            addMessageToTree(deployMessage, rootFailureTreeItem);
        }
    }

    protected void handleDeployWarningMessages(Collection<DeployMessage> messages, TreeItem rootTreeItem) {
        for (DeployMessage deployMessage : messages) {
            if (logger.isDebugEnabled()) {
                logger.debug("Deployment of '" + getDisplayName(deployMessage) + "' contained warning - "
                        + deployMessage.getProblem());
            }

            addMessageToTree(deployMessage, rootTreeItem);
        }
    }

    private void handleDeploySuccessMessages(Collection<DeployMessage> messages) {
        if (logger.isDebugEnabled()) {
            for (DeployMessage deployMessage : messages) {
                logger.debug("Deployment of '" + getDisplayName(deployMessage)
                        + "' was successful - remote component was " + getDeployAction(deployMessage));
            }
        }
    }

    private void addMessageToTree(DeployMessage deployMessage, TreeItem rootTreeItem) {
        String displayName = getDisplayName(deployMessage);
        // find existing node for given component; create new if not found
        TreeItem componentTreeItem = getChildTreeItem(rootTreeItem, displayName);
        componentTreeItem.setImage(deployMessage.isSuccess() ? warningIcon : failureIcon);
        // create message node and set data
        TreeItem messageTreeItem = new TreeItem(componentTreeItem, SWT.NONE);
        messageTreeItem.setText(deployMessage.getFullName() + " : " + deployMessage.getProblem());
        messageTreeItem.setData("line", deployMessage.getLineNumber());
        messageTreeItem.setData("column", deployMessage.getColumnNumber());
    }

    protected void handleDeployTestFailureMessages(Collection<RunTestFailure> messages, TreeItem rootFailureTreeItem) {
        for (RunTestFailure testFailure : messages) {
            generateTestFailureNode(testFailure, rootFailureTreeItem);
        }
    }

    protected void generateTestFailureNode(RunTestFailure testFailure, TreeItem rootFailureTreeItem) {
        String displayName = getDisplayName(testFailure.getNamespace(), testFailure.getName());

        TreeItem componentTreeItem = getChildTreeItem(rootFailureTreeItem, displayName);
        componentTreeItem.setImage(failureIcon);

        String methodName =
                Utils.isNotEmpty(testFailure.getMethodName()) ? testFailure.getMethodName()
                        : "Method Name Not Available";
        TreeItem methodTreeItem = getChildTreeItem(componentTreeItem, methodName);
        methodTreeItem.setImage(failureIcon);

        TreeItem messageTreeItem = new TreeItem(methodTreeItem, SWT.NONE);
        messageTreeItem.setText(testFailure.getMessage());
        messageTreeItem.setImage(failureIcon);
        // line and column #s and trace
        setStacktraceData(testFailure, messageTreeItem);
    }

    protected void handleCodeCoverageWarnings(List<CodeCoverageWarning> warnings, TreeItem rootFailureTreeItem) {
        if (warnings.isEmpty()) {
            if (logger.isInfoEnabled()) {
                logger.info("No code coverage warnings found");
            }
            return;
        }

        Collections.sort(warnings, new Comparator<CodeCoverageWarning>() {
            public int compare(final CodeCoverageWarning w1, final CodeCoverageWarning w2) {
                if (Utils.isEmpty(w1.getName())) {
                    return -1;
                } else if (Utils.isNotEmpty(w1.getName()) && Utils.isEmpty(w2.getName())) {
                    return 1;
                } else {
                    return w1.getName().compareTo(w2.getName());
                }
            }
        });

        for (CodeCoverageWarning codeCoverageWarning : warnings) {
            generateCodeCoverageWarningNode(codeCoverageWarning, rootFailureTreeItem);
        }
    }

    protected void generateCodeCoverageWarningNode(CodeCoverageWarning codeCoverageWarning, TreeItem rootFailureTreeItem) {
        String displayName = getDisplayName(codeCoverageWarning.getNamespace(), codeCoverageWarning.getName());
        if (Utils.isEmpty(displayName)) {
            displayName = "General Warnings";
        }

        // find existing node for given component; create new if not found
        TreeItem warningNameTreeItem = getChildTreeItem(rootFailureTreeItem, displayName);
        warningNameTreeItem.setImage(warningIcon);
        // create message node
        TreeItem warningMessageTreeItem = new TreeItem(warningNameTreeItem, SWT.NONE);
        warningMessageTreeItem.setText(codeCoverageWarning.getMessage());
        warningMessageTreeItem.setImage(warningIcon);
    }

    protected void handleCodeCoverageResults() {
        if (Utils.isEmpty(runTestResult.getCodeCoverages())) {
            if (logger.isInfoEnabled()) {
                logger.info("No code coverage results found");
            }
            return;
        }

        TreeItem rootCodeCoverageTreeItem = new TreeItem(resultsTree, SWT.NONE);
        rootCodeCoverageTreeItem.setText("Code Coverage Results");

        // loop thru results for each method displaying code coverage and failures
        ICodeCoverageResultExt[] codeCoverageResults = runTestResult.getCodeCoverages();
        sortCodeCoverageResults(codeCoverageResults);

        for (ICodeCoverageResultExt codeCoverageResult : codeCoverageResults) {
            generateCodeCoverageWarningNode(codeCoverageResult, rootCodeCoverageTreeItem);
        }

        if (rootCodeCoverageTreeItem.getImage() == null) {
            rootCodeCoverageTreeItem.setImage(confirmIcon);
        }
    }

    protected void generateCodeCoverageWarningNode(ICodeCoverageResultExt codeCoverageResult,
            TreeItem rootCodeCoverageTreeItem) {
        IFile componentFile =
                getCoverageResultTargetComponentFile(codeCoverageResult.getName(), codeCoverageResult.getType());
        if (componentFile == null) {
            logger.warn("Unable to locate component file in project to display code coverage result '"
                    + codeCoverageResult.getName() + "'");
        }
        String displayName = getDisplayName(codeCoverageResult);

        int numLocations = codeCoverageResult.getNumLocations();
        int numLocationsNotCovered = codeCoverageResult.getNumLocationsNotCovered();
        int codeCoveragePrct = 100;

        if (numLocationsNotCovered > 0) {
            int covered = numLocations - numLocationsNotCovered;
            Double coverage = (Double.valueOf(covered) / Double.valueOf(numLocations)) * 100;
            codeCoveragePrct = Integer.valueOf((int) Math.round(coverage.doubleValue())).intValue();
        }

        TreeItem rootComponentTreeItem = new TreeItem(rootCodeCoverageTreeItem, SWT.NONE);
        rootComponentTreeItem.setText(displayName + " -- " + numLocationsNotCovered + " lines not tested, "
                + codeCoveragePrct + "% covered");

        // if coverage doesn't meet compliance, highlight nodes
        if (codeCoveragePrct < runTestResult.getCodeCompilanceCovagePercentage() && numLocationsNotCovered != 0) {
            // set root warning tree icon
            rootCodeCoverageTreeItem.setImage(warningIcon);
            rootCodeCoverageTreeItem.setForeground(rootCodeCoverageTreeItem.getDisplay().getSystemColor(
                SWT.COLOR_DARK_YELLOW));
            // set artifact warning tree icon
            rootComponentTreeItem.setImage(warningIcon);
            addUncoveredLines(componentFile, rootComponentTreeItem, codeCoverageResult.getLocationsNotCovered());
        } else {
            rootComponentTreeItem.setImage(confirmIcon);
            addUncoveredLines(componentFile, rootComponentTreeItem, codeCoverageResult.getLocationsNotCovered());
        }
    }

    private IFile getCoverageResultTargetComponentFile(String componentName, String componentType) {
        IFile file = null;

        try {
            file = projectService.getComponentFileByNameType(project, componentName, apexPrefixCheck(componentType));
        } catch (CoreException e) {
            String logMessage = Utils.generateCoreExceptionLog(e);
            logger.warn("Unable to find resource for '" + componentName + "( " + componentType + ")'  in package "
                    + project.getName() + ": " + logMessage, e);
        } catch (FactoryException e) {
            logger.warn("Unable to find resource for '" + componentName + "( " + componentType + ")'  in package "
                    + project.getName(), e);
        }
        return file;
    }

    private void addUncoveredLines(IFile componentFile, TreeItem rootComponentTreeItem,
            ICodeLocationExt[] codeLocationExt) {
        if (Utils.isEmpty(codeLocationExt)) {
            if (logger.isDebugEnabled()) {
                logger.debug("No code locations provided to displayed uncovered test locations");
            }
            return;
        }

        for (ICodeLocationExt codeLocation : codeLocationExt) {
            TreeItem uncoveredLineTreeItem = new TreeItem(rootComponentTreeItem, SWT.NONE);
            uncoveredLineTreeItem.setText("Line " + codeLocation.getLine() + ", Column " + codeLocation.getColumn()
                    + " not covered");
            ApexCodeLocation location =
                    new ApexCodeLocation(componentFile, codeLocation.getLine(), codeLocation.getColumn());
            uncoveredLineTreeItem.setData("location", location);
            uncoveredLineTreeItem.setData("line", codeLocation.getLine());
            uncoveredLineTreeItem.setImage(warningIcon);
        }
    }

    private String apexPrefixCheck(String componentType) {
        if (Utils.isNotEmpty(componentType) && !componentType.startsWith(Constants.APEX_PREFIX)) {
            componentType = Constants.APEX_PREFIX + componentType;
        }
        return componentType;
    }

    private void sortCodeCoverageResults(ICodeCoverageResultExt[] codeCoverageResults) {
        if (Utils.isEmpty(codeCoverageResults)) {
            return;
        }

        Arrays.sort(codeCoverageResults, new Comparator<ICodeCoverageResultExt>() {
            @Override
            public int compare(ICodeCoverageResultExt o1, ICodeCoverageResultExt o2) {
                String s1 = getDisplayName(o1.getNamespace(), o1.getName());
                String s2 = getDisplayName(o2.getNamespace(), o2.getName());
                return s1.compareTo(s2);
            }
        });
    }

    private String getDisplayName(DeployMessage deployMessage) {
        // REVIEWME: full name or file name?
        return deployMessage.getFileName();
    }

    private String getDisplayName(ICodeCoverageResultExt codeCoverageResult) {
        String componentName = getDisplayName(codeCoverageResult.getNamespace(), codeCoverageResult.getName());
        Component component = null;
        try {
            component =
                    projectService.getComponentFactory().getComponentByComponentType(
                        apexPrefixCheck(codeCoverageResult.getType()));
        } catch (FactoryException e) {
            logger.error("Unable to locate corresponding component based on CodeCoverageResult type '"
                    + codeCoverageResult.getType() + "' ", e);
        }
        return componentName
                + (Utils.isNotEmpty(component) ? " (" + component.getComponentType() + ")" : " ("
                        + codeCoverageResult.getType() + ")");
    }

    private String getDisplayName(String namespace, String name) {
        StringBuffer strBuff = new StringBuffer();

        // prepend namespace
        if (Utils.isNotEmpty(namespace)) {
            strBuff.append(namespace + ".");
        }

        strBuff.append(Utils.isNotEmpty(name) ? name : "");

        return strBuff.toString();
    }

    private String getDeployAction(DeployMessage deployMessage) {
        if (deployMessage.isCreated()) {
            return "created";
        } else if (deployMessage.isDeleted()) {
            return "deleted";
        } else if (deployMessage.isChanged()) {
            return "updated";
        } else {
            return "unknown action";
        }
    }

    private TreeItem getChildTreeItem(TreeItem parentTreeItem, String name) {
        if (parentTreeItem.getItemCount() > 0) {
            TreeItem[] childTreeItems = parentTreeItem.getItems();
            for (TreeItem childTreeItem : childTreeItems) {
                if (childTreeItem.getText().equals(name)) {
                    return childTreeItem;
                }
            }
        }

        TreeItem tmpTreeItem = new TreeItem(parentTreeItem, SWT.NONE);
        tmpTreeItem.setText(name);

        return tmpTreeItem;
    }

    private void setStacktraceData(RunTestFailure testFailure, TreeItem messageTreeItem) {
        if (Utils.isEmpty(testFailure.getStackTrace())) {
            return;
        }

        String stacktrace = testFailure.getStackTrace();
        TreeItem stacktraceTreeItem = new TreeItem(messageTreeItem, SWT.NONE);
        ApexCodeLocation location = getLocationFromStackLine(testFailure.getName(), stacktrace);

        IFile file = getCoverageResultTargetComponentFile(testFailure.getName(), testFailure.getType());
        if (file != null) {
            location.setFile(file);
        }

        stacktraceTreeItem.setData("location", location);
        stacktraceTreeItem.setData("line", "1");
        stacktraceTreeItem.setText(stacktrace);
    }

    private ApexCodeLocation getLocationFromStackLine(String name, String stackTrace) {
        if (Utils.isEmpty(name) || Utils.isEmpty(stackTrace)) {
            logger.warn("Unable to get location from stacktrace - name and/or stacktrace is null");
            return null;
        }

        String line = null;
        String column = null;
        try {
            String[] temp = stackTrace.split("line");
            line = temp[1].split(",")[0].trim();
            String c = temp[1].trim();
            column = c.split("column")[1].trim();
            if (Utils.isNotEmpty(column) && column.contains("\n")) {
                column = column.substring(0, column.indexOf("\n"));
            }
        } catch (Exception e) {
            logger.warn("Unable to get location from stacktrace", e);
        }
        return new ApexCodeLocation(name, line, column);
    }
}
TOP

Related Classes of com.salesforce.ide.ui.internal.utils.DeployResultsViewAssembler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.