Package com.salesforce.ide.core.project

Source Code of com.salesforce.ide.core.project.MarkerUtils

/*******************************************************************************
* 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.core.project;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;

import com.salesforce.ide.core.ForceIdeCorePlugin;
import com.salesforce.ide.core.internal.utils.Messages;
import com.salesforce.ide.core.internal.utils.Utils;

/**
* Common methods for adding and removing dirty markers
*
* TODO: There is a weird error with Eclipse itself, where if we specify both line number and column number, it only
* respects the column number. For now, disable column location in all apply*Marker methods.
*
* @author cwall
*/
public class MarkerUtils {

    private static final Logger logger = Logger.getLogger(MarkerUtils.class);

    private static final String MARKER_ATTR_OBJECT_TYPE = "ComponentType";

    // Superclass for all apex markers
    public static final String MARKER_PROBLEM = ForceIdeCorePlugin.getPluginId() + ".problem";

    // Dirty sync marker
    public static final String MARKER_DIRTY = ForceIdeCorePlugin.getPluginId() + ".dirty";

    // apex code compile error marker
    public static final String MARKER_COMPILE_ERROR = ForceIdeCorePlugin.getPluginId() + ".compileError";

    // save error marker
    public static final String MARKER_SAVE_ERROR = ForceIdeCorePlugin.getPluginId() + ".saveError";

    // retrieve error marker
    public static final String MARKER_RETRIEVE_ERROR = ForceIdeCorePlugin.getPluginId() + ".retrieveError";

    // run test failure marker
    public static final String MARKER_RUN_TEST_FAILURE = ForceIdeCorePlugin.getPluginId() + ".runTestFailure";

    // code coverage warning marker
    public static final String MARKER_CODE_COVERAGE_WARNING = ForceIdeCorePlugin.getPluginId() + ".codeCoverageWarning";

    // inactive marker
    public static final String MARKER_INACTIVE = ForceIdeCorePlugin.getPluginId() + ".inactive";

    private static MarkerUtils instance = null;

    protected MarkerUtils() {}

    public static MarkerUtils getInstance() {
        if (instance == null) {
            instance = new MarkerUtils();
        }
        return instance;
    }

    /**
     * Set a dirty resource marker on the resource
     *
     * @param res
     */
    public void applyDirty(IResource[] resources) {
        if (Utils.isEmpty(resources)) {
            logger.warn("Unable to apply dirty marker to resources - resources is null or empty");
            return;
        }

        for (IResource resource : resources) {
            applyDirty(resource);
        }
    }

    public void applyDirty(IResource resource) {
        if (resource == null) {
            logger.warn("Unable to apply dirty marker to resource - resource is null");
            return;
        }

        applyDirty(resource, Messages.getString("Markers.OnlySavedLocally.message"));
    }

    /**
     * Set a dirty resource marker on the resource
     *
     * @param resource
     */
    public void applyDirty(IResource resource, String msg) {
        applyDirty(resource, MarkerUtils.MARKER_DIRTY, msg);
    }

    /**
     * Set a dirty resource marker on the resource
     *
     * @param resource
     */
    @SuppressWarnings("unchecked")
    public void applyDirty(IResource resource, String markerId, String msg) {
        if (isDirty(resource, markerId)) {
            return;
        }
        Map attributes = new HashMap(4);

        attributes.put(IMarker.MESSAGE, msg);
        // marker line numbers are 1-based: we set the marker arbitrarily on the first line
        attributes.put(IMarker.LINE_NUMBER, new Integer(1));
        attributes.put(IMarker.SEVERITY, Integer.valueOf(IMarker.SEVERITY_WARNING));
        attributes.put(IMarker.PRIORITY, Integer.valueOf(IMarker.PRIORITY_HIGH));

        createMarker(resource, attributes, markerId);
    }

    /**
     *
     * @param resource
     * @return true if the resource is dirty, false otherwise
     */
    public boolean isDirty(IResource resource) {
        return isDirty(resource, MARKER_DIRTY);
    }

    public boolean isDirty(IResource resource, String markerId) {
        IMarker[] markers = getMarkers(resource, markerId);
        if (markers.length == 0) {
            return false;
        }
        return true;
    }

