Package org.infernus.idea.checkstyle

Source Code of org.infernus.idea.checkstyle.CheckStyleInspection

package org.infernus.idea.checkstyle;

import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleServiceManager;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.puppycrawl.tools.checkstyle.Checker;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.infernus.idea.checkstyle.checker.CheckStyleAuditListener;
import org.infernus.idea.checkstyle.checker.CheckerContainer;
import org.infernus.idea.checkstyle.checker.CheckerFactory;
import org.infernus.idea.checkstyle.checks.Check;
import org.infernus.idea.checkstyle.checks.CheckFactory;
import org.infernus.idea.checkstyle.exception.CheckStylePluginException;
import org.infernus.idea.checkstyle.model.ConfigurationLocation;
import org.infernus.idea.checkstyle.ui.CheckStyleInspectionPanel;
import org.infernus.idea.checkstyle.util.CheckStyleUtilities;
import org.infernus.idea.checkstyle.util.IDEAUtilities;
import org.infernus.idea.checkstyle.util.ScannableFile;
import org.intellij.lang.annotations.Pattern;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
* Inspection for CheckStyle integration for IntelliJ IDEA.
*/
public class CheckStyleInspection extends LocalInspectionTool {

    private static final Log LOG = LogFactory.getLog(CheckStyleInspection.class);

    private final CheckStyleInspectionPanel configPanel = new CheckStyleInspectionPanel();

    /**
     * Produce a CheckStyle checker.
     *
     * @param checkStylePlugin the plugin.
     * @param module           the current module. May be null.
     * @return a checker.
     */
    private CheckerContainer getChecker(final CheckStylePlugin checkStylePlugin,
                                        @Nullable final Module module) {
        LOG.debug("Getting CheckStyle checker for inspection.");

        if (module == null) {
            return null;
        }

        ConfigurationLocation configurationLocation = null;
        try {
            configurationLocation = getConfigurationLocation(module, checkStylePlugin);
            if (configurationLocation == null) {
                return null;
            }

            if (configurationLocation.isBlacklisted()) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Configuration is blacklisted, skipping: " + configurationLocation);
                }
                return null;
            }

