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 */ 020 package org.sonar.plugins.jacoco; 021 022 import org.apache.commons.lang.StringUtils; 023 import org.jacoco.core.runtime.AgentOptions; 024 import org.sonar.api.BatchExtension; 025 import org.sonar.api.Properties; 026 import org.sonar.api.Property; 027 import org.sonar.api.config.Settings; 028 029 @Properties({ 030 @Property( 031 key = JacocoConfiguration.REPORT_PATH_PROPERTY, 032 name = "File with execution data", 033 defaultValue = JacocoConfiguration.REPORT_PATH_DEFAULT_VALUE, 034 description = "Path (absolute or relative) to the file with execution data.", 035 global = false, 036 module = true, 037 project = true 038 ), 039 @Property( 040 key = JacocoConfiguration.INCLUDES_PROPERTY, 041 name = "Includes", 042 description = "A list of class names that should be included in execution analysis." + 043 " The list entries are separated by a colon (:) and may use wildcard characters (* and ?)." + 044 " Except for performance optimization or technical corner cases this option is normally not required.", 045 global = true, 046 project = true, 047 module = true 048 ), 049 @Property( 050 key = JacocoConfiguration.EXCLUDES_PROPERTY, 051 name = "Excludes", 052 defaultValue = JacocoConfiguration.EXCLUDES_DEFAULT_VALUE, 053 description = "A list of class names that should be excluded from execution analysis." + 054 " The list entries are separated by a colon (:) and may use wildcard characters (* and ?)." + 055 " Except for performance optimization or technical corner cases this option is normally not required.", 056 global = true, 057 project = true, 058 module = true 059 ), 060 @Property( 061 key = JacocoConfiguration.EXCLCLASSLOADER_PROPERTY, 062 name = "Excluded class loaders", 063 description = "A list of class loader names that should be excluded from execution analysis." + 064 " The list entries are separated by a colon (:) and may use wildcard characters (* and ?)." + 065 " This option might be required in case of special frameworks that conflict with JaCoCo code" + 066 " instrumentation, in particular class loaders that do not have access to the Java runtime classes.", 067 global = true, 068 project = true, 069 module = true 070 ), 071 @Property( 072 key = JacocoConfiguration.IT_REPORT_PATH_PROPERTY, 073 name = "File with execution data for integration tests", 074 defaultValue = JacocoConfiguration.IT_REPORT_PATH_DEFAULT_VALUE, 075 description = "Path (absolute or relative) to the file with execution data.", 076 global = false, 077 module = true, 078 project = true 079 ), 080 @Property( 081 key = JacocoConfiguration.ANT_TARGETS_PROPERTY, 082 name = "Ant targets", 083 defaultValue = JacocoConfiguration.ANT_TARGETS_DEFAULT_VALUE, 084 description = "Comma separated list of Ant targets for execution of tests.", 085 global = true, 086 module = true, 087 project = true 088 )}) 089 public class JacocoConfiguration implements BatchExtension { 090 091 public static final String REPORT_PATH_PROPERTY = "sonar.jacoco.reportPath"; 092 public static final String REPORT_PATH_DEFAULT_VALUE = "target/jacoco.exec"; 093 public static final String IT_REPORT_PATH_PROPERTY = "sonar.jacoco.itReportPath"; 094 public static final String IT_REPORT_PATH_DEFAULT_VALUE = ""; 095 public static final String INCLUDES_PROPERTY = "sonar.jacoco.includes"; 096 public static final String EXCLUDES_PROPERTY = "sonar.jacoco.excludes"; 097 098 /** 099 * Hibernate uses Javassist to modify entity classes and without exclusion of such classes from JaCoCo exception might be thrown: 100 * <pre> 101 * Javassist Enhancement failed: org.sonar.api.profiles.Alert 102 * java.lang.VerifyError: (class: org/sonar/api/profiles/Alert_$$_javassist_3, method: <clinit> signature: ()V) Illegal local variable number 103 * </pre> 104 */ 105 public static final String EXCLUDES_DEFAULT_VALUE = "*_javassist_*"; 106 public static final String EXCLCLASSLOADER_PROPERTY = "sonar.jacoco.exclclassloader"; 107 public static final String ANT_TARGETS_PROPERTY = "sonar.jacoco.antTargets"; 108 public static final String ANT_TARGETS_DEFAULT_VALUE = ""; 109 110 private Settings settings; 111 private JaCoCoAgentDownloader downloader; 112 113 public JacocoConfiguration(Settings settings, JaCoCoAgentDownloader downloader) { 114 this.settings = settings; 115 this.downloader = downloader; 116 } 117 118 public String getReportPath() { 119 return settings.getString(REPORT_PATH_PROPERTY); 120 } 121 122 public String getItReportPath() { 123 return settings.getString(IT_REPORT_PATH_PROPERTY); 124 } 125 126 public String getJvmArgument() { 127 AgentOptions options = new AgentOptions(); 128 options.setDestfile(getReportPath()); 129 String includes = settings.getString(INCLUDES_PROPERTY); 130 if (StringUtils.isNotBlank(includes)) { 131 options.setIncludes(includes); 132 } 133 String excludes = settings.getString(EXCLUDES_PROPERTY); 134 if (StringUtils.isNotBlank(excludes)) { 135 options.setExcludes(excludes); 136 } 137 String exclclassloader = settings.getString(EXCLCLASSLOADER_PROPERTY); 138 if (StringUtils.isNotBlank(exclclassloader)) { 139 options.setExclClassloader(exclclassloader); 140 } 141 return options.getVMArgument(downloader.getAgentJarFile()); 142 } 143 144 public String[] getAntTargets() { 145 return settings.getStringArray(ANT_TARGETS_PROPERTY); 146 } 147 148 public String getExcludes() { 149 return settings.getString(EXCLUDES_PROPERTY); 150 } 151 152 }