    public boolean hasMarker(IResource resource, String markerId) {
        IMarker[] markers = getMarkers(resource, markerId);
        if (Utils.isEmpty(markers)) {
            return false;
        }
        for (IMarker marker : markers) {
            if (String.valueOf(marker.getId()).equals(markerId)) {
                return true;
            }
        }
        return true;
    }

    public void applyCompileErrorMarker(IResource resource, String msg) {
        applyCompileMarker(resource, 1, 1, 2, msg, IMarker.SEVERITY_ERROR);
    }

    public void applyCompileErrorMarker(IResource resource, int line, int charStart, int charEnd,
            String msg) {
        applyCompileMarker(resource, line, charStart, charEnd, msg, IMarker.SEVERITY_ERROR);
    }

    public void applyCompileWarningMarker(IResource resource, int line, int charStart, int charEnd,
            String msg) {
        applyCompileMarker(resource, line, charStart, charEnd, msg, IMarker.SEVERITY_WARNING);
    }

    public void applyCompileMarker(IResource resource, int line, int charStart, int charEnd, String msg,
            int severity) {
        if (resource == null) {
            logger.warn("Unable to apply compile " + (severity == IMarker.SEVERITY_ERROR ? "error" : "warning")
                + " marker to resource - resource is null");
            return;
        }

        String message = Messages.getString("Markers.CompilationPrefix.message") + " " + msg;
        Map<String, Object> attributes = new HashMap<String, Object>();
        attributes.put(IMarker.MESSAGE, message);
        attributes.put(IMarker.LINE_NUMBER, line);
        attributes.put(IMarker.SEVERITY, severity);
        attributes.put(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);

        createMarker(resource, attributes, MarkerUtils.MARKER_COMPILE_ERROR);
    }

    public void applySaveErrorMarker(IResource resource, String msg) {
        applySaveErrorMarker(resource, 1, 1, 2, msg);
    }

    public void applySaveErrorMarker(IResource resource, Integer line, Integer charStart, Integer charEnd,
            String msg) {
        applySaveMarker(resource, (line != null ? line : 0), (charStart != null ? charStart : 0), (charEnd != null
                ? charEnd : 0), msg, IMarker.SEVERITY_ERROR);
    }

    public void applySaveWarningMarker(IResource resource, String msg) {
        applySaveWarningMarker(resource, 1, 1, 2, msg);
    }

    public void applySaveWarningMarker(IResource resource, Integer line, Integer charStart,
            Integer charEnd, String msg) {
        applySaveMarker(resource, (line != null ? line : 0), (charStart != null ? charStart : 0), (charEnd != null
                ? charEnd : 0), msg, IMarker.SEVERITY_WARNING);
    }

    private void applySaveMarker(IResource resource, int line, int charStart, int charEnd, String msg,
            int severity) {
        if (resource == null) {
            logger.warn("Unable to apply save " + (severity == IMarker.SEVERITY_ERROR ? "error" : "warning")
                + " marker to resource - resource is null");
            return;
        }

        String message =
                Messages.getString(severity == IMarker.SEVERITY_ERROR ? "Markers.SavePrefix.Error.message"
                        : "Markers.SavePrefix.Warning.message") + " " + msg;
        Map<String, Object> attributes = new HashMap<String, Object>();
        attributes.put(IMarker.MESSAGE, message);
        attributes.put(IMarker.LINE_NUMBER, line);
        attributes.put(IMarker.SEVERITY, severity);
        attributes.put(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);

        if (logger.isInfoEnabled()) {
            logger.info("Applying save " + (severity == IMarker.SEVERITY_ERROR ? "error" : "warning") + " marker: '"
                    + resource.getProjectRelativePath().toPortableString() + "': '" + message + "'");
        }
        createMarker(resource, attributes, MarkerUtils.MARKER_SAVE_ERROR);
    }

    public void applyRetrieveErrorMarker(IResource resource, String[] componentTypes, String msg) {
        for (String componentType : componentTypes) {
            applyRetrieveErrorMarker(resource, 1, 1, 2, componentType, msg);
        }
    }

