001/* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020package org.sonar.plugins.pmd; 021 022import com.google.common.annotations.VisibleForTesting; 023import com.google.common.base.Functions; 024import com.google.common.collect.ImmutableMap; 025import com.google.common.io.Closeables; 026import net.sourceforge.pmd.PMD; 027import net.sourceforge.pmd.PMDException; 028import net.sourceforge.pmd.RuleContext; 029import net.sourceforge.pmd.RuleSets; 030import net.sourceforge.pmd.SourceType; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033import org.sonar.api.resources.InputFile; 034import org.sonar.api.utils.SonarException; 035 036import java.io.File; 037import java.io.InputStream; 038import java.nio.charset.Charset; 039import java.util.Map; 040 041public class PmdTemplate { 042 private static final Logger LOG = LoggerFactory.getLogger(PmdTemplate.class); 043 044 private static final Map<String, String> JAVA_VERSIONS = ImmutableMap.of( 045 "1.1", "1.3", 046 "1.2", "1.3", 047 "5", "1.5", 048 "6", "1.6"); 049 050 private final PMD pmd; 051 052 public PmdTemplate(String javaVersion) { 053 this(new PMD()); 054 setJavaVersion(pmd, javaVersion); 055 } 056 057 @VisibleForTesting 058 PmdTemplate(PMD pmd) { 059 this.pmd = pmd; 060 } 061 062 public void process(InputFile inputFile, Charset encoding, RuleSets rulesets, RuleContext ruleContext) { 063 File file = inputFile.getFile(); 064 ruleContext.setSourceCodeFilename(file.getAbsolutePath()); 065 066 InputStream inputStream = null; 067 try { 068 inputStream = inputFile.getInputStream(); 069 070 pmd.processFile(inputStream, encoding.displayName(), rulesets, ruleContext); 071 } catch (PMDException e) { 072 LOG.error("Fail to execute PMD. Following file is ignored: " + file, e.getCause()); 073 } catch (Exception e) { 074 LOG.error("Fail to execute PMD. Following file is ignored: " + file, e); 075 } finally { 076 Closeables.closeQuietly(inputStream); 077 } 078 } 079 080 @VisibleForTesting 081 static void setJavaVersion(PMD pmd, String javaVersion) { 082 String version = normalize(javaVersion); 083 SourceType sourceType = SourceType.getSourceTypeForId("java " + version); 084 if (sourceType == null) { 085 throw new SonarException("Unsupported Java version for PMD: " + version); 086 } 087 088 LOG.info("Java version: " + version); 089 pmd.setJavaVersion(sourceType); 090 } 091 092 private static String normalize(String version) { 093 return Functions.forMap(JAVA_VERSIONS, version).apply(version); 094 } 095}