            LOG.info("Loading configuration from " + configurationLocation);
            return getCheckerFactory().getChecker(configurationLocation, module);

        } catch (Exception e) {
            LOG.error("Checker could not be created.", e);

            if (configurationLocation != null) {
                configurationLocation.blacklist();
            }

            throw new CheckStylePluginException("Couldn't create Checker", e);
        }
    }

    private CheckStylePlugin getPlugin(final Project project) {
        final CheckStylePlugin checkStylePlugin = project.getComponent(CheckStylePlugin.class);
        if (checkStylePlugin == null) {
            throw new IllegalStateException("Couldn't get checkstyle plugin");
        }
        return checkStylePlugin;
    }

    private CheckerFactory getCheckerFactory() {
        return ServiceManager.getService(CheckerFactory.class);
    }

    private ConfigurationLocation getConfigurationLocation(final Module module,
                                                           final CheckStylePlugin checkStylePlugin) {
        final ConfigurationLocation configurationLocation;
        if (module != null) {
            final CheckStyleModuleConfiguration moduleConfiguration
                    = ModuleServiceManager.getService(module, CheckStyleModuleConfiguration.class);
            if (moduleConfiguration == null) {
                throw new IllegalStateException("Couldn't get checkstyle module configuration");
            }

            if (moduleConfiguration.isExcluded()) {
                configurationLocation = null;
            } else {
                configurationLocation = moduleConfiguration.getActiveConfiguration();
            }

        } else {
            configurationLocation = checkStylePlugin.getConfiguration().getActiveConfiguration();
        }
        return configurationLocation;
    }

    /**
     * Retrieve a CheckStyle configuration.
     *
     * @param checkStylePlugin the plugin.
     * @param module           the current module. May be null.
     * @return a checkstyle configuration.
     */
    private Configuration getConfig(final CheckStylePlugin checkStylePlugin,
                                    final Module module) {
        LOG.debug("Getting CheckStyle checker for inspection.");

        try {
            final ConfigurationLocation configurationLocation = getConfigurationLocation(module, checkStylePlugin);
            if (configurationLocation == null) {
                return null;
            }

            LOG.info("Loading configuration from " + configurationLocation);
            return getCheckerFactory().getConfig(configurationLocation, module);

        } catch (Exception e) {
            LOG.error("Checker could not be created.", e);
            throw new CheckStylePluginException("Couldn't create Checker", e);
        }
    }

    @Nullable
    public JComponent createOptionsPanel() {
        return configPanel;
    }

    @NotNull
    public String getGroupDisplayName() {
        return IDEAUtilities.getResource("plugin.group", "CheckStyle");
    }

    @NotNull
    public String getDisplayName() {
        return IDEAUtilities.getResource("plugin.display-name",
                "Real-time scan");
    }

    @Pattern("[a-zA-Z_0-9.-]+")
    @NotNull
    @Override
    public String getID() {
        return CheckStyleConstants.ID_INSPECTION;
    }

    @NotNull
    @NonNls
    public String getShortName() {
        return CheckStyleConstants.ID_PLUGIN;
    }

    @Nullable
    public ProblemDescriptor[] checkFile(@NotNull final PsiFile psiFile,
                                         @NotNull final InspectionManager manager,
                                         final boolean isOnTheFly) {
        LOG.debug("Inspection has been invoked.");

        try {
            if (!psiFile.isValid() || !psiFile.isPhysical()) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Skipping file as invalid: " + psiFile.getName());
                }
                return null;
            }

            final CheckStylePlugin checkStylePlugin = getPlugin(manager.getProject());

            if (!checkStylePlugin.getConfiguration().isScanningNonJavaFiles()
                    && !CheckStyleUtilities.isJavaFile(psiFile.getFileType())) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Skipping as file is not a Java file: " + psiFile.getName());
                }
                return null;
            }

            final Module module = ModuleUtil.findModuleForPsiElement(psiFile);

            final boolean checkTestClasses = checkStylePlugin.getConfiguration().isScanningTestClasses();
            if (!checkTestClasses && module != null) {
                final VirtualFile elementFile = psiFile.getContainingFile().getVirtualFile();
                if (elementFile != null) {
                    final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
                    if (moduleRootManager != null && moduleRootManager.getFileIndex().isInTestSourceContent(elementFile)) {
                        if (LOG.isDebugEnabled()) {
                            LOG.debug("Skipping test class " + psiFile.getName());
                        }
                        return null;
                    }
                }
            }

            return scanFile(psiFile, manager, checkStylePlugin, module);

        } catch (ProcessCanceledException e) {
            LOG.warn("Process cancelled when scanning: " + psiFile.getName());
            return null;

        } catch (AssertionError e) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Assertion error caught, exiting quietly", e);
            }
            return null;

        } catch (Throwable e) {
            final CheckStylePluginException processed = CheckStylePlugin.processError(
                    "The inspection could not be executed.", e);
            LOG.error("The inspection could not be executed.", processed);

            return null;
        }
    }

    private ProblemDescriptor[] scanFile(final PsiFile psiFile,
                                         final InspectionManager manager,
                                         final CheckStylePlugin checkStylePlugin,
                                         final Module module)
            throws IOException {
        ScannableFile scannableFile = null;
        try {
            final CheckerContainer checkerContainer = getChecker(checkStylePlugin, module);
            final Configuration config = getConfig(checkStylePlugin, module);
            if (checkerContainer == null || config == null) {
                return new ProblemDescriptor[0];
            }

            final List<Check> checks = CheckFactory.getChecks(config);

            final Document fileDocument = PsiDocumentManager.getInstance(
                    manager.getProject()).getDocument(psiFile);
            if (fileDocument == null) {
                LOG.debug("Skipping check - file is binary or has no document: " + psiFile.getName());
                return null;
            }

            scannableFile = new ScannableFile(psiFile, module);

            final Map<String, PsiFile> filesToScan = Collections.singletonMap(scannableFile.getAbsolutePath(), psiFile);

            final boolean suppressingErrors = checkStylePlugin.getConfiguration().isSuppressingErrors();
            final CheckStyleAuditListener listener = new CheckStyleAuditListener(
                    filesToScan, manager, false, suppressingErrors, checkerContainer.getTabWidth(), checks);
            final Checker checker = checkerContainer.getChecker();
            synchronized (checker) {
                checker.addListener(listener);
                checker.process(Arrays.asList(scannableFile.getFile()));
                checker.removeListener(listener);
            }

            final List<ProblemDescriptor> problems = listener.getProblems(psiFile);
            return problems.toArray(new ProblemDescriptor[problems.size()]);

        } finally {
            if (scannableFile != null) {
                scannableFile.deleteIfRequired();
            }
        }
    }

}
TOP

Related Classes of org.infernus.idea.checkstyle.CheckStyleInspection

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.