    public void applyRetrieveErrorMarker(IResource resource, String msg) {
        applyRetrieveErrorMarker(resource, 1, 1, 2, null, msg);
    }

    public void applyRetrieveErrorMarker(IResource resource, Integer line, Integer charStart,
            Integer charEnd, String componentType, String msg) {
        applyRetrieveMarker(resource, (line != null ? line : 0), (charStart != null ? charStart : 0), (charEnd != null
                ? charEnd : 0), componentType, msg, IMarker.SEVERITY_ERROR);
    }

    public void applyRetrieveWarningMarker(IResource resource, String[] componentTypes, String msg) {
        for (String componentType : componentTypes) {
            applyRetrieveWarningMarker(resource, 1, 1, 2, componentType, msg);
        }
    }

    public void applyRetrieveWarningMarker(IResource resource, String msg) {
        applyRetrieveWarningMarker(resource, 1, 1, 2, null, msg);
    }

    public void applyRetrieveWarningMarker(IResource resource, Integer line, Integer charStart,
            Integer charEnd, String componentType, String msg) {
        applyRetrieveMarker(resource, (line != null ? line : 0), (charStart != null ? charStart : 0), (charEnd != null
                ? charEnd : 0), componentType, msg, IMarker.SEVERITY_WARNING);
    }

