/* * ==========================================================================%%# * EasyPmd * ===========================================================================%% * Copyright (C) 2009 - 2016 Gianluca Costa * ===========================================================================%% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * ==========================================================================%## */ package info.gianlucacosta.easypmd.pmdscanner; import info.gianlucacosta.easypmd.ide.Injector; import info.gianlucacosta.easypmd.ide.options.Options; import net.sourceforge.pmd.*; import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.dfa.report.ReportTree; import java.io.*; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; /** * Scans a file using PMD */ class LinkedPmdScanningStrategy implements PmdScannerStrategy { private final LanguageVersionParser languageVersionParser; private final PMD pmd; private final RuleSets ruleSets; private final String sourceFileEncoding; public LinkedPmdScanningStrategy(Options options) { languageVersionParser = Injector.lookup(LanguageVersionParser.class); ClassLoader pmdBasedClassLoader = PmdBasedClassLoader.create(options.getAdditionalClassPathUrls()); RuleSetFactory ruleSetFactory = new RuleSetFactory(); String ruleSetsString = buildRuleSetsString(options.getRuleSets()); try { ruleSetFactory.setClassLoader(pmdBasedClassLoader); ruleSetFactory.setMinimumPriority(options.getMinimumPriority()); ruleSets = ruleSetFactory.createRuleSets(ruleSetsString); } catch (RuleSetNotFoundException ex) { throw new RuntimeException(ex); } LanguageVersion languageVersion = languageVersionParser.parse(options.getTargetJavaVersion()); sourceFileEncoding = options.getSourceFileEncoding(); pmd = new PMD(); PMDConfiguration pmdConfiguration = pmd.getConfiguration(); pmdConfiguration.setDefaultLanguageVersion(languageVersion); pmdConfiguration.setSuppressMarker(options.getSuppressMarker()); pmdConfiguration.setClassLoader(pmdBasedClassLoader); pmdConfiguration.setMinimumPriority(options.getMinimumPriority()); String auxiliaryClassPath = options.getAuxiliaryClassPath(); if (auxiliaryClassPath != null && !auxiliaryClassPath.isEmpty()) { try { pmdConfiguration.prependClasspath(auxiliaryClassPath); } catch (IOException ex) { throw new RuntimeException(ex); } } } private String buildRuleSetsString(Collection<String> ruleSets) { StringBuilder result = new StringBuilder(); Iterator<String> iterator = ruleSets.iterator(); while (iterator.hasNext()) { String ruleSet = iterator.next(); result.append(ruleSet); if (iterator.hasNext()) { result.append(","); } } return result.toString(); } @Override public ScanMessageList scanFile(File file) { String filePath = file.getAbsolutePath(); Report report = new Report(); RuleContext ruleContext = new RuleContext(); ruleContext.setReport(report); ruleContext.setSourceCodeFilename(filePath); ScanMessageList scanMessages = new ScanMessageList(); RuleSets applicableRuleSets = new RuleSets(); Iterator<RuleSet> ruleSetsIterator = ruleSets.getRuleSetsIterator(); while (ruleSetsIterator.hasNext()) { RuleSet currentRuleSet = ruleSetsIterator.next(); if (currentRuleSet.applies(file)) { applicableRuleSets.addRuleSet(currentRuleSet); } } try { try (Reader reader = new InputStreamReader(new FileInputStream(filePath), sourceFileEncoding)) { pmd.getSourceCodeProcessor().processSourceCode(reader, applicableRuleSets, ruleContext); } ReportTree violationTree = report.getViolationTree(); Iterator<RuleViolation> violationsIterator = violationTree.iterator(); while (violationsIterator.hasNext()) { RuleViolation violation = violationsIterator.next(); scanMessages.add(new ScanViolation(violation)); } } catch (IOException | PMDException ex) { scanMessages.add(new ScanError(ex)); } return scanMessages; } }