aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2015-02-15 23:32:14 +0100
committerSimon Brandhof <simon.brandhof@sonarsource.com>2015-02-19 12:02:10 +0100
commit7cf57c2495bd16c2e7056c0ff47fc962a8ff432f (patch)
treea4a0124029e70fbcc45d00429da495d0058b7a49 /sonar-plugin-api
parent6658f59ae96921016438eeeab136a4eb4e5703af (diff)
downloadsonarqube-7cf57c2495bd16c2e7056c0ff47fc962a8ff432f.tar.gz
sonarqube-7cf57c2495bd16c2e7056c0ff47fc962a8ff432f.zip
SONAR-5700 New logging API to remove coupling on SLF4J
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r--sonar-plugin-api/pom.xml48
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/maven/MavenUtils.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentKeys.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/Languages.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoader.java7
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/LocalizedMessages.java18
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/TimeProfiler.java17
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/ValidationMessages.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/XpathParser.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/command/CommandExecutor.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/BaseLogger.java169
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleFormatter.java39
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLogger.java148
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLoggers.java40
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ListInterceptor.java57
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptor.java35
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java100
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java124
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLoggers.java46
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java89
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Loggers.java53
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/NullInterceptor.java56
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/internal/InMemoryLogger.java88
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/internal/Slf4jLoggers.java54
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/package-info.java25
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/platform/ComponentKeysTest.java6
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/TimeProfilerTest.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/ValidationMessagesTest.java7
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java41
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggerTest.java82
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggersTest.java47
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogTesterTest.java61
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogbackLoggerTest.java69
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LoggersTest.java37
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/NullInterceptorTest.java37
39 files changed, 1442 insertions, 206 deletions
diff --git a/sonar-plugin-api/pom.xml b/sonar-plugin-api/pom.xml
index 6eeb77a9630..fef2a0bed26 100644
--- a/sonar-plugin-api/pom.xml
+++ b/sonar-plugin-api/pom.xml
@@ -34,10 +34,22 @@
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-colorizer</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-duplications</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.sonar</groupId>
@@ -46,6 +58,12 @@
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-squid</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<!-- TODO we can't remove hibernate-annotations, because currently it's used
@@ -54,11 +72,16 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
+ <scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
</exclusions>
</dependency>
@@ -96,18 +119,12 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
+ <optional>true</optional>
</dependency>
<dependency>
<groupId>xpp3</groupId>
<artifactId>xpp3</artifactId>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.woodstox</groupId>
@@ -133,6 +150,16 @@
<version>3.0.1</version>
<optional>true</optional>
</dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <optional>true</optional>
+ </dependency>
<!-- unit tests -->
<dependency>
@@ -141,11 +168,6 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<scope>test</scope>
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/maven/MavenUtils.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/maven/MavenUtils.java
index 6fc76d56d9a..655edcdbecb 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/maven/MavenUtils.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/maven/MavenUtils.java
@@ -23,7 +23,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.project.MavenProject;
-import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.log.Loggers;
import java.nio.charset.Charset;
import java.util.Collection;
@@ -142,7 +142,7 @@ public final class MavenUtils {
return Charset.forName(encoding);
} catch (Exception e) {
- LoggerFactory.getLogger(MavenUtils.class).warn("Can not get project charset", e);
+ Loggers.get(MavenUtils.class).warn("Can not get project charset", e);
}
}
return Charset.defaultCharset();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentKeys.java b/sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentKeys.java
index 3a603649e3b..56de51f17e1 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentKeys.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentKeys.java
@@ -20,9 +20,9 @@
package org.sonar.api.platform;
import com.google.common.annotations.VisibleForTesting;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sonar.api.utils.internal.Uuids;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import java.util.HashSet;
import java.util.Set;
@@ -37,7 +37,7 @@ class ComponentKeys {
private final Set<Class> objectsWithoutToString = new HashSet<Class>();
Object of(Object component) {
- return of(component, LoggerFactory.getLogger(ComponentKeys.class));
+ return of(component, Loggers.get(ComponentKeys.class));
}
@VisibleForTesting
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Languages.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Languages.java
index 62590f42f36..055b3897c1d 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Languages.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Languages.java
@@ -21,10 +21,10 @@ package org.sonar.api.resources;
import com.google.common.collect.Maps;
import org.apache.commons.lang.ArrayUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import java.util.ArrayList;
import java.util.Arrays;
@@ -39,7 +39,7 @@ import java.util.Map;
*/
public class Languages implements BatchComponent, ServerComponent {
- private static final Logger LOG = LoggerFactory.getLogger(Languages.class);
+ private static final Logger LOG = Loggers.get(Languages.class);
private final Map<String, Language> map = Maps.newLinkedHashMap();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java
index 3d963373c22..7f19e8214cd 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java
@@ -20,8 +20,8 @@
package org.sonar.api.rules;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
-import org.slf4j.LoggerFactory;
import org.sonar.api.resources.Resource;
+import org.sonar.api.utils.log.Loggers;
import java.util.Date;
@@ -128,7 +128,7 @@ public class Violation {
public Violation setLineId(Integer lineId) {
if (lineId != null && lineId < 1) {
// TODO this normalization was added in 2.8, throw exception in future versions - see http://jira.codehaus.org/browse/SONAR-2386
- LoggerFactory.getLogger(getClass()).warn("line must not be less than 1 - in future versions this will cause IllegalArgumentException");
+ Loggers.get(getClass()).warn("line must not be less than 1 - in future versions this will cause IllegalArgumentException");
this.lineId = null;
} else {
this.lineId = lineId;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java
index f26cad3ae4c..6caa31b5217 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java
@@ -23,11 +23,11 @@ import com.google.common.base.Strings;
import com.google.common.collect.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
-import org.slf4j.LoggerFactory;
import org.sonar.api.ServerExtension;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.debt.DebtRemediationFunction;
+import org.sonar.api.utils.log.Loggers;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@@ -448,7 +448,7 @@ public interface RulesDefinition extends ServerExtension {
// Should fail in a perfect world, but at the time being the Findbugs plugin
// defines several times the rule EC_INCOMPATIBLE_ARRAY_COMPARE
// See http://jira.codehaus.org/browse/SONARJAVA-428
- LoggerFactory.getLogger(getClass()).warn(String.format("The rule '%s' of repository '%s' is declared several times", ruleKey, key));
+ Loggers.get(getClass()).warn(String.format("The rule '%s' of repository '%s' is declared several times", ruleKey, key));
}
NewRule newRule = new NewRule(key, ruleKey);
newRules.put(ruleKey, newRule);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoader.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoader.java
index 0c2a08f3dcc..d7b49912f4d 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoader.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoader.java
@@ -24,14 +24,15 @@ import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.utils.AnnotationUtils;
import org.sonar.api.utils.FieldUtils2;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import org.sonar.check.Cardinality;
import javax.annotation.CheckForNull;
+
import java.lang.reflect.Field;
import java.util.List;
@@ -44,7 +45,7 @@ import java.util.List;
*/
public class RulesDefinitionAnnotationLoader {
- private static final Logger LOG = LoggerFactory.getLogger(RulesDefinitionAnnotationLoader.class);
+ private static final Logger LOG = Loggers.get(RulesDefinitionAnnotationLoader.class);
private static final Function<Class<?>, RuleParamType> TYPE_FOR_CLASS = Functions.forMap(
ImmutableMap.<Class<?>, RuleParamType>builder()
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java
index b0cce8cdbc2..054ba773196 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java
@@ -22,9 +22,9 @@ package org.sonar.api.server.ws.internal;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
-import org.slf4j.LoggerFactory;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.log.Loggers;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@@ -106,7 +106,7 @@ public abstract class ValidatingRequest extends Request {
private String readParamOrDefaultValue(String key, @Nullable WebService.Param definition) {
if (definition == null) {
String message = String.format("BUG - parameter '%s' is undefined for action '%s'", key, action.key());
- LoggerFactory.getLogger(getClass()).error(message);
+ Loggers.get(getClass()).error(message);
throw new IllegalArgumentException(message);
}
String deprecatedKey = definition.deprecatedKey();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java
index 2df7765ff2b..ee0ba26214c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java
@@ -32,11 +32,11 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
-import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.api.config.Settings;
import org.sonar.api.platform.Server;
+import org.sonar.api.utils.log.Loggers;
import javax.annotation.Nullable;
@@ -271,7 +271,7 @@ public class HttpDownloader extends UriReader.SchemeProcessor implements BatchCo
@Override
public InputStream getInput() throws IOException {
- LoggerFactory.getLogger(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri, ProxySelector.getDefault()) + ")");
+ Loggers.get(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri, ProxySelector.getDefault()) + ")");
HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
connection.setRequestMethod(requestMethod);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/LocalizedMessages.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/LocalizedMessages.java
index 55df7e312ee..00ba41a1d4b 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/LocalizedMessages.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/LocalizedMessages.java
@@ -21,14 +21,22 @@ package org.sonar.api.utils;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.*;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.Set;
public class LocalizedMessages extends ResourceBundle {
- private static final Logger LOG = LoggerFactory.getLogger(LocalizedMessages.class);
+ private static final Logger LOG = Loggers.get(LocalizedMessages.class);
private Locale locale;
private List<ResourceBundle> bundles;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/TimeProfiler.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/TimeProfiler.java
index 10b264d5124..ce86e880cdb 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/TimeProfiler.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/TimeProfiler.java
@@ -19,8 +19,8 @@
*/
package org.sonar.api.utils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
/**
* A very simple profiler to log the time elapsed performing some tasks.
@@ -39,15 +39,24 @@ public class TimeProfiler {
this.logger = logger;
}
+ /**
+ * @deprecated do not use SLF4J but org.sonar.api.utils.log.Logger
+ * @since 5.1
+ */
+ @Deprecated
+ public TimeProfiler(org.slf4j.Logger logger) {
+ this.logger = Loggers.get(logger.getName());
+ }
+
public TimeProfiler(Class clazz) {
- this.logger = LoggerFactory.getLogger(clazz);
+ this.logger = Loggers.get(clazz);
}
/**
* Use the default Sonar logger
*/
public TimeProfiler() {
- this.logger = LoggerFactory.getLogger(getClass());
+ this.logger = Loggers.get(getClass());
}
public TimeProfiler start(String name) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/ValidationMessages.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/ValidationMessages.java
index 4dffb8e57a7..e2455ef29e2 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/ValidationMessages.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/ValidationMessages.java
@@ -21,7 +21,7 @@ package org.sonar.api.utils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
-import org.slf4j.Logger;
+import org.sonar.api.utils.log.Logger;
import java.util.ArrayList;
import java.util.List;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/XpathParser.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/XpathParser.java
index 4b40db12e86..e206847699b 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/XpathParser.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/XpathParser.java
@@ -21,8 +21,8 @@ package org.sonar.api.utils;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -78,7 +78,7 @@ public class XpathParser {
bf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
bf.setFeature("http://apache.org/xml/features/allow-java-encodings", true);
} catch (ParserConfigurationException e) {
- Logger log = LoggerFactory.getLogger(this.getClass().getName());
+ Logger log = Loggers.get(this.getClass().getName());
log.error("Error occured during features set up.", e);
}
try {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/CommandExecutor.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/CommandExecutor.java
index 799d8896a21..e395c8ab820 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/CommandExecutor.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/CommandExecutor.java
@@ -21,8 +21,8 @@ package org.sonar.api.utils.command;
import com.google.common.base.Charsets;
import com.google.common.io.Closeables;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import javax.annotation.Nullable;
@@ -44,7 +44,7 @@ import java.util.concurrent.TimeUnit;
*/
public class CommandExecutor {
- private static final Logger LOG = LoggerFactory.getLogger(CommandExecutor.class);
+ private static final Logger LOG = Loggers.get(CommandExecutor.class);
private static final CommandExecutor INSTANCE = new CommandExecutor();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/BaseLogger.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/BaseLogger.java
new file mode 100644
index 00000000000..7dbec222096
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/BaseLogger.java
@@ -0,0 +1,169 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import javax.annotation.Nullable;
+
+abstract class BaseLogger implements Logger {
+ @Override
+ public void debug(String msg) {
+ LogInterceptor.instance.log(msg);
+ doDebug(msg);
+ }
+
+ @Override
+ public void debug(String pattern, @Nullable Object arg) {
+ LogInterceptor.instance.log(pattern, arg);
+ doDebug(pattern, arg);
+ }
+
+ @Override
+ public void debug(String msg, @Nullable Object arg1, @Nullable Object arg2) {
+ LogInterceptor.instance.log(msg, arg1, arg2);
+ doDebug(msg, arg1, arg2);
+ }
+
+ @Override
+ public void debug(String msg, Object... args) {
+ LogInterceptor.instance.log(msg, args);
+ doDebug(msg, args);
+ }
+
+ @Override
+ public void info(String msg) {
+ LogInterceptor.instance.log(msg);
+ doInfo(msg);
+ }
+
+ @Override
+ public void info(String msg, @Nullable Object arg) {
+ LogInterceptor.instance.log(msg, arg);
+ doInfo(msg, arg);
+ }
+
+ @Override
+ public void info(String msg, @Nullable Object arg1, @Nullable Object arg2) {
+ LogInterceptor.instance.log(msg, arg1, arg2);
+ doInfo(msg, arg1, arg2);
+ }
+
+ @Override
+ public void info(String msg, Object... args) {
+ LogInterceptor.instance.log(msg, args);
+ doInfo(msg, args);
+ }
+
+ @Override
+ public void warn(String msg) {
+ LogInterceptor.instance.log(msg);
+ doWarn(msg);
+ }
+
+ @Override
+ public void warn(String msg, @Nullable Object arg) {
+ LogInterceptor.instance.log(msg, arg);
+ doWarn(msg, arg);
+ }
+
+ @Override
+ public void warn(String msg, @Nullable Object arg1, @Nullable Object arg2) {
+ LogInterceptor.instance.log(msg, arg1, arg2);
+ doWarn(msg, arg1, arg2);
+ }
+
+ @Override
+ public void warn(String msg, Object... args) {
+ LogInterceptor.instance.log(msg, args);
+ doWarn(msg, args);
+ }
+
+ @Override
+ public void error(String msg) {
+ LogInterceptor.instance.log(msg);
+ doError(msg);
+ }
+
+ @Override
+ public void error(String msg, @Nullable Object arg) {
+ LogInterceptor.instance.log(msg, arg);
+ doError(msg, arg);
+ }
+
+ @Override
+ public void error(String msg, @Nullable Object arg1, @Nullable Object arg2) {
+ LogInterceptor.instance.log(msg, arg1, arg2);
+ doError(msg, arg1, arg2);
+ }
+
+ @Override
+ public void error(String msg, Object... args) {
+ LogInterceptor.instance.log(msg, args);
+ doError(msg, args);
+ }
+
+ @Override
+ public void error(String msg, Throwable thrown) {
+ LogInterceptor.instance.log(msg, thrown);
+ doError(msg, thrown);
+ }
+
+ abstract void doDebug(String msg);
+
+ abstract void doDebug(String msg, @Nullable Object arg);
+
+ abstract void doDebug(String msg, @Nullable Object arg1, @Nullable Object arg2);
+
+ abstract void doDebug(String msg, Object... args);
+
+ /**
+ * Logs an INFO level message.
+ */
+ abstract void doInfo(String msg);
+
+ abstract void doInfo(String msg, @Nullable Object arg);
+
+ abstract void doInfo(String msg, @Nullable Object arg1, @Nullable Object arg2);
+
+ abstract void doInfo(String msg, Object... args);
+
+ /**
+ * Logs a WARN level message.
+ */
+ abstract void doWarn(String msg);
+
+ abstract void doWarn(String msg, @Nullable Object arg);
+
+ abstract void doWarn(String msg, @Nullable Object arg1, @Nullable Object arg2);
+
+ abstract void doWarn(String msg, Object... args);
+
+ /**
+ * Logs an ERROR level message.
+ */
+ abstract void doError(String msg);
+
+ abstract void doError(String msg, @Nullable Object arg);
+
+ abstract void doError(String msg, @Nullable Object arg1, @Nullable Object arg2);
+
+ abstract void doError(String msg, Object... args);
+
+ abstract void doError(String msg, Throwable thrown);
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleFormatter.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleFormatter.java
new file mode 100644
index 00000000000..21247843ed2
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleFormatter.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import org.apache.commons.lang.StringUtils;
+
+import java.util.Objects;
+
+class ConsoleFormatter {
+
+ private ConsoleFormatter() {
+ // only static methods
+ }
+
+ static String format(String pattern, Object... args) {
+ String result = pattern;
+ for (Object arg : args) {
+ result = StringUtils.replaceOnce(result, "{}", Objects.toString(arg));
+ }
+ return result;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLogger.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLogger.java
new file mode 100644
index 00000000000..93af4ef8785
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLogger.java
@@ -0,0 +1,148 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import javax.annotation.Nullable;
+
+import java.io.PrintStream;
+
+import static org.sonar.api.utils.log.ConsoleFormatter.format;
+
+/**
+ * Slow implementation based on {@link java.lang.System#out}. It is not production-ready and it must be used
+ * only for the tests that do not have logback dependency.
+ * <p/>Implementation of message patterns is naive. It does not support escaped '{' and '}'
+ * arguments.
+ */
+class ConsoleLogger extends BaseLogger {
+
+ private final PrintStream stream;
+
+ ConsoleLogger(String unusedName) {
+ this.stream = System.out;
+ }
+
+ ConsoleLogger(PrintStream stream) {
+ this.stream = stream;
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return Loggers.getFactory().isDebugEnabled();
+ }
+
+ @Override
+ protected void doDebug(String msg) {
+ if (isDebugEnabled()) {
+ log("DEBUG", msg);
+ }
+ }
+
+ @Override
+ protected void doDebug(String pattern, @Nullable Object arg) {
+ if (isDebugEnabled()) {
+ debug(format(pattern, arg));
+ }
+ }
+
+ @Override
+ protected void doDebug(String pattern, @Nullable Object arg1, @Nullable Object arg2) {
+ if (isDebugEnabled()) {
+ debug(format(pattern, arg1, arg2));
+ }
+ }
+
+ @Override
+ protected void doDebug(String pattern, Object... args) {
+ if (isDebugEnabled()) {
+ debug(format(pattern, args));
+ }
+ }
+
+ @Override
+ protected void doInfo(String msg) {
+ log("INFO ", msg);
+ }
+
+ @Override
+ protected void doInfo(String pattern, @Nullable Object arg) {
+ info(format(pattern, arg));
+ }
+
+ @Override
+ protected void doInfo(String pattern, @Nullable Object arg1, @Nullable Object arg2) {
+ info(format(pattern, arg1, arg2));
+ }
+
+ @Override
+ protected void doInfo(String pattern, Object... args) {
+ info(format(pattern, args));
+ }
+
+ @Override
+ protected void doWarn(String msg) {
+ log("WARN ", msg);
+ }
+
+ @Override
+ protected void doWarn(String pattern, @Nullable Object arg) {
+ warn(format(pattern, arg));
+ }
+
+ @Override
+ protected void doWarn(String pattern, @Nullable Object arg1, @Nullable Object arg2) {
+ warn(format(pattern, arg1, arg2));
+ }
+
+ @Override
+ protected void doWarn(String pattern, Object... args) {
+ warn(format(pattern, args));
+ }
+
+ @Override
+ protected void doError(String msg) {
+ log("ERROR", msg);
+ }
+
+ @Override
+ protected void doError(String pattern, @Nullable Object arg) {
+ error(format(pattern, arg));
+ }
+
+ @Override
+ protected void doError(String pattern, @Nullable Object arg1, @Nullable Object arg2) {
+ error(format(pattern, arg1, arg2));
+ }
+
+ @Override
+ protected void doError(String pattern, Object... args) {
+ error(format(pattern, args));
+ }
+
+ @Override
+ public void doError(String msg, Throwable thrown) {
+ doError(msg);
+ thrown.printStackTrace();
+ }
+
+ private void log(String level, String msg) {
+ this.stream.println(String.format("%s %s", level, msg));
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLoggers.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLoggers.java
new file mode 100644
index 00000000000..a6a2f2524a0
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLoggers.java
@@ -0,0 +1,40 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+class ConsoleLoggers extends Loggers {
+
+ private boolean debugEnabled = false;
+
+ @Override
+ protected Logger newInstance(String name) {
+ return new ConsoleLogger(name);
+ }
+
+ @Override
+ protected boolean isDebugEnabled() {
+ return debugEnabled;
+ }
+
+ @Override
+ protected void enableDebug(boolean b) {
+ this.debugEnabled = b;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ListInterceptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ListInterceptor.java
new file mode 100644
index 00000000000..94aa6dad39a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ListInterceptor.java
@@ -0,0 +1,57 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class ListInterceptor extends LogInterceptor {
+
+ private final List<String> logs = new ArrayList<>();
+
+ @Override
+ public void log(String msg) {
+ logs.add(msg);
+ }
+
+ @Override
+ public void log(String msg, Object arg) {
+ logs.add(ConsoleFormatter.format(msg, arg));
+ }
+
+ @Override
+ public void log(String msg, Object arg1, Object arg2) {
+ logs.add(ConsoleFormatter.format(msg, arg1, arg2));
+ }
+
+ @Override
+ public void log(String msg, Object... args) {
+ logs.add(ConsoleFormatter.format(msg, args));
+ }
+
+ @Override
+ public void log(String msg, Throwable thrown) {
+ logs.add(msg);
+ }
+
+ public List<String> logs() {
+ return logs;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptor.java
new file mode 100644
index 00000000000..aab01e6a359
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptor.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+abstract class LogInterceptor {
+
+ static LogInterceptor instance = NullInterceptor.NULL_INSTANCE;
+
+ abstract void log(String msg);
+
+ abstract void log(String msg, Object arg);
+
+ abstract void log(String msg, Object arg1, Object arg2);
+
+ abstract void log(String msg, Object... args);
+
+ abstract void log(String msg, Throwable thrown);
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java
new file mode 100644
index 00000000000..9ee625e0c62
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java
@@ -0,0 +1,100 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import org.junit.rules.ExternalResource;
+
+import java.util.List;
+
+/**
+ * <b>For tests only</b>
+ * <p/>
+ * This JUnit rule allows to configure and access logs in tests. By default
+ * debug logs are enabled.
+ * <p/>
+ * Warning - not compatible with parallel execution of tests.
+ * <p/>
+ * Example:
+ * <pre>
+ * public class MyClass {
+ * private final Logger logger = Loggers.get("logger_name");
+ *
+ * public void doSomething() {
+ * logger.info("foo");
+ * }
+ * }
+ *
+ * public class MyTest {
+ * &#064;Rule
+ * public LogTester logTester = new LogTester();
+ *
+ * &#064;Test
+ * public void test_log() {
+ * new MyClass().doSomething();
+ *
+ * assertThat(logTester.logs()).containsOnly("foo");
+ * }
+ * }
+ * </pre>
+ *
+ * @since 5.1
+ */
+public class LogTester extends ExternalResource {
+
+ private boolean initialDebugMode;
+
+ @Override
+ protected void before() throws Throwable {
+ initialDebugMode = Loggers.getFactory().isDebugEnabled();
+
+ // this shared instance breaks compatibility with parallel execution of tests
+ LogInterceptor.instance = new ListInterceptor();
+ enableDebug(true);
+ }
+
+ @Override
+ protected void after() {
+ enableDebug(initialDebugMode);
+ LogInterceptor.instance = NullInterceptor.NULL_INSTANCE;
+ }
+
+ /**
+ * @see #enableDebug(boolean)
+ */
+ public boolean isDebugEnabled() {
+ return Loggers.getFactory().isDebugEnabled();
+ }
+
+ /**
+ * Enable/disable debug logs. Info, warn and error logs are always enabled.
+ * By default debug logs are enabled when LogTester is started.
+ */
+ public LogTester enableDebug(boolean b) {
+ Loggers.getFactory().enableDebug(b);
+ return this;
+ }
+
+ /**
+ * Logs in chronological order (item at index 0 is the oldest one)
+ */
+ public List<String> logs() {
+ return ((ListInterceptor) LogInterceptor.instance).logs();
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java
new file mode 100644
index 00000000000..7313a2fc2a5
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java
@@ -0,0 +1,124 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import javax.annotation.Nullable;
+
+/**
+ * Note that logback is accessed through SLF4J
+ */
+class LogbackLogger extends BaseLogger {
+
+ private final transient org.slf4j.Logger slf4j;
+
+ LogbackLogger(org.slf4j.Logger slf4j) {
+ this.slf4j = slf4j;
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return slf4j.isDebugEnabled();
+ }
+
+ @Override
+ protected void doDebug(String msg) {
+ slf4j.debug(msg);
+ }
+
+ @Override
+ protected void doDebug(String msg, @Nullable Object arg) {
+ slf4j.debug(msg, arg);
+ }
+
+ @Override
+ protected void doDebug(String msg, @Nullable Object arg1, @Nullable Object arg2) {
+ slf4j.debug(msg, arg1, arg2);
+ }
+
+ @Override
+ protected void doDebug(String msg, Object... args) {
+ slf4j.debug(msg, args);
+ }
+
+ @Override
+ protected void doInfo(String msg) {
+ slf4j.info(msg);
+ }
+
+ @Override
+ protected void doInfo(String msg, @Nullable Object arg) {
+ slf4j.info(msg, arg);
+ }
+
+ @Override
+ protected void doInfo(String msg, @Nullable Object arg1, @Nullable Object arg2) {
+ slf4j.info(msg, arg1, arg2);
+ }
+
+ @Override
+ protected void doInfo(String msg, Object... args) {
+ slf4j.info(msg, args);
+ }
+
+ @Override
+ protected void doWarn(String msg) {
+ slf4j.warn(msg);
+ }
+
+ @Override
+ protected void doWarn(String msg, @Nullable Object arg) {
+ slf4j.warn(msg, arg);
+ }
+
+ @Override
+ protected void doWarn(String msg, @Nullable Object arg1, @Nullable Object arg2) {
+ slf4j.warn(msg, arg1, arg2);
+ }
+
+ @Override
+ protected void doWarn(String msg, Object... args) {
+ slf4j.warn(msg, args);
+ }
+
+ @Override
+ protected void doError(String msg) {
+ slf4j.error(msg);
+ }
+
+ @Override
+ protected void doError(String msg, @Nullable Object arg) {
+ slf4j.error(msg, arg);
+ }
+
+ @Override
+ protected void doError(String msg, @Nullable Object arg1, @Nullable Object arg2) {
+ slf4j.error(msg, arg1, arg2);
+ }
+
+ @Override
+ protected void doError(String msg, Object... args) {
+ slf4j.error(msg, args);
+ }
+
+ @Override
+ protected void doError(String msg, Throwable thrown) {
+ slf4j.error(msg, thrown);
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLoggers.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLoggers.java
new file mode 100644
index 00000000000..e4490a79e3a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLoggers.java
@@ -0,0 +1,46 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import ch.qos.logback.classic.Level;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Note that this is not "Slf4jLoggers" as there's a coupling on Logback
+ * in order to change level of root logger.
+ */
+class LogbackLoggers extends Loggers {
+
+ @Override
+ protected Logger newInstance(String name) {
+ return new LogbackLogger(LoggerFactory.getLogger(name));
+ }
+
+ @Override
+ protected boolean isDebugEnabled() {
+ return LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME).isDebugEnabled();
+ }
+
+ @Override
+ protected void enableDebug(boolean b) {
+ ch.qos.logback.classic.Logger logback = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
+ logback.setLevel(b ? Level.DEBUG : Level.INFO);
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java
index dab1503bce8..834dc235661 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java
@@ -1,16 +1,95 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.sonar.api.utils.log;
+import javax.annotation.Nullable;
+
+/**
+ * SonarQube plugins are not coupled with external logging libraries like SLF4J or Logback.
+ *
+ * Example:
+ * <pre>
+ * public class MyClass {
+ * private final Logger logger = Loggers.get("logger_name");
+ *
+ * public void doSomething() {
+ * logger.info("something valuable for production environment");
+ * logger.warn("message with arguments {} and {}", "foo", 42);
+ * }
+ * }
+ * </pre>
+ *
+ * See {@link org.sonar.api.utils.log.LogTester} for testing facilities.
+ * @since 5.1
+ */
public interface Logger {
boolean isDebugEnabled();
- void debug(String message);
+ /**
+ * Logs a DEBUG level message. Debug messages must
+ * be valuable for production environments and are not for development debugging.
+ */
+ void debug(String msg);
+
+ void debug(String pattern, @Nullable Object arg);
+
+ void debug(String msg, @Nullable Object arg1, @Nullable Object arg2);
+
+ void debug(String msg, Object... args);
+
+ /**
+ * Logs an INFO level message.
+ */
+ void info(String msg);
+
+ void info(String msg, @Nullable Object arg);
+
+ void info(String msg, @Nullable Object arg1, @Nullable Object arg2);
+
+ void info(String msg, Object... args);
+
+ /**
+ * Logs a WARN level message.
+ */
+ void warn(String msg);
+
+ void warn(String msg, @Nullable Object arg);
+
+ void warn(String msg, @Nullable Object arg1, @Nullable Object arg2);
+
+ void warn(String msg, Object... args);
+
+ /**
+ * Logs an ERROR level message.
+ */
+ void error(String msg);
- void info(String message);
+ void error(String msg, @Nullable Object arg);
- void warn(String message);
+ void error(String msg, @Nullable Object arg1, @Nullable Object arg2);
- void error(String message);
+ void error(String msg, Object... args);
- void error(String message, Throwable throwable);
+ /**
+ * Logs an ERROR level message.
+ */
+ void error(String msg, Throwable thrown);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Loggers.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Loggers.java
index 6a9f278e112..4f2627fc5e9 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Loggers.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Loggers.java
@@ -1,6 +1,57 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.sonar.api.utils.log;
-public class Loggers {
+/**
+ * @since 5.1
+ */
+public abstract class Loggers {
+ private static volatile Loggers factory;
+
+ static {
+ try {
+ Class.forName("org.slf4j.Logger");
+ factory = new LogbackLoggers();
+ } catch (Throwable e) {
+ // no slf4j -> testing environment
+ factory = new ConsoleLoggers();
+ }
+ }
+
+ public static Logger get(Class name) {
+ return factory.newInstance(name.getName());
+ }
+
+ public static Logger get(String name) {
+ return factory.newInstance(name);
+ }
+
+ static Loggers getFactory() {
+ return factory;
+ }
+
+ protected abstract Logger newInstance(String name);
+
+ protected abstract boolean isDebugEnabled();
+
+ protected abstract void enableDebug(boolean b);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/NullInterceptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/NullInterceptor.java
new file mode 100644
index 00000000000..63e0d9ab847
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/NullInterceptor.java
@@ -0,0 +1,56 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+/**
+ * Log interceptor that does nothing, so production-ready!
+ */
+class NullInterceptor extends LogInterceptor {
+
+ static final NullInterceptor NULL_INSTANCE = new NullInterceptor();
+
+ private NullInterceptor() {
+ }
+
+ @Override
+ void log(String msg) {
+ // nothing
+ }
+
+ @Override
+ void log(String msg, Object arg) {
+ // nothing
+ }
+
+ @Override
+ void log(String msg, Object arg1, Object arg2) {
+ // nothing
+ }
+
+ @Override
+ void log(String msg, Object... args) {
+ // nothing
+ }
+
+ @Override
+ void log(String msg, Throwable thrown) {
+ // nothing
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/internal/InMemoryLogger.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/internal/InMemoryLogger.java
deleted file mode 100644
index b7f2fa061de..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/internal/InMemoryLogger.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.sonar.api.utils.log.internal;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Lists;
-import org.sonar.api.utils.log.Logger;
-
-import java.util.List;
-
-/**
- * Implementation of {@link org.sonar.api.utils.log.Logger} which keeps logs
- * in memory, so that they can be loaded after writing. It is helpful
- * for testing.
- */
-public class InMemoryLogger implements Logger {
-
- private static enum Level {
- DEBUG, INFO, WARN, ERROR
- }
-
- private boolean debugEnabled = false;
- private final ArrayListMultimap<Level, String> logs = ArrayListMultimap.create();
-
- @Override
- public boolean isDebugEnabled() {
- return debugEnabled;
- }
-
- public InMemoryLogger setDebugEnabled(boolean b) {
- this.debugEnabled = b;
- return this;
- }
-
- @Override
- public void debug(String message) {
- if (isDebugEnabled()) {
- log(Level.DEBUG, message);
- }
- }
-
- @Override
- public void info(String message) {
- log(Level.INFO, message);
- }
-
- @Override
- public void warn(String message) {
- log(Level.WARN, message);
- }
-
- @Override
- public void error(String message) {
- log(Level.ERROR, message);
- }
-
- @Override
- public void error(String message, Throwable throwable) {
- log(Level.ERROR, String.format("%s | %s", message, throwable.getMessage()));
- }
-
- public List<String> logs() {
- return Lists.newArrayList(logs.values());
- }
-
- public List<String> debugLogs() {
- return logs.get(Level.DEBUG);
- }
-
- public List<String> infoLogs() {
- return logs.get(Level.INFO);
- }
-
- public List<String> warnLogs() {
- return logs.get(Level.WARN);
- }
-
- public List<String> errorLogs() {
- return logs.get(Level.ERROR);
- }
-
- public InMemoryLogger clear() {
- logs.clear();
- return this;
- }
-
- private void log(Level level, String message) {
- logs.put(level, message);
- }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/internal/Slf4jLoggers.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/internal/Slf4jLoggers.java
deleted file mode 100644
index d1cfadd2bf5..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/internal/Slf4jLoggers.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.sonar.api.utils.log.internal;
-
-
-import org.slf4j.LoggerFactory;
-import org.sonar.api.utils.log.Logger;
-
-public class Slf4jLoggers {
-
- public static class Slf4jLogger implements Logger {
- private final org.slf4j.Logger slf4j;
-
- public Slf4jLogger(org.slf4j.Logger slf4j) {
- this.slf4j = slf4j;
- }
-
- @Override
- public boolean isDebugEnabled() {
- return slf4j.isDebugEnabled();
- }
-
- @Override
- public void debug(String message) {
- slf4j.debug(message);
- }
-
- @Override
- public void info(String message) {
- slf4j.info(message);
- }
-
- @Override
- public void warn(String message) {
- slf4j.warn(message);
- }
-
- @Override
- public void error(String message) {
- slf4j.error(message);
- }
-
- @Override
- public void error(String message, Throwable throwable) {
- slf4j.error(message, throwable);
- }
- }
-
- public Slf4jLogger getLogger(String name) {
- return new Slf4jLogger(LoggerFactory.getLogger(name));
- }
-
- public Slf4jLogger getLogger(Class name) {
- return new Slf4jLogger(LoggerFactory.getLogger(name));
- }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/package-info.java
new file mode 100644
index 00000000000..a2aedc1a627
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.api.utils.log;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/platform/ComponentKeysTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/platform/ComponentKeysTest.java
index cb38cde6f6f..2a882663993 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/platform/ComponentKeysTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/platform/ComponentKeysTest.java
@@ -20,13 +20,11 @@
package org.sonar.api.platform;
import org.junit.Test;
-import org.slf4j.Logger;
+import org.sonar.api.utils.log.Logger;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.startsWith;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.*;
public class ComponentKeysTest {
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/TimeProfilerTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/TimeProfilerTest.java
index 713b4677abf..3d7e3ac6177 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/TimeProfilerTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/TimeProfilerTest.java
@@ -21,7 +21,7 @@ package org.sonar.api.utils;
import org.junit.Before;
import org.junit.Test;
-import org.slf4j.Logger;
+import org.sonar.api.utils.log.Logger;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/ValidationMessagesTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/ValidationMessagesTest.java
index a00847874c8..7a4e3468362 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/ValidationMessagesTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/ValidationMessagesTest.java
@@ -20,14 +20,11 @@
package org.sonar.api.utils;
import org.junit.Test;
-import org.slf4j.Logger;
+import org.sonar.api.utils.log.Logger;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.*;
public class ValidationMessagesTest {
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java
new file mode 100644
index 00000000000..4e2280fe775
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java
@@ -0,0 +1,41 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import org.junit.Test;
+import org.sonar.test.TestUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ConsoleFormatterTest {
+
+ @Test
+ public void format() throws Exception {
+ assertThat(ConsoleFormatter.format("foo")).isEqualTo("foo");
+ assertThat(ConsoleFormatter.format("arg: {}", "foo")).isEqualTo("arg: foo");
+ assertThat(ConsoleFormatter.format("two args: {} and {}", "foo", 42)).isEqualTo("two args: foo and 42");
+ assertThat(ConsoleFormatter.format("args: {}, {} and {}", true, 42, 2L)).isEqualTo("args: true, 42 and 2");
+ }
+
+ @Test
+ public void only_static_methods() throws Exception {
+ assertThat(TestUtils.hasOnlyPrivateConstructors(ConsoleFormatter.class)).isTrue();
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggerTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggerTest.java
new file mode 100644
index 00000000000..68d4d02bac3
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggerTest.java
@@ -0,0 +1,82 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.PrintStream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.*;
+
+public class ConsoleLoggerTest {
+
+ PrintStream stream = mock(PrintStream.class);
+ ConsoleLogger sut = new ConsoleLogger(stream);
+
+ @Rule
+ public LogTester tester = new LogTester();
+
+ @Test
+ public void debug_enabled() throws Exception {
+ tester.enableDebug(true);
+ assertThat(sut.isDebugEnabled()).isTrue();
+ sut.debug("message");
+ sut.debug("message {}", "foo");
+ sut.debug("message {} {}", "foo", "bar");
+ sut.debug("message {} {} {}", "foo", "bar", "baz");
+ verify(stream, times(4)).println(anyString());
+ }
+
+ @Test
+ public void debug_disabled() throws Exception {
+ tester.enableDebug(false);
+ assertThat(sut.isDebugEnabled()).isFalse();
+ sut.debug("message");
+ sut.debug("message {}", "foo");
+ sut.debug("message {} {}", "foo", "bar");
+ sut.debug("message {} {} {}", "foo", "bar", "baz");
+ verifyZeroInteractions(stream);
+ }
+
+ @Test
+ public void log() throws Exception {
+ sut.info("message");
+ sut.info("message {}", "foo");
+ sut.info("message {} {}", "foo", "bar");
+ sut.info("message {} {} {}", "foo", "bar", "baz");
+ verify(stream, times(4)).println(startsWith("INFO "));
+
+ sut.warn("message");
+ sut.warn("message {}", "foo");
+ sut.warn("message {} {}", "foo", "bar");
+ sut.warn("message {} {} {}", "foo", "bar", "baz");
+ verify(stream, times(4)).println(startsWith("WARN "));
+
+ sut.error("message");
+ sut.error("message {}", "foo");
+ sut.error("message {} {}", "foo", "bar");
+ sut.error("message {} {} {}", "foo", "bar", "baz");
+ sut.error("message", new IllegalArgumentException());
+ verify(stream, times(5)).println(startsWith("ERROR "));
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggersTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggersTest.java
new file mode 100644
index 00000000000..64fa4cc7b96
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggersTest.java
@@ -0,0 +1,47 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ConsoleLoggersTest {
+
+ ConsoleLoggers sut = new ConsoleLoggers();
+
+ @Test
+ public void newInstance() throws Exception {
+ Logger logger = sut.newInstance("foo");
+ assertThat(logger).isInstanceOf(ConsoleLogger.class);
+ }
+
+ @Test
+ public void debugMode() throws Exception {
+ // disabled by default
+ assertThat(sut.isDebugEnabled()).isFalse();
+
+ sut.enableDebug(true);
+ assertThat(sut.isDebugEnabled()).isTrue();
+
+ sut.enableDebug(false);
+ assertThat(sut.isDebugEnabled()).isFalse();
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogTesterTest.java
new file mode 100644
index 00000000000..32bb1000bd6
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogTesterTest.java
@@ -0,0 +1,61 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LogTesterTest {
+
+ LogTester sut = new LogTester();
+
+ @Test
+ public void debugLevel() throws Throwable {
+ boolean initial = sut.isDebugEnabled();
+
+ // when LogTester is used, then debug logs are enabled by default
+ sut.before();
+ assertThat(sut.isDebugEnabled()).isTrue();
+ assertThat(Loggers.getFactory().isDebugEnabled()).isTrue();
+
+ // change
+ sut.enableDebug(false);
+ assertThat(sut.isDebugEnabled()).isFalse();
+ assertThat(Loggers.getFactory().isDebugEnabled()).isFalse();
+
+ // reset to initial level
+ sut.after();
+ assertThat(sut.isDebugEnabled()).isEqualTo(initial);
+ assertThat(Loggers.getFactory().isDebugEnabled()).isEqualTo(initial);
+ }
+
+ @Test
+ public void intercept_logs() throws Throwable {
+ sut.before();
+ Loggers.get("logger1").info("an information");
+ Loggers.get("logger2").warn("warning: {}", 42);
+
+ assertThat(sut.logs()).containsExactly("an information", "warning: 42");
+
+ sut.after();
+ assertThat(LogInterceptor.instance).isSameAs(NullInterceptor.NULL_INSTANCE);
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogbackLoggerTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogbackLoggerTest.java
new file mode 100644
index 00000000000..2c8c3680eb7
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogbackLoggerTest.java
@@ -0,0 +1,69 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LogbackLoggerTest {
+
+ LogbackLogger sut = new LogbackLogger(LoggerFactory.getLogger(getClass()));
+
+ @Rule
+ public LogTester tester = new LogTester();
+
+ @Test
+ public void debug_enabling() throws Exception {
+ tester.enableDebug(true);
+ assertThat(sut.isDebugEnabled()).isTrue();
+
+ tester.enableDebug(false);
+ assertThat(sut.isDebugEnabled()).isFalse();
+ }
+
+ @Test
+ public void log() throws Exception {
+ // no assertions. Simply verify that calls do not fail.
+ sut.debug("message");
+ sut.debug("message {}", "foo");
+ sut.debug("message {} {}", "foo", "bar");
+ sut.debug("message {} {} {}", "foo", "bar", "baz");
+
+ sut.info("message");
+ sut.info("message {}", "foo");
+ sut.info("message {} {}", "foo", "bar");
+ sut.info("message {} {} {}", "foo", "bar", "baz");
+
+ sut.warn("message");
+ sut.warn("message {}", "foo");
+ sut.warn("message {} {}", "foo", "bar");
+ sut.warn("message {} {} {}", "foo", "bar", "baz");
+
+ sut.error("message");
+ sut.error("message {}", "foo");
+ sut.error("message {} {}", "foo", "bar");
+ sut.error("message {} {} {}", "foo", "bar", "baz");
+ sut.error("message", new IllegalArgumentException(""));
+
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LoggersTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LoggersTest.java
new file mode 100644
index 00000000000..b26094ce16a
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LoggersTest.java
@@ -0,0 +1,37 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import org.junit.Test;
+import org.sonar.api.SonarPlugin;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LoggersTest {
+
+ @Test
+ public void factory() throws Exception {
+ // logback is used by sonar-plugin-api
+ assertThat(Loggers.getFactory()).isInstanceOf(LogbackLoggers.class);
+
+ assertThat(Loggers.get("foo")).isInstanceOf(LogbackLogger.class);
+ assertThat(Loggers.get(SonarPlugin.class)).isInstanceOf(LogbackLogger.class);
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/NullInterceptorTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/NullInterceptorTest.java
new file mode 100644
index 00000000000..d25d04d1dcd
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/NullInterceptorTest.java
@@ -0,0 +1,37 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils.log;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+
+public class NullInterceptorTest {
+
+ @Test
+ public void do_nothing() throws Exception {
+ // verify that... it does nothing
+ NullInterceptor.NULL_INSTANCE.log("foo");
+ NullInterceptor.NULL_INSTANCE.log("foo {}", 42);
+ NullInterceptor.NULL_INSTANCE.log("foo {} {}", 42, 66);
+ NullInterceptor.NULL_INSTANCE.log("foo {} {} {}", 42, 66, 84);
+ NullInterceptor.NULL_INSTANCE.log("foo", mock(Exception.class));
+ }
+}