    private void applyRetrieveMarker(IResource resource, int line, int charStart, int charEnd,
            String componentType, String msg, int severity) {
        if (resource == null) {
            logger.warn("Unable to apply retrieve " + (severity == IMarker.SEVERITY_ERROR ? "error" : "warning")
                + " marker to resource - resource is null");
            return;
        }

        String message = Messages.getString("Markers.RetrievePrefix.message") + " " + msg;
        Map<String, Object> attributes = new HashMap<String, Object>();
        attributes.put(IMarker.MESSAGE, message);
        attributes.put(IMarker.LINE_NUMBER, line);
        attributes.put(IMarker.SEVERITY, severity);
        attributes.put(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
        if (Utils.isEmpty(componentType) && msg.matches("^..*type '..*' not found")) {
            // get object type by parsing error message, ex: Entity of type 'Layout' named 'Account-kk' not found
            // this is for scenario where markers generated by refreshing from
            // server on package, src, project levels, invocation will not associated with any object type
            // consequently, when we refresh from server on component folder level afterwards, the markers won't get
            // removed properly base on object type attribute on marker.

            // FIXME - Too much assumption on this solution
            int firstSingleQuote = msg.indexOf("'");
            int secondSingleQuote = msg.indexOf("'", firstSingleQuote + 1);
            componentType = msg.substring(firstSingleQuote + 1, secondSingleQuote);
        }

        if (Utils.isNotEmpty(componentType)) {
            attributes.put(MARKER_ATTR_OBJECT_TYPE, componentType);
        }

        createMarker(resource, attributes, MarkerUtils.MARKER_RETRIEVE_ERROR);
    }

    public void applyRunTestFailureMarker(IResource resource, String msg) {
        applyRunTestFailureMarker(resource, 1, 1, 2, msg);
    }

    public void applyRunTestFailureMarker(IResource resource, int line, int charStart, int charEnd,
            String msg) {
        if (resource == null) {
            logger.warn("Unable to apply run test failure marker to resource - resource is null");
            return;
        }

        Map<String, Object> attributes = new HashMap<String, Object>();
        attributes.put(IMarker.MESSAGE, msg);
        attributes.put(IMarker.LINE_NUMBER, line);
        attributes.put(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
        attributes.put(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);

        if (logger.isInfoEnabled()) {
            logger.info("Run test failure marker on resource '" + resource.getProjectRelativePath().toPortableString()
                + "': '" + msg + "'");
        }
        createMarker(resource, attributes, MarkerUtils.MARKER_RUN_TEST_FAILURE);
    }

    public void applyCodeCoverageWarningMarker(IResource resource, String msg) {
        applyCodeCoverageWarningMarker(resource, 1, 1, 2, msg);
    }

    public void applyCodeCoverageWarningMarker(IResource resource, int line, int charStart, int charEnd,
            String msg) {
        if (resource == null) {
            logger.warn("Unable to apply code coverage warning marker to resource - resource is null");
            return;
        }

        Map<String, Object> attributes = new HashMap<String, Object>();
        attributes.put(IMarker.MESSAGE, msg);
        attributes.put(IMarker.LINE_NUMBER, line);
        attributes.put(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
        attributes.put(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);

        if (logger.isInfoEnabled()) {
            logger.info("Code coverage warning marker on resource '"
                    + resource.getProjectRelativePath().toPortableString() + "': '" + msg + "'");
        }
        createMarker(resource, attributes, MarkerUtils.MARKER_CODE_COVERAGE_WARNING);
    }

    /*
     * All apex markers
     */
    public void clearAll(IResource[] resources) {
        if (Utils.isNotEmpty(resources)) {
            for (int i = 0; i < resources.length; i++) {
                clearMarkers(resources[i], null, MarkerUtils.MARKER_PROBLEM);
            }
        }
    }

    public void clearAll(List<IResource> resources) {
        if (Utils.isNotEmpty(resources)) {
            for (IResource resource : resources) {
                clearMarkers(resource, null, MarkerUtils.MARKER_PROBLEM);
            }
        }
    }

    /**
     * Clear all apex resource markers on the resource
     *
     * @param resource
     */
    public void clearAll(IResource resource) {
        clearMarkers(resource, null, MarkerUtils.MARKER_PROBLEM);
    }

    public void clearAllRecursively(IResource resource) {
        clearMarkers(resource, null, MarkerUtils.MARKER_PROBLEM, IResource.DEPTH_INFINITE);
    }

    public void clearDirty(IResource[] resources) {
        if (Utils.isEmpty(resources)) {
            logger.warn("Unable to clear dirty markers on resources - resources is null or empty");
            return;
        }

        for (IResource resource : resources) {
            clearDirty(resource);
        }
    }

    public void clearDirty(List<IResource> resources) {
        clearDirty(resources.toArray(new IResource[0]));
    }

    /**
     * Clear dirty resource markers on the resource
     *
     * @param resource
     */
    public void clearDirty(IResource resource) {
        clearDirty(resource, MarkerUtils.MARKER_DIRTY);
    }

    public void clearDirty(IResource resource, String markerId) {
        clearMarkers(resource, null, markerId);
    }

    public void createMarker(final IResource resource, final Map<String, Object> attributes,
            final String markerType) {
        if (resource == null || !resource.exists()) {
            return;
        }

        try {

            IWorkspaceRunnable r = new IWorkspaceRunnable() {
                @Override
                public void run(IProgressMonitor monitor) throws CoreException {
                    // apply marker
                    IMarker marker = resource.createMarker(markerType);
                    marker.setAttributes(attributes);
                }
            };
            ISchedulingRule sr = getRule(resource);
            resource.getWorkspace().run(r, sr, IWorkspace.AVOID_UPDATE, null);

            if (logger.isInfoEnabled()) {
                logger.info("Applied '"
                        + markerType
                        + "' "
                        + (attributes.get(IMarker.SEVERITY) != null
                        && (Integer) attributes.get(IMarker.SEVERITY) == IMarker.SEVERITY_ERROR ? "error"
                                : "warning") + " marker on resource '" + resource.getName() + "': '"
                                + attributes.get(IMarker.MESSAGE) + "'");
            }

        } catch (CoreException e) {
            String logMessage = Utils.generateCoreExceptionLog(e);
            logger.warn("Unable to apply marker to resource: " + logMessage);
        }
    }

    private ISchedulingRule getRule(IResource resource) {
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IResourceRuleFactory ruleFactory = workspace.getRuleFactory();
        ISchedulingRule rule = ruleFactory.markerRule(resource.getProject());
        return rule;
    }

    public IMarker[] getMarkers(IResource resource, String marker) {
        return getMarkers(resource, marker, IResource.DEPTH_ZERO);
    }

    protected IMarker[] getMarkers(IResource resource, String marker, int depth) {
        IMarker[] markers = new IMarker[0];
        if (resource == null || !resource.exists()) {
            return markers;
        }

        try {
            markers = resource.findMarkers(marker, true, depth);
        } catch (CoreException e) {
            String logMessage = Utils.generateCoreExceptionLog(e);
            logger.warn(logMessage);
        }
        return markers;
    }

    public void clearMarkers(IResource resource, String componentType, String marker) {
        clearMarkers(resource, componentType, marker, IResource.DEPTH_ZERO);
    }

    public void clearMarkers(IResource resource, String componentType, String marker, int depth) {
        if (resource == null || !resource.exists()) {
            return;
        }

        IMarker[] markers = getMarkers(resource, marker, depth);
        try {
            for (IMarker element : markers) {
                if (Utils.isEmpty(componentType) || componentType.equals(element.getAttribute(MARKER_ATTR_OBJECT_TYPE))) {
                    element.delete();

                    if (logger.isDebugEnabled()) {
                        String filepath = resource.getProjectRelativePath().toPortableString();
                        logger.debug("Cleared '" + element.getId() + "' marker for '"
                                + (Utils.isNotEmpty(filepath) ? filepath : "/" + resource.getName()) + "'");
                    }
                }

            }
        } catch (CoreException e) {
            String logMessage = Utils.generateCoreExceptionLog(e);
            logger.warn("Unable to clear marker: " + logMessage);
        }
    }

    /*
     * Compile errors
     */

    public void clearCompileMarkers(IResource[] resources) {
        if (Utils.isEmpty(resources)) {
            logger.warn("Unable to clear compile markers on resources - resources is null or empty");
            return;
        }

        for (IResource resource : resources) {
            clearCompileMarkers(resource);
        }
    }

    public void clearCompileMarkers(IResource resource) {
        clearMarkers(resource, null, MarkerUtils.MARKER_COMPILE_ERROR);
    }

    public void clearSaveMarkers(List<IResource> resources) {
        if (Utils.isEmpty(resources)) {
            logger.warn("Unable to clear save markers on resources - resources is null or empty ");
            return;
        }

        for (IResource resource : resources) {
            clearSaveMarkers(resource);
        }
    }

    public void clearSaveMarkers(IResource resource) {
        clearMarkers(resource, null, MarkerUtils.MARKER_SAVE_ERROR);
    }

    public void clearRetrieveMarkers(List<IResource> resources) {
        if (Utils.isEmpty(resources)) {
            logger.warn("Unable to clear retrieve markers on resources - resources is null or empty ");
            return;
        }

        for (IResource resource : resources) {
            clearRetrieveMarkers(resource, null);
        }
    }

    public void clearRetrieveMarkers(IResource resource, String[] componentTypes) {
        if (Utils.isNotEmpty(componentTypes)) {
            for (String componentType : componentTypes) {
                clearMarkers(resource, componentType, MarkerUtils.MARKER_RETRIEVE_ERROR);
            }
        }
    }

    public void clearRunTestFailureMarkers(List<IResource> resources) {
        if (Utils.isEmpty(resources)) {
            if (logger.isInfoEnabled()) {
                logger.info("Unable to clear run tests markers on resources - resources is null or empty ");
            }
            return;
        }

        for (IResource resource : resources) {
            clearRunTestFailureMarkers(resource);
        }
    }

    public void clearRunTestFailureMarkers(IResource resource) {
        clearMarkers(resource, null, MarkerUtils.MARKER_RUN_TEST_FAILURE);
    }

    public void clearCodeCoverageWarningMarkers(List<IResource> resources) {
        if (Utils.isEmpty(resources)) {
            if (logger.isInfoEnabled()) {
                logger.info("Unable to clear coverage warning markers on resources - resources is null or empty ");
            }
            return;
        }

        for (IResource resource : resources) {
            clearRunTestFailureMarkers(resource);
        }
    }

    public void clearCodeCoverageWarningMarkers(IResource resource) {
        clearMarkers(resource, null, MarkerUtils.MARKER_CODE_COVERAGE_WARNING);
    }

}
TOP

Related Classes of com.salesforce.ide.core.project.MarkerUtils

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.