diff --git a/.gitignore b/.gitignore
index f1d4a1d9..2dd13ef3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,12 @@
-# Maven
+# Android
+local.properties
+
+/# Maven
target/
# Gradle
.gradle/
+build/
# Ant Working Directory
.sonar/
@@ -11,6 +15,7 @@ target/
*.iws
*.iml
*.ipr
+.idea/
# Eclipse
.classpath
@@ -18,7 +23,7 @@ target/
.settings
# ---- Mac OS X
-.DS_Store?
+.DS_Store
Icon?
# Thumbnails
._*
diff --git a/.sonarsource.properties b/.sonarsource.properties
new file mode 100644
index 00000000..bfb4e7b9
--- /dev/null
+++ b/.sonarsource.properties
@@ -0,0 +1,6 @@
+# Sonarsource meta data file for this project
+
+# Wallboard
+# teamAtSonarSource drives in which wallboard the alerting will be sent
+# platform , language, infra , po , support
+wallboard.teamAtSonarSource=support
diff --git a/.whitesource b/.whitesource
new file mode 100644
index 00000000..55b922e8
--- /dev/null
+++ b/.whitesource
@@ -0,0 +1,12 @@
+{
+ "scanSettings": {
+ "baseBranches": []
+ },
+ "checkRunSettings": {
+ "vulnerableCheckRunConclusionLevel": "failure",
+ "displayMode": "diff"
+ },
+ "issueSettings": {
+ "minSeverityLevel": "LOW"
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index e3ccd5b8..91768667 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,17 @@
-# Sonar Usage and Examples
-
-Please add usage scenarios or links to articles that mention special use-cases below.
-Note that these examples are usually for Sonar 2.10 and greater versions.
-
## Configuration of Projects
-The directory /projects contains some typical configurations of projects for the multiple supported build tools (Maven, Ant, Java Runner).
+The directory /projects contains sample projects for:
+ * the different analyzers (SonarQube Runner, Maven, Ant)
+ * the different languages (Java, Cobol, .Net, etc.)
+ * the different ways to execute unit tests and get code coverage data
-## Sonar Plugins
+## SonarQube Plugins
-The directory /plugins contains the most frequent kinds of plugins :
-
- * Extensions of rule engines like Checkstyle or PMD
+The directory /plugins contains the most frequent kinds of plugins:
+ * Extensions of rule engines like Java and JavaScript
* Define a new metric, compute measures and display them in web app
+## SonarQube Web Service API
-
+The directory /ws contains project samples using the SonarQube web service API.
+
diff --git a/plugins/java-custom-rules/README.md b/plugins/java-custom-rules/README.md
new file mode 100644
index 00000000..27e63097
--- /dev/null
+++ b/plugins/java-custom-rules/README.md
@@ -0,0 +1,3 @@
+This example demonstrates how to write new *custom* rules for the Java analyzer.
+
+It requires to install the **Java Plugin**, at least version **3.13.1**, which is compatible with SonarQube 4.5.6 LTS.
diff --git a/plugins/java-custom-rules/pom.xml b/plugins/java-custom-rules/pom.xml
new file mode 100644
index 00000000..ca4bb695
--- /dev/null
+++ b/plugins/java-custom-rules/pom.xml
@@ -0,0 +1,135 @@
+
+
+ 4.0.0
+
+ org.sonar.samples
+ java-custom-rules
+ 1.0-SNAPSHOT
+ sonar-plugin
+
+
+ 7.15.0.30507
+
+
+ Java Custom Rules
+ Java Custom Rules
+
+
+
+ org.codehaus.sonar
+ sonar-plugin-api
+ 5.0
+ provided
+
+
+
+ org.sonarsource.java
+ sonar-java-plugin
+ sonar-plugin
+ ${java.plugin.version}
+ provided
+
+
+
+ org.sonarsource.java
+ java-frontend
+ ${java.plugin.version}
+
+
+
+ org.sonarsource.sslr-squid-bridge
+ sslr-squid-bridge
+ 2.7.1.392
+
+
+ org.codehaus.sonar.sslr
+ sslr-core
+
+
+
+
+
+ org.sonarsource.java
+ java-checks-testkit
+ ${java.plugin.version}
+ test
+
+
+
+ org.codehaus.sonar.sslr
+ sslr-testing-harness
+ 1.19.2
+ test
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ org.easytesting
+ fest-assert
+ 1.4
+ test
+
+
+ ch.qos.logback
+ logback-classic
+ 0.9.30
+ test
+
+
+
+
+
+
+ org.sonarsource.sonar-packaging-maven-plugin
+ sonar-packaging-maven-plugin
+ 1.15
+ true
+
+ org.sonar.samples.java.MyJavaRulesPlugin
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ 1.7
+ 1.7
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 2.10
+
+
+ copy
+ test-compile
+
+ copy
+
+
+
+
+ org.apache.commons
+ commons-collections4
+ 4.0
+ jar
+
+
+ ${project.build.directory}/test-jars
+
+
+
+
+
+
+
+
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/MyJavaFileCheckRegistrar.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/MyJavaFileCheckRegistrar.java
new file mode 100644
index 00000000..647a1dfe
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/MyJavaFileCheckRegistrar.java
@@ -0,0 +1,53 @@
+package org.sonar.samples.java;
+
+import java.util.Arrays;
+
+import org.sonar.plugins.java.api.CheckRegistrar;
+import org.sonar.plugins.java.api.JavaCheck;
+import org.sonar.samples.java.checks.AvoidAnnotationRule;
+import org.sonar.samples.java.checks.AvoidBrandInMethodNamesRule;
+import org.sonar.samples.java.checks.AvoidMethodDeclarationRule;
+import org.sonar.samples.java.checks.AvoidSuperClassRule;
+import org.sonar.samples.java.checks.AvoidUnmodifiableListRule;
+import org.sonar.samples.java.checks.MyCustomSubscriptionRule;
+import org.sonar.samples.java.checks.SecurityAnnotationMandatoryRule;
+
+/**
+ * Provide the "checks" (implementations of rules) classes that are gonna be executed during
+ * source code analysis.
+ *
+ * This class is a batch extension by implementing the {@link org.sonar.plugins.java.api.CheckRegistrar} interface.
+ */
+public class MyJavaFileCheckRegistrar implements CheckRegistrar {
+
+ /**
+ * Register the classes that will be used to instantiate checks during analysis.
+ */
+ @Override
+ public void register(RegistrarContext registrarContext) {
+ // Call to registerClassesForRepository to associate the classes with the correct repository key
+ registrarContext.registerClassesForRepository(MyJavaRulesDefinition.REPOSITORY_KEY, Arrays.asList(checkClasses()), Arrays.asList(testCheckClasses()));
+ }
+
+ /**
+ * Lists all the checks provided by the plugin
+ */
+ public static Class extends JavaCheck>[] checkClasses() {
+ return new Class[] {
+ AvoidAnnotationRule.class,
+ AvoidBrandInMethodNamesRule.class,
+ AvoidMethodDeclarationRule.class,
+ AvoidSuperClassRule.class,
+ AvoidUnmodifiableListRule.class,
+ MyCustomSubscriptionRule.class,
+ SecurityAnnotationMandatoryRule.class
+ };
+ }
+
+ /**
+ * Lists all the test checks provided by the plugin
+ */
+ public static Class extends JavaCheck>[] testCheckClasses() {
+ return new Class[] {};
+ }
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/MyJavaRulesDefinition.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/MyJavaRulesDefinition.java
new file mode 100644
index 00000000..f2d8530b
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/MyJavaRulesDefinition.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009-2014 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.java;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.plugins.java.Java;
+import org.sonar.squidbridge.annotations.AnnotationBasedRulesDefinition;
+
+/**
+ * Declare rule metadata in server repository of rules.
+ * That allows to list the rules in the page "Rules".
+ */
+public class MyJavaRulesDefinition implements RulesDefinition {
+
+ public static final String REPOSITORY_KEY = "myrepo";
+
+ @Override
+ public void define(Context context) {
+ NewRepository repository = context.createRepository(REPOSITORY_KEY, Java.KEY);
+ repository.setName("MyRepo");
+
+ AnnotationBasedRulesDefinition.load(repository, "java", RulesList.getChecks());
+ repository.done();
+ }
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/MyJavaRulesPlugin.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/MyJavaRulesPlugin.java
new file mode 100644
index 00000000..3b4ef0cc
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/MyJavaRulesPlugin.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009-2014 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.java;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.sonar.api.SonarPlugin;
+
+/**
+ * Entry point of plugin
+ */
+public class MyJavaRulesPlugin extends SonarPlugin {
+
+ @Override
+ public List getExtensions() {
+ return Arrays.asList(
+ // server extensions -> objects are instantiated during server startup
+ MyJavaRulesDefinition.class,
+
+ // batch extensions -> objects are instantiated during code analysis
+ MyJavaFileCheckRegistrar.class);
+ }
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/RulesList.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/RulesList.java
new file mode 100644
index 00000000..a9ab3340
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/RulesList.java
@@ -0,0 +1,41 @@
+package org.sonar.samples.java;
+
+import java.util.List;
+
+import org.sonar.plugins.java.api.JavaCheck;
+import org.sonar.samples.java.checks.AvoidAnnotationRule;
+import org.sonar.samples.java.checks.AvoidBrandInMethodNamesRule;
+import org.sonar.samples.java.checks.AvoidMethodDeclarationRule;
+import org.sonar.samples.java.checks.AvoidSuperClassRule;
+import org.sonar.samples.java.checks.AvoidUnmodifiableListRule;
+import org.sonar.samples.java.checks.MyCustomSubscriptionRule;
+import org.sonar.samples.java.checks.SecurityAnnotationMandatoryRule;
+
+import com.google.common.collect.ImmutableList;
+
+public final class RulesList {
+
+ private RulesList() {
+ }
+
+ public static List getChecks() {
+ return ImmutableList.builder().addAll(getJavaChecks()).addAll(getJavaTestChecks()).build();
+ }
+
+ public static List> getJavaChecks() {
+ return ImmutableList.>builder()
+ .add(AvoidAnnotationRule.class)
+ .add(AvoidBrandInMethodNamesRule.class)
+ .add(AvoidMethodDeclarationRule.class)
+ .add(AvoidSuperClassRule.class)
+ .add(AvoidUnmodifiableListRule.class)
+ .add(MyCustomSubscriptionRule.class)
+ .add(SecurityAnnotationMandatoryRule.class)
+ .build();
+ }
+
+ public static List> getJavaTestChecks() {
+ return ImmutableList.>builder()
+ .build();
+ }
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidAnnotationRule.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidAnnotationRule.java
new file mode 100644
index 00000000..9ccfafd4
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidAnnotationRule.java
@@ -0,0 +1,66 @@
+package org.sonar.samples.java.checks;
+
+import java.util.List;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+import org.sonar.plugins.java.api.JavaFileScanner;
+import org.sonar.plugins.java.api.JavaFileScannerContext;
+import org.sonar.plugins.java.api.tree.AnnotationTree;
+import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
+import org.sonar.plugins.java.api.tree.IdentifierTree;
+import org.sonar.plugins.java.api.tree.MethodTree;
+import org.sonar.plugins.java.api.tree.Tree;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+@Rule(key = "AvoidAnnotation",
+ name = "Avoid usage of annotation",
+ description = "This rule detects usage of configured annotation",
+ tags = {"example"})
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.ARCHITECTURE_CHANGEABILITY)
+@SqaleConstantRemediation("10min")
+public class AvoidAnnotationRule extends BaseTreeVisitor implements JavaFileScanner {
+
+ private static final String DEFAULT_VALUE = "Inject";
+
+ private JavaFileScannerContext context;
+
+ /**
+ * Name of the annotation to avoid. Value can be set by users in Quality profiles.
+ * The key
+ */
+ @RuleProperty(
+ defaultValue = DEFAULT_VALUE,
+ description = "Name of the annotation to avoid, without the prefix @, for instance 'Override'")
+ protected String name;
+
+ @Override
+ public void scanFile(JavaFileScannerContext context) {
+ this.context = context;
+
+ scan(context.getTree());
+
+ System.out.println(PrinterVisitor.print(context.getTree()));
+ }
+
+ @Override
+ public void visitMethod(MethodTree tree) {
+ List annotations = tree.modifiers().annotations();
+ for (AnnotationTree annotationTree : annotations) {
+ if (annotationTree.annotationType().is(Tree.Kind.IDENTIFIER)) {
+ IdentifierTree idf = (IdentifierTree) annotationTree.annotationType();
+ System.out.println(idf.name());
+
+ if (idf.name().equals(name)) {
+ context.addIssue(idf, this, String.format("Avoid using annotation @%s", name));
+ }
+ }
+ }
+
+ // The call to the super implementation allows to continue the visit of the AST.
+ // Be careful to always call this method to visit every node of the tree.
+ super.visitMethod(tree);
+ }
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidBrandInMethodNamesRule.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidBrandInMethodNamesRule.java
new file mode 100644
index 00000000..5449d4be
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidBrandInMethodNamesRule.java
@@ -0,0 +1,53 @@
+package org.sonar.samples.java.checks;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.JavaFileScanner;
+import org.sonar.plugins.java.api.JavaFileScannerContext;
+import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
+import org.sonar.plugins.java.api.tree.MethodTree;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+@Rule(key = "AvoidBrandInMethodNames",
+ name = "Avoid Brand in Method Names",
+ description = "Avoid Brand in Method Names",
+ tags = {"company"})
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.ARCHITECTURE_CHANGEABILITY)
+@SqaleConstantRemediation("10min")
+public class AvoidBrandInMethodNamesRule extends BaseTreeVisitor implements JavaFileScanner {
+
+ private JavaFileScannerContext context;
+
+ protected static final String COMPANY_NAME = "MyCompany";
+
+ @Override
+ public void scanFile(JavaFileScannerContext context) {
+ this.context = context;
+
+ // The call to the scan method on the root of the tree triggers the visit of the AST by this visitor
+ scan(context.getTree());
+
+ // For debugging purpose, you can print out the entire AST of the analyzed file
+ System.out.println(PrinterVisitor.print(context.getTree()));
+ }
+
+ /**
+ * Overriding the visitor method to implement the logic of the rule.
+ * @param tree AST of the visited method.
+ */
+ @Override
+ public void visitMethod(MethodTree tree) {
+
+ if (tree.simpleName().name().toUpperCase().contains(COMPANY_NAME.toUpperCase())) {
+ // Adds an issue by attaching it with the tree and the rule
+ context.addIssue(tree, this, "Avoid using Brand in method name");
+ }
+ // The call to the super implementation allows to continue the visit of the AST.
+ // Be careful to always call this method to visit every node of the tree.
+ super.visitMethod(tree);
+
+ // All the code located after the call to the overridden method is executed when leaving the node
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidMethodDeclarationRule.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidMethodDeclarationRule.java
new file mode 100644
index 00000000..d6916775
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidMethodDeclarationRule.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2009-2014 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.java.checks;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.JavaFileScanner;
+import org.sonar.plugins.java.api.JavaFileScannerContext;
+import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
+import org.sonar.plugins.java.api.tree.MethodTree;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+/**
+ * This class is an example of how to implement your own rules.
+ * The (stupid) rule raises a minor issue each time a method is encountered.
+ * The @Rule annotation allows to specify metadata like rule key, name, description
+ * or default severity.
+ */
+@Rule(key = "MethodDeclaration",
+ name = "Avoid using methods",
+ description = "My stupid rule to avoid calling methods",
+ tags = {"stupid", "example"},
+ // default severity (formerly "priority") when rule is enabled in Quality profile
+ priority = Priority.MINOR)
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.ARCHITECTURE_CHANGEABILITY)
+@SqaleConstantRemediation("10min")
+/**
+ * The class extends BaseTreeVisitor: the visitor for the Java AST.
+ * The logic of the rule is implemented by overriding its methods.
+ * It also implements the JavaFileScanner interface to be injected with the JavaFileScannerContext to attach issues to this context.
+ */
+public class AvoidMethodDeclarationRule extends BaseTreeVisitor implements JavaFileScanner {
+
+ /**
+ * Private field to store the context: this is the object used to create issues.
+ */
+ private JavaFileScannerContext context;
+
+ /**
+ * Implementation of the method of the JavaFileScanner interface.
+ * @param context Object used to attach issues to source file.
+ */
+ @Override
+ public void scanFile(JavaFileScannerContext context) {
+ this.context = context;
+
+ // The call to the scan method on the root of the tree triggers the visit of the AST by this visitor
+ scan(context.getTree());
+
+ // For debugging purpose, you can print out the entire AST of the analyzed file
+ System.out.println(PrinterVisitor.print(context.getTree()));
+
+ }
+
+ /**
+ * Overriding the visitor method to implement the logic of the rule.
+ * @param tree AST of the visited method.
+ */
+ @Override
+ public void visitMethod(MethodTree tree) {
+
+ // All the code located before the call to the overridden method is executed before visiting the node
+
+ // Adds an issue by attaching it with the tree and the rule
+ context.addIssue(tree, this, "Avoid method calls (don't ask why)");
+
+ // The call to the super implementation allows to continue the visit of the AST.
+ // Be careful to always call this method to visit every node of the tree.
+ super.visitMethod(tree);
+
+ // All the code located after the call to the overridden method is executed when leaving the node
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidSuperClassRule.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidSuperClassRule.java
new file mode 100644
index 00000000..09abf6fb
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidSuperClassRule.java
@@ -0,0 +1,56 @@
+/*
+ * Creation : 20 avr. 2015
+ */
+package org.sonar.samples.java.checks;
+
+import java.util.List;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.tree.ClassTree;
+import org.sonar.plugins.java.api.tree.Tree;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Only to bring out the unit test requirement about classpath when bytecode methods used (see rule unit test class)
+ */
+@Rule(key = "avoid_super_class",
+ name = "Avoid using SuperClass",
+ description = "My stupid rule to avoid extends some SuperClass",
+ tags = {"stupid", "example"})
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.ARCHITECTURE_CHANGEABILITY)
+@SqaleConstantRemediation("10min")
+public class AvoidSuperClassRule extends IssuableSubscriptionVisitor {
+
+ public static final List SUPER_CLASS_AVOID = ImmutableList.of("org.apache.log4j.Logger");
+
+ @Override
+ public List nodesToVisit() {
+ // Register to the kind of nodes you want to be called upon visit.
+ return ImmutableList.of(Tree.Kind.CLASS);
+ }
+
+ @Override
+ public void visitNode(Tree tree) {
+ // Visit CLASS node only => cast could be done
+ ClassTree treeClazz = (ClassTree) tree;
+
+ // No extends => stop to visit class
+ if (treeClazz.superClass() == null) {
+ return;
+ }
+
+ // For 'symbolType' usage, jar in dependencies must be on classpath, !unknownSymbol! result otherwise
+ String superClassName = treeClazz.superClass().symbolType().fullyQualifiedName();
+
+ // Check if superClass avoid
+ if (SUPER_CLASS_AVOID.contains(superClassName)) {
+ addIssue(tree, String.format("The usage of super class %s is forbidden", superClassName));
+ }
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidUnmodifiableListRule.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidUnmodifiableListRule.java
new file mode 100644
index 00000000..c024ffee
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/AvoidUnmodifiableListRule.java
@@ -0,0 +1,36 @@
+package org.sonar.samples.java.checks;
+
+import java.util.List;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.tree.NewClassTree;
+import org.sonar.plugins.java.api.tree.Tree;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+import com.google.common.collect.ImmutableList;
+
+@Rule(
+ key = "AvoidUnmodifiableList",
+ name = "Avoid usage of UnmodifiableList",
+ description = "This rule detects instanciation of apache commons collections UnmodifableList",
+ tags = {"example"})
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.ARCHITECTURE_CHANGEABILITY)
+@SqaleConstantRemediation("10min")
+public class AvoidUnmodifiableListRule extends IssuableSubscriptionVisitor {
+
+ @Override
+ public List nodesToVisit() {
+ return ImmutableList.of(Tree.Kind.NEW_CLASS);
+ }
+
+ @Override
+ public void visitNode(Tree tree) {
+ if (((NewClassTree) tree).symbolType().isSubtypeOf("org.apache.commons.collections4.list.UnmodifiableList")) {
+ addIssue(tree, "Avoid using UnmodifiableList");
+ }
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/MyCustomSubscriptionRule.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/MyCustomSubscriptionRule.java
new file mode 100644
index 00000000..db4fda11
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/MyCustomSubscriptionRule.java
@@ -0,0 +1,53 @@
+package org.sonar.samples.java.checks;
+
+import java.util.List;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.semantic.Symbol.MethodSymbol;
+import org.sonar.plugins.java.api.semantic.Type;
+import org.sonar.plugins.java.api.tree.MethodTree;
+import org.sonar.plugins.java.api.tree.Tree;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+import com.google.common.collect.ImmutableList;
+
+@Rule(key = "method_with_same_type_as_arg",
+ name = "method with same return type as argument",
+ description = "This rule detects methods with same type as argument",
+ tags = {"example"})
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.ARCHITECTURE_CHANGEABILITY)
+@SqaleConstantRemediation("10min")
+/**
+ * To use subsctiption visitor, just extend the IssuableSubscriptionVisitor.
+ */
+public class MyCustomSubscriptionRule extends IssuableSubscriptionVisitor {
+
+ @Override
+ public List nodesToVisit() {
+ // Register to the kind of nodes you want to be called upon visit.
+ return ImmutableList.of(Tree.Kind.METHOD);
+ }
+
+ @Override
+ public void visitNode(Tree tree) {
+ // Cast the node to the correct type :
+ // in this case we registered only to one kind so we will only receive MethodTree see Tree.Kind enum to know about which type you can
+ // cast depending on Kind.
+ MethodTree methodTree = (MethodTree) tree;
+ // Retrieve symbol of method.
+ MethodSymbol methodSymbol = methodTree.symbol();
+ Type returnType = methodSymbol.returnType().type();
+ // Check method has only one argument.
+ if (methodSymbol.parameterTypes().size() == 1) {
+ Type argType = methodSymbol.parameterTypes().get(0);
+ // Verify argument type is same as return type.
+ if (argType.is(returnType.fullyQualifiedName())) {
+ // raise an issue on this node of the SyntaxTree
+ addIssue(tree, "message");
+ }
+ }
+ }
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/PrinterVisitor.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/PrinterVisitor.java
new file mode 100644
index 00000000..e7514fff
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/PrinterVisitor.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009-2014 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.java.checks;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
+import org.sonar.plugins.java.api.tree.Tree;
+
+public class PrinterVisitor extends BaseTreeVisitor {
+
+ private static final int INDENT_SPACES = 2;
+
+ private final StringBuilder sb;
+ private int indentLevel;
+
+ public PrinterVisitor() {
+ sb = new StringBuilder();
+ indentLevel = 0;
+ }
+
+ public static String print(Tree tree) {
+ PrinterVisitor pv = new PrinterVisitor();
+ pv.scan(tree);
+ return pv.sb.toString();
+ }
+
+ private StringBuilder indent() {
+ return sb.append(StringUtils.leftPad("", INDENT_SPACES * indentLevel));
+ }
+
+ @Override
+ protected void scan(List extends Tree> trees) {
+ if (!trees.isEmpty()) {
+ sb.deleteCharAt(sb.length() - 1);
+ sb.append(" : [\n");
+ super.scan(trees);
+ indent().append("]\n");
+ }
+ }
+
+ @Override
+ protected void scan(@Nullable Tree tree) {
+ if (tree != null && tree.getClass().getInterfaces() != null && tree.getClass().getInterfaces().length > 0) {
+ String nodeName = tree.getClass().getInterfaces()[0].getSimpleName();
+ indent().append(nodeName).append("\n");
+ }
+ indentLevel++;
+ super.scan(tree);
+ indentLevel--;
+ }
+}
diff --git a/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/SecurityAnnotationMandatoryRule.java b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/SecurityAnnotationMandatoryRule.java
new file mode 100644
index 00000000..f1441cd4
--- /dev/null
+++ b/plugins/java-custom-rules/src/main/java/org/sonar/samples/java/checks/SecurityAnnotationMandatoryRule.java
@@ -0,0 +1,101 @@
+package org.sonar.samples.java.checks;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+import org.sonar.java.model.PackageUtils;
+import org.sonar.plugins.java.api.JavaFileScanner;
+import org.sonar.plugins.java.api.JavaFileScannerContext;
+import org.sonar.plugins.java.api.tree.AnnotationTree;
+import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
+import org.sonar.plugins.java.api.tree.ClassTree;
+import org.sonar.plugins.java.api.tree.CompilationUnitTree;
+import org.sonar.plugins.java.api.tree.IdentifierTree;
+import org.sonar.plugins.java.api.tree.MethodTree;
+import org.sonar.plugins.java.api.tree.Tree;
+import org.sonar.plugins.java.api.tree.TypeTree;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+@Rule(key = "SecurityAnnotationMandatory",
+ name = "Security Annotation Mandatory",
+ description = "Security Annotation Mandatory",
+ tags = {"security"})
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.ARCHITECTURE_CHANGEABILITY)
+@SqaleConstantRemediation("10min")
+public class SecurityAnnotationMandatoryRule extends BaseTreeVisitor implements JavaFileScanner {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SecurityAnnotationMandatoryRule.class);
+
+ private static final String DEFAULT_VALUE = "MySecurityAnnotation";
+
+ private boolean implementsSpecificInterface = Boolean.FALSE;
+
+ private JavaFileScannerContext context;
+
+ @RuleProperty(
+ defaultValue = DEFAULT_VALUE,
+ description = "Name of the mandatory annotation")
+ protected String name;
+
+ @Override
+ public void scanFile(JavaFileScannerContext context) {
+ this.context = context;
+ scan(context.getTree());
+ }
+
+ @Override
+ public void visitClass(ClassTree tree) {
+ List interfaces = tree.superInterfaces();
+ for (TypeTree typeTree : interfaces) {
+ LOGGER.info("implements Interface : " + typeTree);
+ if ("MySecurityInterface".equals(typeTree.toString())) {
+ implementsSpecificInterface = Boolean.TRUE;
+ }
+ }
+
+ super.visitClass(tree);
+ }
+
+ @Override
+ public void visitCompilationUnit(CompilationUnitTree tree) {
+
+ if (tree.packageDeclaration() != null) {
+ String packageName = PackageUtils.packageName(tree.packageDeclaration(), ".");
+ LOGGER.info("PackageName : " + packageName);
+ }
+
+ super.visitCompilationUnit(tree);
+ }
+
+ @Override
+ public void visitMethod(MethodTree tree) {
+ if (implementsSpecificInterface) {
+ List annotations = tree.modifiers().annotations();
+
+ boolean isHavingMandatoryAnnotation = Boolean.FALSE;
+
+ for (AnnotationTree annotationTree : annotations) {
+ if (annotationTree.annotationType().is(Tree.Kind.IDENTIFIER)) {
+ IdentifierTree idf = (IdentifierTree) annotationTree.annotationType();
+ LOGGER.info("Method Name {}", idf.name());
+
+ if (idf.name().equals(name)) {
+ isHavingMandatoryAnnotation = Boolean.TRUE;
+ }
+ }
+ }
+ if (!isHavingMandatoryAnnotation) {
+ context.addIssue(tree, this, String.format("Mandatory Annotation not set @%s", name));
+ }
+
+ }
+ // The call to the super implementation allows to continue the visit of the AST.
+ // Be careful to always call this method to visit every node of the tree.
+ super.visitMethod(tree);
+ }
+}
diff --git a/plugins/java-custom-rules/src/test/files/AvoidAnnotationCheck.java b/plugins/java-custom-rules/src/test/files/AvoidAnnotationCheck.java
new file mode 100644
index 00000000..d3df6680
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/files/AvoidAnnotationCheck.java
@@ -0,0 +1,19 @@
+/**
+ *This file is the sample code against we run our unit test.
+ *It is placed src/test/files in order to not be part of the maven compilation.
+ **/
+class AvoidAnnotationCheck {
+
+ int aField;
+
+ @MyAnnotation
+ public void aMethod() {
+
+ }
+
+ @Zuper // Noncompliant {{Avoid using annotation @Zuper}}
+ public void aMethod() {
+
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/test/files/AvoidBrandInMethodNamesCheck.java b/plugins/java-custom-rules/src/test/files/AvoidBrandInMethodNamesCheck.java
new file mode 100644
index 00000000..a3d952f3
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/files/AvoidBrandInMethodNamesCheck.java
@@ -0,0 +1,21 @@
+/**
+ *This file is the sample code against we run our unit test.
+ *It is placed src/test/files in order to not be part of the maven compilation.
+ **/
+class AvoidBrandInNamesCheck {
+
+ int aField;
+
+ public void methodWithMYCOMPANY() { // Noncompliant {{Avoid using Brand in method name}}
+
+ }
+
+ public void methodWithMyCompany() { // Noncompliant {{Avoid using Brand in method name}}
+
+ }
+
+ public void methodWithMyOtherCompany() {
+
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/test/files/AvoidMethodDeclarationCheck.java b/plugins/java-custom-rules/src/test/files/AvoidMethodDeclarationCheck.java
new file mode 100644
index 00000000..24b9b620
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/files/AvoidMethodDeclarationCheck.java
@@ -0,0 +1,13 @@
+/**
+ *This file is the sample code against we run our unit test.
+ *It is placed src/test/files in order to not be part of the maven compilation.
+ **/
+class AvoidMethodDeclarationCheck {
+
+ int aField;
+
+ public void aMethod() { // Noncompliant {{Avoid method calls (don't ask why)}}
+
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/test/files/AvoidSuperClassCheck.java b/plugins/java-custom-rules/src/test/files/AvoidSuperClassCheck.java
new file mode 100644
index 00000000..a4e3d660
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/files/AvoidSuperClassCheck.java
@@ -0,0 +1,17 @@
+/*
+ * Creation : 20 avr. 2015
+ */
+package org.sonar.samples.java;
+
+import org.apache.log4j.Logger;
+
+/**
+ * A class with extends another class outside the JVM but in classpath
+ */
+public class AvoidSuperClassCheck extends Logger { // Noncompliant {{The usage of super class org.apache.log4j.Logger is forbidden}}
+
+ protected AvoidSuperClassCheck(String name) {
+ super(name);
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/test/files/AvoidUnmodifiableList.java b/plugins/java-custom-rules/src/test/files/AvoidUnmodifiableList.java
new file mode 100644
index 00000000..a6acadbb
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/files/AvoidUnmodifiableList.java
@@ -0,0 +1,17 @@
+import org.apache.commons.collections4.list.UnmodifiableList;
+import java.util.ArrayList;
+
+import java.util.ArrayList;
+
+class A {
+ void foo() {
+ UnmodifiableList myList = new UnmodifiableList(new ArrayList<>()); // Noncompliant {{Avoid using UnmodifiableList}}
+ // Noncompliant@+1
+ MyList myOtherList = new MyList(); // as MyList extends the UnmodifiableList, we expect an issue here
+ }
+}
+
+class MyList extends UnmodifiableList {
+ public MyList() {
+ }
+}
diff --git a/plugins/java-custom-rules/src/test/files/MyCustomRule.java b/plugins/java-custom-rules/src/test/files/MyCustomRule.java
new file mode 100644
index 00000000..29cde439
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/files/MyCustomRule.java
@@ -0,0 +1,10 @@
+class A {
+
+ int foo() {}
+ int foo(int a) {} // Noncompliant {{message}}
+ int foo(int a, int b) {}
+
+ Object foo(Object a){} // Noncompliant {{message}}
+ String foo(String a){} // Noncompliant {{message}}
+ String foo(Object a){}
+}
\ No newline at end of file
diff --git a/plugins/java-custom-rules/src/test/files/SecurityAnnotationMandatoryCheck.java b/plugins/java-custom-rules/src/test/files/SecurityAnnotationMandatoryCheck.java
new file mode 100644
index 00000000..e3b8e263
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/files/SecurityAnnotationMandatoryCheck.java
@@ -0,0 +1,20 @@
+package company.demo;
+
+/**
+ *This file is the sample code against we run our unit test.
+ *It is placed src/test/files in order to not be part of the maven compilation.
+ **/
+class BusinessClassDelegate implements MySecurityInterface, SecondInterface {
+
+ int aField;
+
+ @MySecurityAnnotation
+ public void aMethod() {
+
+ }
+
+ public void aMethod() { // Noncompliant {{Mandatory Annotation not set @MySecurityAnnotation}}
+
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidAnnotationCheckTest.java b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidAnnotationCheckTest.java
new file mode 100644
index 00000000..694ec699
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidAnnotationCheckTest.java
@@ -0,0 +1,22 @@
+package org.sonar.samples.java.checks;
+
+import org.junit.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+public class AvoidAnnotationCheckTest {
+
+ @Test
+ public void detected() {
+
+ // Use an instance of the check under test to raise the issue.
+ AvoidAnnotationRule check = new AvoidAnnotationRule();
+
+ // define the forbidden annotation name
+ check.name = "Zuper";
+
+ // Verifies that the check will raise the adequate issues with the expected message.
+ // In the test file, lines which should raise an issue have been commented out
+ // by using the following syntax: "// Noncompliant {{EXPECTED_MESSAGE}}"
+ JavaCheckVerifier.verify("src/test/files/AvoidAnnotationCheck.java", check);
+ }
+}
diff --git a/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidBrandInMethodNamesCheckTest.java b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidBrandInMethodNamesCheckTest.java
new file mode 100644
index 00000000..45f96d16
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidBrandInMethodNamesCheckTest.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2009-2014 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+
+package org.sonar.samples.java.checks;
+
+import org.junit.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+public class AvoidBrandInMethodNamesCheckTest {
+
+ @Test
+ public void detected() {
+ // Verifies that the check will raise the adequate issues with the expected message.
+ // In the test file, lines which should raise an issue have been commented out
+ // by using the following syntax: "// Noncompliant {{EXPECTED_MESSAGE}}"
+ JavaCheckVerifier.verify("src/test/files/AvoidBrandInMethodNamesCheck.java", new AvoidBrandInMethodNamesRule());
+ }
+}
diff --git a/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidMethodDeclarationCheckTest.java b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidMethodDeclarationCheckTest.java
new file mode 100644
index 00000000..f37a8469
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidMethodDeclarationCheckTest.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009-2014 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+
+package org.sonar.samples.java.checks;
+
+import org.junit.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+/**
+ * This class is the test of the ExampleCheck.
+ * Checks by running it against a minimal valid file.
+ */
+public class AvoidMethodDeclarationCheckTest {
+
+ @Test
+ public void detected() {
+ // Verifies that the check will raise the adequate issues with the expected message.
+ // In the test file, lines which should raise an issue have been commented out
+ // by using the following syntax: "// Noncompliant {{EXPECTED_MESSAGE}}"
+ JavaCheckVerifier.verify("src/test/files/AvoidMethodDeclarationCheck.java", new AvoidMethodDeclarationRule());
+ }
+}
diff --git a/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidSuperClassCheckTest.java b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidSuperClassCheckTest.java
new file mode 100644
index 00000000..a0ae03d1
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidSuperClassCheckTest.java
@@ -0,0 +1,39 @@
+/*
+ * Creation : 20 avr. 2015
+ */
+package org.sonar.samples.java.checks;
+
+import org.junit.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class AvoidSuperClassCheckTest {
+
+ /** JAR dependencies for classpath execution */
+ private static final List CLASSPATH_JAR;
+
+ static {
+ // Jar ClassPath construction. Don't use 'ClassLoader.getSystemClassLoader()', because with Maven+Surefire/Jacoco execution, only
+ // surefirebooter.jar & jacoco.agent-version-runtime.jar are on classpath => 'old schoold way'
+ CLASSPATH_JAR = new ArrayList<>();
+ for (String jar : System.getProperty("java.class.path").split(File.pathSeparator)) {
+ if (jar.endsWith(".jar")) {
+ CLASSPATH_JAR.add(new File(jar));
+ }
+ }
+ }
+
+ @Test
+ public void checkWithJarDependenciesInClassPath() throws Exception {
+ // As external sources are required to run the rule ('symbolType' used in custom rule, which is
+ // part of the semantic API), the test requires external dependencies in order to be run correctly.
+
+ // Verifies that the check will raise the adequate issues with the expected message.
+ // In the test file, lines which should raise an issue have been commented out
+ // by using the following syntax: "// Noncompliant {{EXPECTED_MESSAGE}}"
+ JavaCheckVerifier.verify("src/test/files/AvoidSuperClassCheck.java", new AvoidSuperClassRule(), CLASSPATH_JAR);
+ }
+}
diff --git a/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidUnmodifiableListTest.java b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidUnmodifiableListTest.java
new file mode 100644
index 00000000..2658b75f
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/AvoidUnmodifiableListTest.java
@@ -0,0 +1,18 @@
+package org.sonar.samples.java.checks;
+
+import org.junit.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+public class AvoidUnmodifiableListTest {
+
+ @Test
+ public void verify() {
+ // In order to test this check efficiently, we added the test-jar "org.apache.commons.commons-collections4" to the pom,
+ // which is normally not used by the code of our custom plugin.
+ // All the classes from this jar will then be read when verifying the ticket, allowing correct type resolution.
+
+ // Verifies automatically that the check will raise the adequate issues with the expected message
+ JavaCheckVerifier.verify("src/test/files/AvoidUnmodifiableList.java", new AvoidUnmodifiableListRule());
+ }
+
+}
diff --git a/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/MyCustomSubscriptionRuleTest.java b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/MyCustomSubscriptionRuleTest.java
new file mode 100644
index 00000000..dc00bf48
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/MyCustomSubscriptionRuleTest.java
@@ -0,0 +1,15 @@
+package org.sonar.samples.java.checks;
+
+import org.junit.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+public class MyCustomSubscriptionRuleTest {
+
+ @Test
+ public void check() {
+ // Verifies that the check will raise the adequate issues with the expected message.
+ // In the test file, lines which should raise an issue have been commented out
+ // by using the following syntax: "// Noncompliant {{EXPECTED_MESSAGE}}"
+ JavaCheckVerifier.verify("src/test/files/MyCustomRule.java", new MyCustomSubscriptionRule());
+ }
+}
diff --git a/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/SecurityAnnotationMandatoryCheckTest.java b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/SecurityAnnotationMandatoryCheckTest.java
new file mode 100644
index 00000000..5735f9b7
--- /dev/null
+++ b/plugins/java-custom-rules/src/test/java/org/sonar/samples/java/checks/SecurityAnnotationMandatoryCheckTest.java
@@ -0,0 +1,27 @@
+package org.sonar.samples.java.checks;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+import org.sonar.squidbridge.checks.CheckMessagesVerifierRule;
+
+public class SecurityAnnotationMandatoryCheckTest {
+
+ @Rule
+ public CheckMessagesVerifierRule checkMessagesVerifier = new CheckMessagesVerifierRule();
+
+ @Test
+ public void detected() {
+
+ // Use an instance of the check under test to raise the issue.
+ SecurityAnnotationMandatoryRule check = new SecurityAnnotationMandatoryRule();
+
+ // define the mandatory annotation name
+ check.name = "MySecurityAnnotation";
+
+ // Verifies that the check will raise the adequate issues with the expected message.
+ // In the test file, lines which should raise an issue have been commented out
+ // by using the following syntax: "// Noncompliant {{EXPECTED_MESSAGE}}"
+ JavaCheckVerifier.verify("src/test/files/SecurityAnnotationMandatoryCheck.java", check);
+ }
+}
diff --git a/plugins/javascript-custom-rules/pom.xml b/plugins/javascript-custom-rules/pom.xml
new file mode 100644
index 00000000..13e982a6
--- /dev/null
+++ b/plugins/javascript-custom-rules/pom.xml
@@ -0,0 +1,74 @@
+
+
+ 4.0.0
+
+ com.sonarsource.it.javascript
+ javascript-custom-rules-plugin
+ 1.0-SNAPSHOT
+ sonar-plugin
+
+ JavaScript Custom Rules Plugin
+ JavaScript Custom Rules
+
+
+ 8.7.0.17093
+
+
+
+
+ org.codehaus.sonar
+ sonar-plugin-api
+ 5.0
+ provided
+
+
+
+ org.sonarsource.javascript
+ sonar-javascript-plugin
+ sonar-plugin
+ ${javascript.version}
+ provided
+
+
+
+ org.sonarsource.javascript
+ javascript-checks-testkit
+ ${javascript.version}
+ test
+
+
+
+ junit
+ junit
+ 4.13.2
+
+
+
+
+
+
+ org.sonarsource.sonar-packaging-maven-plugin
+ sonar-packaging-maven-plugin
+ 1.15
+ true
+
+ org.sonar.samples.javascript.JavaScriptCustomRulesPlugin
+ javascript
+ custom
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.7
+ 1.7
+
+
+
+
+
+
diff --git a/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/JavaScriptCustomRulesPlugin.java b/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/JavaScriptCustomRulesPlugin.java
new file mode 100644
index 00000000..605f5703
--- /dev/null
+++ b/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/JavaScriptCustomRulesPlugin.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009-2013 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.javascript;
+
+import com.google.common.collect.ImmutableList;
+import org.sonar.api.SonarPlugin;
+
+import java.util.List;
+
+/**
+ * Extension point to define a Sonar Plugin.
+ */
+public class JavaScriptCustomRulesPlugin extends SonarPlugin {
+
+ @Override
+ public List getExtensions() {
+ return ImmutableList.of(
+ JavascriptCustomRulesDefinition.class
+ );
+ }
+
+}
diff --git a/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/JavascriptCustomRulesDefinition.java b/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/JavascriptCustomRulesDefinition.java
new file mode 100644
index 00000000..1130e8c9
--- /dev/null
+++ b/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/JavascriptCustomRulesDefinition.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009-2013 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.javascript;
+
+
+import org.sonar.plugins.javascript.api.CustomJavaScriptRulesDefinition;
+import org.sonar.samples.javascript.checks.ForbiddenFunctionUseCheck;
+import org.sonar.samples.javascript.checks.OtherForbiddenFunctionUseCheck;
+
+/**
+ * Extension point to define a javascript JavaScript rule repository.
+ */
+public class JavascriptCustomRulesDefinition extends CustomJavaScriptRulesDefinition {
+
+ /**
+ * Provide the repository name
+ */
+ @Override
+ public String repositoryName() {
+ return "Custom Repository";
+ }
+
+ /**
+ * Provide the repository key
+ */
+ @Override
+ public String repositoryKey() {
+ return "custom";
+ }
+
+ /**
+ * Provide the list of checks class that implements rules
+ * to be part of the rule repository
+ */
+ @Override
+ public Class[] checkClasses() {
+ return new Class[] {ForbiddenFunctionUseCheck.class, OtherForbiddenFunctionUseCheck.class};
+ }
+}
diff --git a/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/checks/ForbiddenFunctionUseCheck.java b/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/checks/ForbiddenFunctionUseCheck.java
new file mode 100644
index 00000000..a3a51ada
--- /dev/null
+++ b/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/checks/ForbiddenFunctionUseCheck.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009-2013 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.javascript.checks;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.javascript.api.tree.Tree.Kind;
+import org.sonar.plugins.javascript.api.tree.expression.CallExpressionTree;
+import org.sonar.plugins.javascript.api.tree.expression.ExpressionTree;
+import org.sonar.plugins.javascript.api.tree.expression.IdentifierTree;
+import org.sonar.plugins.javascript.api.visitors.DoubleDispatchVisitorCheck;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+/**
+ * Example of implementation of a check by extending {@link DoubleDispatchVisitorCheck}.
+ * DoubleDispatchVisitorCheck provides methods to visit nodes of the Abstract Syntax Tree
+ * that represents the source code.
+ *
+ * Those methods can be overridden to process information
+ * related to node and issues can be created via {@link DoubleDispatchVisitorCheck#addIssue} methods}.
+ */
+@Rule(
+ key = "S1",
+ priority = Priority.MAJOR,
+ name = "Forbidden function should not be used.",
+ tags = {"convention"}
+// Description can either be given in this annotation or through HTML name .html located in package src/resources/org/sonar/l10n/javascript/rules/
+// description = "
The following functions should not be used:
foo
bar
",
+ )
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.DATA_RELIABILITY)
+@SqaleConstantRemediation("5min")
+public class ForbiddenFunctionUseCheck extends DoubleDispatchVisitorCheck {
+
+ private static final Set FORBIDDEN_FUNCTIONS = ImmutableSet.of("foo", "bar");
+
+ /**
+ * Overriding method visiting the call expression to create an issue
+ * each time a call to "foo()" or "bar()" is done.
+ */
+ @Override
+ public void visitCallExpression(CallExpressionTree tree) {
+ ExpressionTree callee = tree.callee();
+
+ if (callee.is(Kind.IDENTIFIER_REFERENCE) && FORBIDDEN_FUNCTIONS.contains(((IdentifierTree) callee).name())) {
+ addIssue(tree, "Remove the usage of this forbidden function.");
+ }
+
+ // super method must be called in order to visit what is under the function node in the syntax tree
+ super.visitCallExpression(tree);
+ }
+
+}
diff --git a/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/checks/OtherForbiddenFunctionUseCheck.java b/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/checks/OtherForbiddenFunctionUseCheck.java
new file mode 100644
index 00000000..dd5289de
--- /dev/null
+++ b/plugins/javascript-custom-rules/src/main/java/org/sonar/samples/javascript/checks/OtherForbiddenFunctionUseCheck.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009-2013 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.javascript.checks;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.util.List;
+import java.util.Set;
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.javascript.api.tree.Tree;
+import org.sonar.plugins.javascript.api.tree.Tree.Kind;
+import org.sonar.plugins.javascript.api.tree.expression.CallExpressionTree;
+import org.sonar.plugins.javascript.api.tree.expression.ExpressionTree;
+import org.sonar.plugins.javascript.api.tree.expression.IdentifierTree;
+import org.sonar.plugins.javascript.api.visitors.SubscriptionVisitorCheck;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+/**
+ * Example of a check extending {@link SubscriptionVisitorCheck}.
+ *
+ * We define the kinds of the nodes that we subscribe to in {@link #nodesToVisit()}.
+ * We can then override visitNode or leaveNode: these methods will be called for all nodes
+ * of the kinds we subscribed to.
+ */
+@Rule(
+ key = "S2",
+ priority = Priority.MINOR,
+ name = "'baz' function should not be used.",
+ tags = {"convention"},
+ description = "It's better not to use the 'baz' function."
+ )
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.DATA_RELIABILITY)
+@SqaleConstantRemediation("5min")
+public class OtherForbiddenFunctionUseCheck extends SubscriptionVisitorCheck {
+
+ private static final Set FORBIDDEN_FUNCTIONS = ImmutableSet.of("baz");
+
+ @Override
+ public List nodesToVisit() {
+ return ImmutableList.of(Kind.CALL_EXPRESSION);
+ }
+
+ @Override
+ public void visitNode(Tree tree) {
+ // we can do this cast because we subscribed only to nodes of kind CALL_EXPRESSION
+ CallExpressionTree callExpressionTree = (CallExpressionTree) tree;
+ ExpressionTree callee = callExpressionTree.callee();
+ if (callee.is(Kind.IDENTIFIER_REFERENCE) && FORBIDDEN_FUNCTIONS.contains(((IdentifierTree) callee).name())) {
+ addIssue(tree, "Remove the usage of this forbidden function.");
+ }
+ }
+
+}
diff --git a/plugins/javascript-custom-rules/src/main/resources/org/sonar/l10n/javascript/rules/custom/S1.html b/plugins/javascript-custom-rules/src/main/resources/org/sonar/l10n/javascript/rules/custom/S1.html
new file mode 100644
index 00000000..1bf97c04
--- /dev/null
+++ b/plugins/javascript-custom-rules/src/main/resources/org/sonar/l10n/javascript/rules/custom/S1.html
@@ -0,0 +1,7 @@
+
+ The following functions should not be used:
+
+
+
foo
+
bar
+
\ No newline at end of file
diff --git a/plugins/javascript-custom-rules/src/test/java/org/sonar/samples/javascript/checks/ForbiddenFunctionUseCheckTest.java b/plugins/javascript-custom-rules/src/test/java/org/sonar/samples/javascript/checks/ForbiddenFunctionUseCheckTest.java
new file mode 100644
index 00000000..f0dad742
--- /dev/null
+++ b/plugins/javascript-custom-rules/src/test/java/org/sonar/samples/javascript/checks/ForbiddenFunctionUseCheckTest.java
@@ -0,0 +1,22 @@
+package org.sonar.samples.javascript.checks;
+
+import java.io.File;
+import org.junit.Test;
+import org.sonar.javascript.checks.verifier.JavaScriptCheckVerifier;
+
+/**
+ * Test class to test the check implementation.
+ */
+public class ForbiddenFunctionUseCheckTest {
+
+ @Test
+ public void test() throws Exception {
+ JavaScriptCheckVerifier.issues(new ForbiddenFunctionUseCheck(), new File("src/test/resources/checks/forbiddenFunctionUseCheck.js"))
+ .next().atLine(1).withMessage("Remove the usage of this forbidden function.")
+ .next().atLine(2)
+ .next().atLine(4)
+ .next().atLine(5)
+ .noMore();
+ }
+
+}
diff --git a/plugins/javascript-custom-rules/src/test/java/org/sonar/samples/javascript/checks/OtherForbiddenFunctionUseCheckTest.java b/plugins/javascript-custom-rules/src/test/java/org/sonar/samples/javascript/checks/OtherForbiddenFunctionUseCheckTest.java
new file mode 100644
index 00000000..ea361f0a
--- /dev/null
+++ b/plugins/javascript-custom-rules/src/test/java/org/sonar/samples/javascript/checks/OtherForbiddenFunctionUseCheckTest.java
@@ -0,0 +1,17 @@
+package org.sonar.samples.javascript.checks;
+
+import java.io.File;
+import org.junit.Test;
+import org.sonar.javascript.checks.verifier.JavaScriptCheckVerifier;
+
+/**
+ * Test class to test the check implementation.
+ */
+public class OtherForbiddenFunctionUseCheckTest {
+
+ @Test
+ public void test() throws Exception {
+ JavaScriptCheckVerifier.verify(new OtherForbiddenFunctionUseCheck(), new File("src/test/resources/checks/otherForbiddenFunctionUseCheck.js"));
+ }
+
+}
diff --git a/plugins/javascript-custom-rules/src/test/resources/checks/forbiddenFunctionUseCheck.js b/plugins/javascript-custom-rules/src/test/resources/checks/forbiddenFunctionUseCheck.js
new file mode 100644
index 00000000..773a9332
--- /dev/null
+++ b/plugins/javascript-custom-rules/src/test/resources/checks/forbiddenFunctionUseCheck.js
@@ -0,0 +1,20 @@
+foo(); // NOK
+foo(1); // NOK
+
+bar(); // NOK
+bar(1); // NOK
+
+var Obj = {
+ foo : function () {
+ return "foo";
+ },
+
+ bar : function () {
+ return "bar";
+ }
+};
+
+var myObj = new Obj();
+
+myObj.foo(); // OK
+myObj.bar(); // OK
\ No newline at end of file
diff --git a/plugins/javascript-custom-rules/src/test/resources/checks/otherForbiddenFunctionUseCheck.js b/plugins/javascript-custom-rules/src/test/resources/checks/otherForbiddenFunctionUseCheck.js
new file mode 100644
index 00000000..5ef61f24
--- /dev/null
+++ b/plugins/javascript-custom-rules/src/test/resources/checks/otherForbiddenFunctionUseCheck.js
@@ -0,0 +1,6 @@
+baz(); // Noncompliant
+baz(1); // Noncompliant {{Remove the usage of this forbidden function.}} [[sc=1;ec=7]]
+
+foo();
+
+x.baz(); // OK
diff --git a/plugins/sonar-checkstyle-extension-plugin/pom.xml b/plugins/php-custom-rules/pom.xml
similarity index 53%
rename from plugins/sonar-checkstyle-extension-plugin/pom.xml
rename to plugins/php-custom-rules/pom.xml
index 083e32f2..31310099 100644
--- a/plugins/sonar-checkstyle-extension-plugin/pom.xml
+++ b/plugins/php-custom-rules/pom.xml
@@ -2,47 +2,62 @@
4.0.0
- org.codehaus.sonar.examples
- sonar-checkstyle-extension-plugin
+
+ org.sonar.examples
+ php-custom-rules1.0-SNAPSHOTsonar-plugin
- Sonar Examples :: Checkstyle Extension Plugin
+
+ PHP Custom Rules
+ PHP Custom Rulesorg.codehaus.sonarsonar-plugin-api
- 2.11
+ 5.0
+ provided
+
+
+
+ org.sonarsource.php
+ sonar-php-plugin
+ sonar-plugin
+ 3.23.0.8726
+ provided
+
- com.puppycrawl.tools
- checkstyle
- 5.5
+ junit
+ junit
+ 4.13.1
- org.codehaus.sonar
+ org.sonarsource.sonar-packaging-maven-pluginsonar-packaging-maven-plugin
- 1.1
+ 1.15true
- org.sonar.examples.checkstyle.CheckstyleExtensionPlugin
- checkstyle
+ org.sonar.samples.php.PHPCustomRulesPlugin
+ php
+ custom
+
org.apache.maven.pluginsmaven-compiler-plugin2.3.2
- 1.5
- 1.5
- UTF-8
+ 1.7
+ 1.7
+
diff --git a/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/PHPCustomRulesPlugin.java b/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/PHPCustomRulesPlugin.java
new file mode 100644
index 00000000..2d2f7327
--- /dev/null
+++ b/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/PHPCustomRulesPlugin.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009-2013 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.php;
+
+import com.google.common.collect.ImmutableList;
+import org.sonar.api.SonarPlugin;
+
+import java.util.List;
+
+/**
+ * Extension point to define a Sonar Plugin.
+ */
+public class PHPCustomRulesPlugin extends SonarPlugin {
+
+ @Override
+ public List getExtensions() {
+ return ImmutableList.of(
+ PHPRulesDefinition.class
+ );
+ }
+
+}
diff --git a/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/PHPRulesDefinition.java b/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/PHPRulesDefinition.java
new file mode 100644
index 00000000..f26e2a44
--- /dev/null
+++ b/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/PHPRulesDefinition.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009-2013 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.php;
+
+
+import com.google.common.collect.ImmutableList;
+
+import org.sonar.plugins.php.api.visitors.PHPCustomRulesDefinition;
+import org.sonar.samples.php.checks.ForbiddenFunctionUseCheck;
+
+/**
+ * Extension point to define a PHP rule repository.
+ */
+public class PHPRulesDefinition extends PHPCustomRulesDefinition {
+
+ /**
+ * Provide the repository name
+ */
+ @Override
+ public String repositoryName() {
+ return "Custom Repository";
+ }
+
+ /**
+ * Provide the repository key
+ */
+ @Override
+ public String repositoryKey() {
+ return "custom";
+ }
+
+ /**
+ * Provide the list of checks class that implements rules
+ * to be part of the rule repository
+ */
+ @Override
+ public ImmutableList checkClasses() {
+ return ImmutableList.of(ForbiddenFunctionUseCheck.class);
+ }
+}
diff --git a/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/checks/ForbiddenFunctionUseCheck.java b/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/checks/ForbiddenFunctionUseCheck.java
new file mode 100644
index 00000000..2ff7d882
--- /dev/null
+++ b/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/checks/ForbiddenFunctionUseCheck.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009-2013 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.php.checks;
+
+import com.google.common.collect.ImmutableSet;
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.php.api.tree.Tree.Kind;
+import org.sonar.plugins.php.api.tree.declaration.NamespaceNameTree;
+import org.sonar.plugins.php.api.tree.expression.ExpressionTree;
+import org.sonar.plugins.php.api.tree.expression.FunctionCallTree;
+import org.sonar.plugins.php.api.visitors.PHPVisitorCheck;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+import java.util.Set;
+
+/**
+ * Example of implementation of a check by extending {@link PHPVisitorCheck}.
+ * PHPVisitorCheck provides methods to visit nodes of the Abstract Syntax Tree
+ * that represents the source code.
+ *
+ * Those methods can be overridden to process information
+ * related to node and issue can be created via the context that can be
+ * accessed through {@link PHPVisitorCheck#context()}.
+ */
+@Rule(
+ key = "S1",
+ priority = Priority.MAJOR,
+ name = "Forbidden function should not be used.",
+ tags = {"convention"}
+// Description can either be given in this annotation or through HTML name .html located in package src/resources/org/sonar/l10n/php/rules/
+// description = "
The following functions should not be used:
foo
bar
"
+ )
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.DATA_RELIABILITY)
+@SqaleConstantRemediation("5min")
+public class ForbiddenFunctionUseCheck extends PHPVisitorCheck {
+
+ private static final Set FORBIDDEN_FUNCTIONS = ImmutableSet.of("foo", "bar");
+
+ /**
+ * Overriding method visiting the call expression to create an issue
+ * each time a call to "foo()" or "bar()" is done.
+ */
+ @Override
+ public void visitFunctionCall(FunctionCallTree tree) {
+ ExpressionTree callee = tree.callee();
+
+ if (callee.is(Kind.NAMESPACE_NAME) && FORBIDDEN_FUNCTIONS.contains(((NamespaceNameTree) callee).qualifiedName())) {
+ context().newIssue(this, "Remove the usage of this forbidden function.").tree(tree);
+ }
+
+ // super method must be called in order to visit function call node's children
+ super.visitFunctionCall(tree);
+ }
+
+}
diff --git a/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/checks/OtherForbiddenFunctionUseCheck.java b/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/checks/OtherForbiddenFunctionUseCheck.java
new file mode 100644
index 00000000..b535bd2e
--- /dev/null
+++ b/plugins/php-custom-rules/src/main/java/org/sonar/samples/php/checks/OtherForbiddenFunctionUseCheck.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009-2013 SonarSource SA
+ * All rights reserved
+ * mailto:contact AT sonarsource DOT com
+ */
+package org.sonar.samples.php.checks;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.php.api.tree.Tree;
+import org.sonar.plugins.php.api.tree.Tree.Kind;
+import org.sonar.plugins.php.api.tree.declaration.NamespaceNameTree;
+import org.sonar.plugins.php.api.tree.expression.ExpressionTree;
+import org.sonar.plugins.php.api.tree.expression.FunctionCallTree;
+import org.sonar.plugins.php.api.visitors.PHPSubscriptionCheck;
+import org.sonar.plugins.php.api.visitors.PHPVisitorCheck;
+import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
+import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Example of implementation of a check by extending {@link PHPSubscriptionCheck}.
+ * PHPSubscriptionCheck provides method {@link PHPSubscriptionCheck#visitNode} to visit nodes of the Abstract Syntax Tree
+ * that represents the source code. Provide the list of nodes you want to visit through {@link PHPSubscriptionCheck#nodesToVisit}.
+ *
+ * Those methods should be overridden to process information
+ * related to node and issue can be created via the context that can be
+ * accessed through {@link PHPVisitorCheck#context()}.
+ */
+@Rule(
+ key = "S1",
+ priority = Priority.MAJOR,
+ name = "Forbidden function should not be used.",
+ tags = {"convention"}
+// Description can either be given in this annotation or through HTML name .html located in package src/resources/org/sonar/l10n/php/rules/
+// description = "
The following functions should not be used:
foo
bar
",
+ )
+@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.DATA_RELIABILITY)
+@SqaleConstantRemediation("5min")
+public class OtherForbiddenFunctionUseCheck extends PHPSubscriptionCheck {
+
+ private static final Set FORBIDDEN_FUNCTIONS = ImmutableSet.of("foo", "bar");
+
+ @Override
+ public List nodesToVisit() {
+ return ImmutableList.of(Kind.FUNCTION_CALL);
+ }
+
+ /**
+ * Overriding method visiting the call expression to create an issue
+ * each time a call to "foo()" or "bar()" is done.
+ */
+ @Override
+ public void visitNode(Tree tree) {
+ ExpressionTree callee = ((FunctionCallTree) tree).callee();
+
+ if (callee.is(Kind.NAMESPACE_NAME) && FORBIDDEN_FUNCTIONS.contains(((NamespaceNameTree) callee).qualifiedName())) {
+ context().newIssue(this, "Remove the usage of this forbidden function.").tree(tree);
+ }
+ }
+
+}
diff --git a/plugins/php-custom-rules/src/main/resources/org/sonar/l10n/php/rules/custom/S1.html b/plugins/php-custom-rules/src/main/resources/org/sonar/l10n/php/rules/custom/S1.html
new file mode 100644
index 00000000..1bf97c04
--- /dev/null
+++ b/plugins/php-custom-rules/src/main/resources/org/sonar/l10n/php/rules/custom/S1.html
@@ -0,0 +1,7 @@
+
+ The following functions should not be used:
+
+
+
foo
+
bar
+
\ No newline at end of file
diff --git a/plugins/php-custom-rules/src/test/java/org/sonar/samples/php/checks/ForbiddenFunctionUseCheckTest.java b/plugins/php-custom-rules/src/test/java/org/sonar/samples/php/checks/ForbiddenFunctionUseCheckTest.java
new file mode 100644
index 00000000..5037d0e6
--- /dev/null
+++ b/plugins/php-custom-rules/src/test/java/org/sonar/samples/php/checks/ForbiddenFunctionUseCheckTest.java
@@ -0,0 +1,18 @@
+package org.sonar.samples.php.checks;
+
+import org.junit.Test;
+import org.sonar.plugins.php.api.tests.PHPCheckTest;
+
+import java.io.File;
+
+/**
+ * Test class to test the check implementation.
+ */
+public class ForbiddenFunctionUseCheckTest {
+
+ @Test
+ public void test() throws Exception {
+ PHPCheckTest.check(new ForbiddenFunctionUseCheck(), new File("src/test/resources/checks/forbiddenFunctionUseCheck.js"));
+ }
+
+}
diff --git a/plugins/php-custom-rules/src/test/java/org/sonar/samples/php/checks/OtherForbiddenFunctionUseCheckTest.java b/plugins/php-custom-rules/src/test/java/org/sonar/samples/php/checks/OtherForbiddenFunctionUseCheckTest.java
new file mode 100644
index 00000000..ffb8e3ec
--- /dev/null
+++ b/plugins/php-custom-rules/src/test/java/org/sonar/samples/php/checks/OtherForbiddenFunctionUseCheckTest.java
@@ -0,0 +1,18 @@
+package org.sonar.samples.php.checks;
+
+import org.junit.Test;
+import org.sonar.plugins.php.api.tests.PHPCheckTest;
+
+import java.io.File;
+
+/**
+ * Test class to test the check implementation.
+ */
+public class OtherForbiddenFunctionUseCheckTest {
+
+ @Test
+ public void test() throws Exception {
+ PHPCheckTest.check(new OtherForbiddenFunctionUseCheck(), new File("src/test/resources/checks/forbiddenFunctionUseCheck.js"));
+ }
+
+}
diff --git a/plugins/php-custom-rules/src/test/resources/checks/forbiddenFunctionUseCheck.js b/plugins/php-custom-rules/src/test/resources/checks/forbiddenFunctionUseCheck.js
new file mode 100644
index 00000000..cd501c59
--- /dev/null
+++ b/plugins/php-custom-rules/src/test/resources/checks/forbiddenFunctionUseCheck.js
@@ -0,0 +1,20 @@
+foo(); // NOK {{Remove the usage of this forbidden function.}}
+foo(1); // NOK
+
+bar(); // NOK
+bar(1); // NOK
+
+var Obj = {
+ foo : function () {
+ return "foo";
+ },
+
+ bar : function () {
+ return "bar";
+ }
+};
+
+var myObj = new Obj();
+
+myObj.foo(); // OK
+myObj.bar(); // OK
diff --git a/plugins/sonar-checkstyle-extension-plugin/src/main/java/org/sonar/examples/checkstyle/CheckstyleExtensionPlugin.java b/plugins/sonar-checkstyle-extension-plugin/src/main/java/org/sonar/examples/checkstyle/CheckstyleExtensionPlugin.java
deleted file mode 100644
index 7fe7ea36..00000000
--- a/plugins/sonar-checkstyle-extension-plugin/src/main/java/org/sonar/examples/checkstyle/CheckstyleExtensionPlugin.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.sonar.examples.checkstyle;
-
-import org.sonar.api.SonarPlugin;
-
-import java.util.Arrays;
-import java.util.List;
-
-public final class CheckstyleExtensionPlugin extends SonarPlugin {
- public List getExtensions() {
- return Arrays.asList(CheckstyleExtensionRepository.class);
- }
-}
diff --git a/plugins/sonar-checkstyle-extension-plugin/src/main/java/org/sonar/examples/checkstyle/CheckstyleExtensionRepository.java b/plugins/sonar-checkstyle-extension-plugin/src/main/java/org/sonar/examples/checkstyle/CheckstyleExtensionRepository.java
deleted file mode 100644
index 458fcf16..00000000
--- a/plugins/sonar-checkstyle-extension-plugin/src/main/java/org/sonar/examples/checkstyle/CheckstyleExtensionRepository.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.sonar.examples.checkstyle;
-
-import org.apache.commons.io.IOUtils;
-import org.sonar.api.resources.Java;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleRepository;
-import org.sonar.api.rules.XMLRuleParser;
-
-import java.io.InputStream;
-import java.util.List;
-
-public final class CheckstyleExtensionRepository extends RuleRepository {
-
- private XMLRuleParser xmlRuleParser;
-
- public CheckstyleExtensionRepository(XMLRuleParser xmlRuleParser) {
- super("checkstyle", Java.KEY);
- setName("Checkstyle");
- this.xmlRuleParser = xmlRuleParser;
- }
-
- @Override
- public List createRules() {
- InputStream input = getClass().getResourceAsStream("/org/sonar/examples/checkstyle/checkstyle-extensions.xml");
- try {
- return xmlRuleParser.parse(input);
-
- } finally {
- IOUtils.closeQuietly(input);
- }
- }
-}
diff --git a/plugins/sonar-checkstyle-extension-plugin/src/main/java/org/sonar/examples/checkstyle/MethodsCountCheck.java b/plugins/sonar-checkstyle-extension-plugin/src/main/java/org/sonar/examples/checkstyle/MethodsCountCheck.java
deleted file mode 100644
index 85653968..00000000
--- a/plugins/sonar-checkstyle-extension-plugin/src/main/java/org/sonar/examples/checkstyle/MethodsCountCheck.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.sonar.examples.checkstyle;
-
-import com.puppycrawl.tools.checkstyle.api.Check;
-import com.puppycrawl.tools.checkstyle.api.DetailAST;
-import com.puppycrawl.tools.checkstyle.api.TokenTypes;
-
-public class MethodsCountCheck extends Check {
-
- private int maxMethodsCount = 1;
-
- private int methodsCount = 0;
- private DetailAST classAST = null;
-
- public void setMaxMethodsCount(int maxMethodsCount) {
- this.maxMethodsCount = maxMethodsCount;
- }
-
- public int[] getDefaultTokens() {
- return new int[]{TokenTypes.CLASS_DEF, TokenTypes.METHOD_DEF};
- }
-
- public void beginTree(DetailAST rootAST) {
- methodsCount = 0;
- classAST = null;
- }
-
- public void visitToken(DetailAST ast) {
- //ensure this is an unit test.
- if (ast.getType() == TokenTypes.CLASS_DEF) {
- classAST = ast;
-
- } else if (ast.getType() == TokenTypes.METHOD_DEF) {
- methodsCount++;
- }
- }
-
- public void finishTree(DetailAST rootAST) {
- super.finishTree(rootAST);
- if (classAST != null && methodsCount > maxMethodsCount) {
- log(classAST.getLineNo(), classAST.getColumnNo(), "Too many methods (" + methodsCount + ") in class");
- }
- }
-}
diff --git a/plugins/sonar-checkstyle-extension-plugin/src/main/resources/org/sonar/examples/checkstyle/checkstyle-extensions.xml b/plugins/sonar-checkstyle-extension-plugin/src/main/resources/org/sonar/examples/checkstyle/checkstyle-extensions.xml
deleted file mode 100644
index 61ff7b1b..00000000
--- a/plugins/sonar-checkstyle-extension-plugin/src/main/resources/org/sonar/examples/checkstyle/checkstyle-extensions.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- org.sonar.examples.checkstyle.MethodsCountCheck
- Methods Count Check
- Checker/TreeWalker/org.sonar.examples.checkstyle.MethodsCountCheck
-
- Count methods
-
- maxMethodsCount
- Maximum number of methods. Default is 10.
-
-
-
\ No newline at end of file
diff --git a/plugins/sonar-reference-plugin/pom.xml b/plugins/sonar-example-plugin/pom.xml
similarity index 55%
rename from plugins/sonar-reference-plugin/pom.xml
rename to plugins/sonar-example-plugin/pom.xml
index 4795e768..d6856a64 100644
--- a/plugins/sonar-reference-plugin/pom.xml
+++ b/plugins/sonar-example-plugin/pom.xml
@@ -1,33 +1,47 @@
-
+4.0.0
- org.codehaus.sonar.examples
- sonar-reference-plugin
+
+ org.sonarsource.plugins.example
+ sonar-example-pluginsonar-plugin0.1-SNAPSHOT
- Sonar Examples :: Reference Plugin
- plugin description will be displayed in Sonar
+
+ Example Plugin for SonarQube
+ Example of plugin for SonarQube
- 2.10UTF-8
- 1.5
+ 7.4
+ 1.8
- org.codehaus.sonar
+ org.sonarsource.sonarqubesonar-plugin-api
- ${sonar.buildVersion}
+ ${sonar.apiVersion}provided
+
+
+ commons-lang
+ commons-lang
+ 2.6
+
+
- org.codehaus.sonar
+ org.sonarsource.sonarqubesonar-testing-harness
- ${sonar.buildVersion}
+ ${sonar.apiVersion}
+ test
+
+
+ junit
+ junit
+ 4.11test
@@ -35,18 +49,18 @@
- org.codehaus.sonar
+ org.sonarsource.sonar-packaging-maven-pluginsonar-packaging-maven-plugin
- 1.1
+ 1.16true
- com.mycompany.sonar.reference.ExamplePlugin
+ org.sonarsource.plugins.example.ExamplePluginorg.apache.maven.pluginsmaven-compiler-plugin
- 2.0.2
+ 3.5.1${jdk.min.version}${jdk.min.version}
@@ -56,21 +70,16 @@
org.codehaus.mojonative2ascii-maven-plugin
- 1.0-alpha-1
+ 1.0-beta-1native2ascii
-
- UTF8
- ${basedir}/src/main/resources
- ${project.build.outputDirectory}
- **/*.properties
-
+
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/ExamplePlugin.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/ExamplePlugin.java
new file mode 100644
index 00000000..6337095f
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/ExamplePlugin.java
@@ -0,0 +1,51 @@
+package org.sonarsource.plugins.example;
+
+import org.sonar.api.Plugin;
+import org.sonarsource.plugins.example.hooks.DisplayIssuesInScanner;
+import org.sonarsource.plugins.example.hooks.DisplayQualityGateStatus;
+import org.sonarsource.plugins.example.languages.FooLanguage;
+import org.sonarsource.plugins.example.languages.FooQualityProfile;
+import org.sonarsource.plugins.example.measures.ComputeSizeAverage;
+import org.sonarsource.plugins.example.measures.ComputeSizeRating;
+import org.sonarsource.plugins.example.measures.ExampleMetrics;
+import org.sonarsource.plugins.example.measures.SetSizeOnFilesSensor;
+import org.sonarsource.plugins.example.rules.CreateIssuesOnJavaFilesSensor;
+import org.sonarsource.plugins.example.rules.FooLintIssuesLoaderSensor;
+import org.sonarsource.plugins.example.rules.FooLintRulesDefinition;
+import org.sonarsource.plugins.example.rules.JavaRulesDefinition;
+import org.sonarsource.plugins.example.settings.ExampleProperties;
+import org.sonarsource.plugins.example.settings.SayHelloFromScanner;
+import org.sonarsource.plugins.example.web.ExampleFooter;
+import org.sonarsource.plugins.example.web.ExampleWidget;
+
+/**
+ * This class is the entry point for all extensions. It is referenced in pom.xml.
+ */
+public class ExamplePlugin implements Plugin {
+
+ @Override
+ public void define(Context context) {
+ // tutorial on hooks
+ // http://docs.sonarqube.org/display/DEV/Adding+Hooks
+ context.addExtensions(DisplayIssuesInScanner.class, DisplayQualityGateStatus.class);
+
+ // tutorial on languages
+ context.addExtensions(FooLanguage.class, FooQualityProfile.class);
+
+ // tutorial on measures
+ context
+ .addExtensions(ExampleMetrics.class, SetSizeOnFilesSensor.class, ComputeSizeAverage.class, ComputeSizeRating.class);
+
+ // tutorial on rules
+ context.addExtensions(JavaRulesDefinition.class, CreateIssuesOnJavaFilesSensor.class);
+ context.addExtensions(FooLintRulesDefinition.class, FooLintIssuesLoaderSensor.class);
+
+ // tutorial on settings
+ context
+ .addExtensions(ExampleProperties.definitions())
+ .addExtension(SayHelloFromScanner.class);
+
+ // tutorial on web extensions
+ context.addExtensions(ExampleFooter.class, ExampleWidget.class);
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/hooks/DisplayIssuesInScanner.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/hooks/DisplayIssuesInScanner.java
new file mode 100644
index 00000000..ad48cf70
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/hooks/DisplayIssuesInScanner.java
@@ -0,0 +1,39 @@
+package org.sonarsource.plugins.example.hooks;
+
+import org.sonar.api.batch.postjob.PostJob;
+import org.sonar.api.batch.postjob.PostJobContext;
+import org.sonar.api.batch.postjob.PostJobDescriptor;
+import org.sonar.api.batch.postjob.issue.PostJobIssue;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+
+public class DisplayIssuesInScanner implements PostJob {
+
+ private static final Logger LOGGER = Loggers.get(DisplayIssuesInScanner.class);
+
+ @Override
+ public void describe(PostJobDescriptor descriptor) {
+ descriptor.name("Display issues");
+ }
+
+ @Override
+ public void execute(PostJobContext context) {
+ // issues are not accessible when the mode "issues" is not enabled
+ // with the scanner property "sonar.analysis.mode=issues"
+ if (context.analysisMode().isIssues()) {
+ // all open issues
+ for (PostJobIssue issue : context.issues()) {
+ String ruleKey = issue.ruleKey().toString();
+ Integer issueLine = issue.line();
+
+ // just to illustrate, we dump some fields of the 'issue' in sysout (bad, very bad)
+ LOGGER.info("OPEN {} : {}({})", ruleKey, issue.componentKey(), issueLine);
+ }
+
+ // all resolved issues
+ for (PostJobIssue issue : context.resolvedIssues()) {
+ LOGGER.info("RESOLVED {} : {}({})", issue.ruleKey(), issue.componentKey(), issue.line());
+ }
+ }
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/hooks/DisplayQualityGateStatus.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/hooks/DisplayQualityGateStatus.java
new file mode 100644
index 00000000..dcfc0437
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/hooks/DisplayQualityGateStatus.java
@@ -0,0 +1,20 @@
+package org.sonarsource.plugins.example.hooks;
+
+import org.sonar.api.ce.posttask.PostProjectAnalysisTask;
+import org.sonar.api.ce.posttask.QualityGate;
+import org.sonar.api.utils.log.Loggers;
+
+/**
+ * Logs the Quality gate status in Compute Engine when analysis is finished (browse
+ * Administration > Projects > Background Tasks).
+ * A real use-case would be to send an email or to notify an IRC channel.
+ */
+public class DisplayQualityGateStatus implements PostProjectAnalysisTask {
+ @Override
+ public void finished(ProjectAnalysis analysis) {
+ QualityGate gate = analysis.getQualityGate();
+ if (gate != null) {
+ Loggers.get(getClass()).info("Quality gate is " + gate.getStatus());
+ }
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/languages/FooLanguage.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/languages/FooLanguage.java
new file mode 100644
index 00000000..5e51be88
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/languages/FooLanguage.java
@@ -0,0 +1,45 @@
+package org.sonarsource.plugins.example.languages;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.config.Settings;
+import org.sonar.api.resources.AbstractLanguage;
+
+/**
+ * This class defines the fictive Foo language.
+ */
+public final class FooLanguage extends AbstractLanguage {
+
+ public static final String NAME = "Foo";
+ public static final String KEY = "foo";
+ public static final String FILE_SUFFIXES_PROPERTY_KEY = "sonar.foo.file.suffixes";
+ public static final String DEFAULT_FILE_SUFFIXES = "foo";
+
+ private final Settings settings;
+
+ public FooLanguage(Settings settings) {
+ super(KEY, NAME);
+ this.settings = settings;
+ }
+
+ @Override
+ public String[] getFileSuffixes() {
+ String[] suffixes = filterEmptyStrings(settings.getStringArray(FILE_SUFFIXES_PROPERTY_KEY));
+ if (suffixes.length == 0) {
+ suffixes = StringUtils.split(DEFAULT_FILE_SUFFIXES, ",");
+ }
+ return suffixes;
+ }
+
+ private String[] filterEmptyStrings(String[] stringArray) {
+ List nonEmptyStrings = new ArrayList<>();
+ for (String string : stringArray) {
+ if (StringUtils.isNotBlank(string.trim())) {
+ nonEmptyStrings.add(string.trim());
+ }
+ }
+ return nonEmptyStrings.toArray(new String[nonEmptyStrings.size()]);
+ }
+
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/languages/FooQualityProfile.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/languages/FooQualityProfile.java
new file mode 100644
index 00000000..3999a6e2
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/languages/FooQualityProfile.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube Protocol Buffers Plugin
+ * Copyright (C) 2015 SonarSource
+ * sonarqube@googlegroups.com
+ *
+ * This program 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.
+ *
+ * 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
+ * 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 02
+ */
+package org.sonarsource.plugins.example.languages;
+
+import org.sonar.api.profiles.ProfileDefinition;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.utils.ValidationMessages;
+
+/**
+ * Default Quality profile for the projects having files of language "foo"
+ */
+public final class FooQualityProfile extends ProfileDefinition {
+
+ @Override
+ public RulesProfile createProfile(ValidationMessages validation) {
+ return RulesProfile.create("FooLint Rules", FooLanguage.KEY);
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/ComputeSizeAverage.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/ComputeSizeAverage.java
new file mode 100644
index 00000000..cb31299d
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/ComputeSizeAverage.java
@@ -0,0 +1,33 @@
+package org.sonarsource.plugins.example.measures;
+
+import org.sonar.api.ce.measure.Component;
+import org.sonar.api.ce.measure.Measure;
+import org.sonar.api.ce.measure.MeasureComputer;
+
+import static org.sonarsource.plugins.example.measures.ExampleMetrics.FILENAME_SIZE;
+
+public class ComputeSizeAverage implements MeasureComputer {
+
+ @Override
+ public MeasureComputerDefinition define(MeasureComputerDefinitionContext def) {
+ return def.newDefinitionBuilder()
+ .setOutputMetrics(FILENAME_SIZE.key())
+ .build();
+ }
+
+ @Override
+ public void compute(MeasureComputerContext context) {
+ // measure is already defined on files by {@link SetSizeOnFilesSensor}
+ // in scanner stack
+ if (context.getComponent().getType() != Component.Type.FILE) {
+ int sum = 0;
+ int count = 0;
+ for (Measure child : context.getChildrenMeasures(FILENAME_SIZE.key())) {
+ sum += child.getIntValue();
+ count++;
+ }
+ int average = count == 0 ? 0 : sum / count;
+ context.addMeasure(FILENAME_SIZE.key(), average);
+ }
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/ComputeSizeRating.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/ComputeSizeRating.java
new file mode 100644
index 00000000..2e48a8e7
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/ComputeSizeRating.java
@@ -0,0 +1,38 @@
+package org.sonarsource.plugins.example.measures;
+
+import org.sonar.api.ce.measure.Measure;
+import org.sonar.api.ce.measure.MeasureComputer;
+
+import static org.sonarsource.plugins.example.measures.ExampleMetrics.FILENAME_SIZE;
+import static org.sonarsource.plugins.example.measures.ExampleMetrics.FILENAME_SIZE_RATING;
+
+/**
+ * Rating is computed from value of metric {@link ExampleMetrics#FILENAME_SIZE}.
+ */
+public class ComputeSizeRating implements MeasureComputer {
+
+ private static final int THRESHOLD = 20;
+ private static final int RATING_A = 1;
+ private static final int RATING_B = 2;
+
+ @Override
+ public MeasureComputerDefinition define(MeasureComputerDefinitionContext def) {
+ return def.newDefinitionBuilder()
+ .setInputMetrics(FILENAME_SIZE.key())
+ .setOutputMetrics(FILENAME_SIZE_RATING.key())
+ .build();
+ }
+
+ @Override
+ public void compute(MeasureComputerContext context) {
+ Measure size = context.getMeasure(FILENAME_SIZE.key());
+ if (size != null) {
+ // rating values are currently implemented as integers in API
+ int rating = RATING_A;
+ if (size.getIntValue() > THRESHOLD) {
+ rating = RATING_B;
+ }
+ context.addMeasure(FILENAME_SIZE_RATING.key(), rating);
+ }
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/ExampleMetrics.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/ExampleMetrics.java
new file mode 100644
index 00000000..3815347c
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/ExampleMetrics.java
@@ -0,0 +1,30 @@
+package org.sonarsource.plugins.example.measures;
+
+import java.util.List;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.Metrics;
+
+import static java.util.Arrays.asList;
+
+public class ExampleMetrics implements Metrics {
+
+ public static final Metric FILENAME_SIZE = new Metric.Builder("filename_size", "Filename Size", Metric.ValueType.INT)
+ .setDescription("Number of characters of file names")
+ .setDirection(Metric.DIRECTION_BETTER)
+ .setQualitative(false)
+ .setDomain(CoreMetrics.DOMAIN_GENERAL)
+ .create();
+
+ public static final Metric FILENAME_SIZE_RATING = new Metric.Builder("filename_size_rating", "Filename Size Rating", Metric.ValueType.RATING)
+ .setDescription("Rating based on size of file names")
+ .setDirection(Metric.DIRECTION_BETTER)
+ .setQualitative(true)
+ .setDomain(CoreMetrics.DOMAIN_GENERAL)
+ .create();
+
+ @Override
+ public List getMetrics() {
+ return asList(FILENAME_SIZE, FILENAME_SIZE_RATING);
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/SetSizeOnFilesSensor.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/SetSizeOnFilesSensor.java
new file mode 100644
index 00000000..b5f6f030
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/measures/SetSizeOnFilesSensor.java
@@ -0,0 +1,34 @@
+package org.sonarsource.plugins.example.measures;
+
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+
+import static org.sonarsource.plugins.example.measures.ExampleMetrics.FILENAME_SIZE;
+
+/**
+ * Scanner feeds raw measures on files but must not aggregate values to directories and project.
+ * This class emulates loading of file measures from a 3rd-party analyser.
+ */
+public class SetSizeOnFilesSensor implements Sensor {
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor.name("Compute size of file names");
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ FileSystem fs = context.fileSystem();
+ // only "main" files, but not "tests"
+ Iterable files = fs.inputFiles(fs.predicates().hasType(InputFile.Type.MAIN));
+ for (InputFile file : files) {
+ context.newMeasure()
+ .forMetric(FILENAME_SIZE)
+ .on(file)
+ .withValue(file.file().getName().length())
+ .save();
+ }
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/CreateIssuesOnJavaFilesSensor.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/CreateIssuesOnJavaFilesSensor.java
new file mode 100644
index 00000000..86c579ec
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/CreateIssuesOnJavaFilesSensor.java
@@ -0,0 +1,52 @@
+package org.sonarsource.plugins.example.rules;
+
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+import org.sonar.api.batch.sensor.issue.NewIssue;
+import org.sonar.api.batch.sensor.issue.NewIssueLocation;
+
+/**
+ * Generates issues on all java files at line 1. This rule
+ * must be activated in the Quality profile.
+ */
+public class CreateIssuesOnJavaFilesSensor implements Sensor {
+
+ private static final double ARBITRARY_GAP = 2.0;
+ private static final int LINE_1 = 1;
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor.name("Add issues on line 1 of all Java files");
+
+ // optimisation to disable execution of sensor if project does
+ // not contain Java files or if the example rule is not activated
+ // in the Quality profile
+ descriptor.onlyOnLanguage("java");
+ descriptor.createIssuesForRuleRepositories(JavaRulesDefinition.REPOSITORY);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ FileSystem fs = context.fileSystem();
+ Iterable javaFiles = fs.inputFiles(fs.predicates().hasLanguage("java"));
+ for (InputFile javaFile : javaFiles) {
+ // no need to define the severity as it is automatically set according
+ // to the configured Quality profile
+ NewIssue newIssue = context.newIssue()
+ .forRule(JavaRulesDefinition.RULE_ON_LINE_1)
+
+ // gap is used to estimate the remediation cost to fix the debt
+ .gap(ARBITRARY_GAP);
+
+ NewIssueLocation primaryLocation = newIssue.newLocation()
+ .on(javaFile)
+ .at(javaFile.selectLine(LINE_1))
+ .message("You can't do anything. This is first line!");
+ newIssue.at(primaryLocation);
+ newIssue.save();
+ }
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/FooLintIssuesLoaderSensor.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/FooLintIssuesLoaderSensor.java
new file mode 100644
index 00000000..fec7abb2
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/FooLintIssuesLoaderSensor.java
@@ -0,0 +1,198 @@
+package org.sonarsource.plugins.example.rules;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+import javax.xml.stream.XMLStreamException;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.Sensor;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.component.ResourcePerspectives;
+import org.sonar.api.config.Settings;
+import org.sonar.api.issue.Issuable;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.resources.Project;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+
+import static java.lang.String.format;
+
+/**
+ * The goal of this Sensor is to load the results of an analysis performed by a fictive external tool named: FooLint
+ * Results are provided as an xml file and are corresponding to the rules defined in 'rules.xml'.
+ * To be very abstract, these rules are applied on source files made with the fictive language Foo.
+ */
+public class FooLintIssuesLoaderSensor implements Sensor {
+
+ private static final Logger LOGGER = Loggers.get(FooLintIssuesLoaderSensor.class);
+
+ protected static final String REPORT_PATH_KEY = "sonar.foolint.reportPath";
+
+ protected final Settings settings;
+ protected final FileSystem fileSystem;
+ protected final RuleFinder ruleFinder;
+ protected final ResourcePerspectives perspectives;
+
+ /**
+ * Use of IoC to get Settings, FileSystem, RuleFinder and ResourcePerspectives
+ */
+ public FooLintIssuesLoaderSensor(final Settings settings, final FileSystem fileSystem, final RuleFinder ruleFinder, final ResourcePerspectives perspectives) {
+ this.settings = settings;
+ this.fileSystem = fileSystem;
+ this.ruleFinder = ruleFinder;
+ this.perspectives = perspectives;
+ }
+
+ @Override
+ public boolean shouldExecuteOnProject(final Project project) {
+ return !StringUtils.isEmpty(getReportPath());
+ }
+
+ protected String reportPathKey() {
+ return REPORT_PATH_KEY;
+ }
+
+ protected String getReportPath() {
+ String reportPath = settings.getString(reportPathKey());
+ if (!StringUtils.isEmpty(reportPath)) {
+ return reportPath;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void analyse(final Project project, final SensorContext context) {
+ String reportPath = getReportPath();
+ File analysisResultsFile = new File(reportPath);
+ try {
+ parseAndSaveResults(analysisResultsFile);
+
+ } catch (XMLStreamException e) {
+ throw new IllegalStateException("Unable to parse the provided FooLint file", e);
+ }
+ }
+
+ protected void parseAndSaveResults(final File file) throws XMLStreamException {
+ LOGGER.info("(mock) Parsing 'FooLint' Analysis Results");
+ FooLintAnalysisResultsParser parser = new FooLintAnalysisResultsParser();
+ List errors = parser.parse(file);
+ for (FooLintError error : errors) {
+ getResourceAndSaveIssue(error);
+ }
+ }
+
+ private void getResourceAndSaveIssue(FooLintError error) {
+ LOGGER.debug(error.toString());
+
+ InputFile inputFile = fileSystem.inputFile(
+ fileSystem.predicates().and(
+ fileSystem.predicates().hasRelativePath(error.getFilePath()),
+ fileSystem.predicates().hasType(InputFile.Type.MAIN)));
+
+ LOGGER.debug("inputFile null ? " + (inputFile == null));
+
+ if (inputFile != null) {
+ saveIssue(inputFile, error.getLine(), error.getType(), error.getDescription());
+ } else {
+ LOGGER.error("Not able to find a InputFile with " + error.getFilePath());
+ }
+ }
+
+ private boolean saveIssue(InputFile inputFile, int line, String externalRuleKey, String message) {
+ RuleKey rule = RuleKey.of(FooLintRulesDefinition.getRepositoryKeyForLanguage(inputFile.language()), externalRuleKey);
+
+ Issuable issuable = perspectives.as(Issuable.class, inputFile);
+ boolean result = false;
+ if (issuable != null) {
+ LOGGER.debug("Issuable is not null: %s", issuable.toString());
+ Issuable.IssueBuilder issueBuilder = issuable.newIssueBuilder()
+ .ruleKey(rule)
+ .message(message);
+ if (line > 0) {
+ LOGGER.debug("line is > 0");
+ issueBuilder = issueBuilder.line(line);
+ }
+ Issue issue = issueBuilder.build();
+ LOGGER.debug("issue == null? " + (issue == null));
+ try {
+ result = issuable.addIssue(issue);
+ LOGGER.debug("after addIssue: result={}", result);
+ } catch (org.sonar.api.utils.MessageException me) {
+ LOGGER.error(format("Can't add issue on file %s at line %d.", inputFile.absolutePath(), line), me);
+ }
+
+ } else {
+ LOGGER.debug("Can't find an Issuable corresponding to InputFile:" + inputFile.absolutePath());
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "FooLintIssuesLoaderSensor";
+ }
+
+ private class FooLintError {
+
+ private final String type;
+ private final String description;
+ private final String filePath;
+ private final int line;
+
+ public FooLintError(final String type, final String description, final String filePath, final int line) {
+ this.type = type;
+ this.description = description;
+ this.filePath = filePath;
+ this.line = line;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getFilePath() {
+ return filePath;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append(type);
+ s.append("|");
+ s.append(description);
+ s.append("|");
+ s.append(filePath);
+ s.append("(");
+ s.append(line);
+ s.append(")");
+ return s.toString();
+ }
+ }
+
+ private class FooLintAnalysisResultsParser {
+
+ public List parse(final File file) throws XMLStreamException {
+ LOGGER.info("Parsing file {}", file.getAbsolutePath());
+
+ // as the goal of this example is not to demonstrate how to parse an xml file we return an hard coded list of FooError
+
+ FooLintError fooError1 = new FooLintError("ExampleRule1", "More precise description of the error", "src/MyClass.foo", 5);
+ FooLintError fooError2 = new FooLintError("ExampleRule2", "More precise description of the error", "src/MyClass.foo", 9);
+
+ return Arrays.asList(fooError1, fooError2);
+ }
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/FooLintRulesDefinition.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/FooLintRulesDefinition.java
new file mode 100644
index 00000000..a6f39279
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/FooLintRulesDefinition.java
@@ -0,0 +1,45 @@
+package org.sonarsource.plugins.example.rules;
+
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
+import org.sonarsource.plugins.example.languages.FooLanguage;
+
+public final class FooLintRulesDefinition implements RulesDefinition {
+
+ protected static final String KEY = "foolint";
+ protected static final String NAME = "FooLint";
+
+ protected String rulesDefinitionFilePath() {
+ return "/example/foolint-rules.xml";
+ }
+
+ private void defineRulesForLanguage(Context context, String repositoryKey, String repositoryName, String languageKey) {
+ NewRepository repository = context.createRepository(repositoryKey, languageKey).setName(repositoryName);
+
+ InputStream rulesXml = this.getClass().getResourceAsStream(rulesDefinitionFilePath());
+ if (rulesXml != null) {
+ RulesDefinitionXmlLoader rulesLoader = new RulesDefinitionXmlLoader();
+ rulesLoader.load(repository, rulesXml, StandardCharsets.UTF_8.name());
+ }
+
+ repository.done();
+ }
+
+ @Override
+ public void define(Context context) {
+ String repositoryKey = FooLintRulesDefinition.getRepositoryKeyForLanguage(FooLanguage.KEY);
+ String repositoryName = FooLintRulesDefinition.getRepositoryNameForLanguage(FooLanguage.KEY);
+ defineRulesForLanguage(context, repositoryKey, repositoryName, FooLanguage.KEY);
+ }
+
+ public static String getRepositoryKeyForLanguage(String languageKey) {
+ return languageKey.toLowerCase() + "-" + KEY;
+ }
+
+ public static String getRepositoryNameForLanguage(String languageKey) {
+ return languageKey.toUpperCase() + " " + NAME;
+ }
+
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/JavaRulesDefinition.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/JavaRulesDefinition.java
new file mode 100644
index 00000000..952968a9
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/rules/JavaRulesDefinition.java
@@ -0,0 +1,36 @@
+package org.sonarsource.plugins.example.rules;
+
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.rule.RulesDefinition;
+
+public class JavaRulesDefinition implements RulesDefinition {
+
+ public static final String REPOSITORY = "java-example";
+ public static final String JAVA_LANGUAGE = "java";
+ public static final RuleKey RULE_ON_LINE_1 = RuleKey.of(REPOSITORY, "line1");
+
+ @Override
+ public void define(Context context) {
+ NewRepository repository = context.createRepository(REPOSITORY, JAVA_LANGUAGE).setName("My Custom Java Analyzer");
+
+ NewRule x1Rule = repository.createRule(RULE_ON_LINE_1.rule())
+ .setName("Stupid rule")
+ .setHtmlDescription("Generates an issue on every line 1 of Java files")
+
+ // optional tags
+ .setTags("style", "stupid")
+
+ // optional status. Default value is READY.
+ .setStatus(RuleStatus.BETA)
+
+ // default severity when the rule is activated on a Quality profile. Default value is MAJOR.
+ .setSeverity(Severity.MINOR);
+
+ x1Rule.setDebtRemediationFunction(x1Rule.debtRemediationFunctions().linearWithOffset("1h", "30min"));
+
+ // don't forget to call done() to finalize the definition
+ repository.done();
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/settings/ExampleProperties.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/settings/ExampleProperties.java
new file mode 100644
index 00000000..0bc6ed09
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/settings/ExampleProperties.java
@@ -0,0 +1,27 @@
+package org.sonarsource.plugins.example.settings;
+
+import java.util.List;
+import org.sonar.api.config.PropertyDefinition;
+
+import static java.util.Arrays.asList;
+
+public class ExampleProperties {
+
+ public static final String HELLO_KEY = "sonar.example.hello";
+ public static final String CATEGORY = "Example";
+
+ private ExampleProperties() {
+ // only statics
+ }
+
+ public static List definitions() {
+ return asList(
+ PropertyDefinition.builder(HELLO_KEY)
+ .name("Hello")
+ .description("Say Hello")
+ .defaultValue(String.valueOf(false))
+ .category(CATEGORY)
+ .build()
+ );
+ }
+}
diff --git a/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/settings/SayHelloFromScanner.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/settings/SayHelloFromScanner.java
new file mode 100644
index 00000000..a05046dc
--- /dev/null
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/settings/SayHelloFromScanner.java
@@ -0,0 +1,21 @@
+package org.sonarsource.plugins.example.settings;
+
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+import org.sonar.api.utils.log.Loggers;
+
+public class SayHelloFromScanner implements Sensor {
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor.name(getClass().getName());
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ if (context.settings().getBoolean(ExampleProperties.HELLO_KEY)) {
+ // print log only if property is set to true
+ Loggers.get(getClass()).info("Hello world!");
+ }
+ }
+}
diff --git a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ui/ExampleFooter.java b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/web/ExampleFooter.java
similarity index 76%
rename from plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ui/ExampleFooter.java
rename to plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/web/ExampleFooter.java
index 1ee91b64..7083e5ea 100644
--- a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ui/ExampleFooter.java
+++ b/plugins/sonar-example-plugin/src/main/java/org/sonarsource/plugins/example/web/ExampleFooter.java
@@ -1,8 +1,10 @@
-package com.mycompany.sonar.reference.ui;
+package org.sonarsource.plugins.example.web;
import org.sonar.api.web.Footer;
public final class ExampleFooter implements Footer {
+
+ @Override
public String getHtml() {
return "
-
-
-
-
\ No newline at end of file
diff --git a/plugins/sonar-gwt-plugin/src/main/resources/com/mycompany/sonar/gwt/viewer/SampleViewer.gwt.xml b/plugins/sonar-gwt-plugin/src/main/resources/com/mycompany/sonar/gwt/viewer/SampleViewer.gwt.xml
deleted file mode 100644
index af900e8d..00000000
--- a/plugins/sonar-gwt-plugin/src/main/resources/com/mycompany/sonar/gwt/viewer/SampleViewer.gwt.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/plugins/sonar-pmd-extension-plugin/pom.xml b/plugins/sonar-pmd-extension-plugin/pom.xml
deleted file mode 100644
index ddedc330..00000000
--- a/plugins/sonar-pmd-extension-plugin/pom.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
- 4.0.0
- org.codehaus.sonar.examples
- sonar-pmd-extension-plugin
- sonar-plugin
- 0.1-SNAPSHOT
- Sonar Examples :: PMD Extension Plugin
-
-
-
- org.codehaus.sonar
- sonar-plugin-api
- 2.10
- provided
-
-
- pmd
- pmd
- 4.2.5
- provided
-
-
-
-
-
-
- org.codehaus.sonar
- sonar-packaging-maven-plugin
- 1.1
- true
-
- org.sonar.examples.pmd.PmdExtensionPlugin
-
-
- pmd
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 2.3.2
-
- 1.5
- 1.5
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/sonar-pmd-extension-plugin/src/main/java/org/sonar/examples/pmd/MaximumMethodsCountCheck.java b/plugins/sonar-pmd-extension-plugin/src/main/java/org/sonar/examples/pmd/MaximumMethodsCountCheck.java
deleted file mode 100644
index 5f0bc10a..00000000
--- a/plugins/sonar-pmd-extension-plugin/src/main/java/org/sonar/examples/pmd/MaximumMethodsCountCheck.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.sonar.examples.pmd;
-
-import net.sourceforge.pmd.AbstractRule;
-import net.sourceforge.pmd.ast.ASTClassOrInterfaceBody;
-import net.sourceforge.pmd.ast.ASTMethodDeclaration;
-import net.sourceforge.pmd.properties.IntegerProperty;
-
-import java.util.List;
-
-public class MaximumMethodsCountCheck extends AbstractRule {
-
- private static final IntegerProperty propertyDescriptor = new IntegerProperty(
- "maxAuthorisedMethodsCount", "Maximum number of methods authorised", 2, 1.0f);
-
- public Object visit(ASTClassOrInterfaceBody node, Object data) {
- List methods = node.findChildrenOfType(ASTMethodDeclaration.class);
- if (methods.size() > getIntProperty(propertyDescriptor)) {
- addViolation(data, node);
- }
- return super.visit(node, data);
- }
-
-}
diff --git a/plugins/sonar-pmd-extension-plugin/src/main/java/org/sonar/examples/pmd/PmdExtensionPlugin.java b/plugins/sonar-pmd-extension-plugin/src/main/java/org/sonar/examples/pmd/PmdExtensionPlugin.java
deleted file mode 100644
index 4af72c5f..00000000
--- a/plugins/sonar-pmd-extension-plugin/src/main/java/org/sonar/examples/pmd/PmdExtensionPlugin.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.sonar.examples.pmd;
-
-import org.sonar.api.SonarPlugin;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class PmdExtensionPlugin extends SonarPlugin {
-
- public List getExtensions() {
- return Arrays.asList(PmdExtensionRepository.class);
- }
-
-}
diff --git a/plugins/sonar-pmd-extension-plugin/src/main/java/org/sonar/examples/pmd/PmdExtensionRepository.java b/plugins/sonar-pmd-extension-plugin/src/main/java/org/sonar/examples/pmd/PmdExtensionRepository.java
deleted file mode 100644
index 47fc9a65..00000000
--- a/plugins/sonar-pmd-extension-plugin/src/main/java/org/sonar/examples/pmd/PmdExtensionRepository.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.sonar.examples.pmd;
-
-import org.apache.commons.io.IOUtils;
-import org.sonar.api.resources.Java;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleRepository;
-import org.sonar.api.rules.XMLRuleParser;
-
-import java.io.InputStream;
-import java.util.List;
-
-public class PmdExtensionRepository extends RuleRepository {
-
- // Must be the same than the PMD plugin
- private static final String REPOSITORY_KEY = "pmd";
- private XMLRuleParser ruleParser;
-
- public PmdExtensionRepository(XMLRuleParser ruleParser) {
- super(REPOSITORY_KEY, Java.KEY);
- this.ruleParser = ruleParser;
- }
-
- @Override
- public List createRules() {
- // In this example, new rules are declared in a XML file
- InputStream input = getClass().getResourceAsStream("/org/sonar/examples/pmd/extensions.xml");
- try {
- return ruleParser.parse(input);
-
- } finally {
- IOUtils.closeQuietly(input);
- }
- }
-
-}
diff --git a/plugins/sonar-pmd-extension-plugin/src/main/resources/org/sonar/examples/pmd/extensions.xml b/plugins/sonar-pmd-extension-plugin/src/main/resources/org/sonar/examples/pmd/extensions.xml
deleted file mode 100644
index 808974b0..00000000
--- a/plugins/sonar-pmd-extension-plugin/src/main/resources/org/sonar/examples/pmd/extensions.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
- MaximumMethodsCountCheck
- Maximum Methods Count Check
- Maximum number of methods authorised
-
-
- com/mycompany/sonar/pmd/rulesets.xml/MaximumMethodsCountCheck
-
-
-
-
-
-
-
- maxAuthorisedMethodsCount
- Maximum number of methods authorised
-
-
- 2
-
-
-
-
-
-
- AvoidIfWithoutBrace
- Avoid if without using brace
- com/mycompany/sonar/pmd/rulesets.xml/AvoidIfWithoutBrace
- CRITICAL
-
-
-
-
-
- PreventUseOfEmptyClass
- MAJOR
-
-
- MINOR
-
- xpath
-
- //VariableDeclarator[../Type/ReferenceType/ClassOrInterfaceType[@Image='EmptyClass']]
-
-
- message
-
- Prevent use of EmptyClass class
-
-
-
\ No newline at end of file
diff --git a/plugins/sonar-pmd-extension-plugin/src/main/resources/org/sonar/examples/pmd/rulesets.xml b/plugins/sonar-pmd-extension-plugin/src/main/resources/org/sonar/examples/pmd/rulesets.xml
deleted file mode 100644
index 6922cd62..00000000
--- a/plugins/sonar-pmd-extension-plugin/src/main/resources/org/sonar/examples/pmd/rulesets.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
- Avoid too many methods
-
- 3
-
-
-
-
-
-
-
-
-
-
- Avoid if without using brace
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ExampleMetrics.java b/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ExampleMetrics.java
deleted file mode 100644
index c6f19d38..00000000
--- a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ExampleMetrics.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.mycompany.sonar.reference;
-
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.Metrics;
-
-import java.util.Arrays;
-import java.util.List;
-
-public final class ExampleMetrics implements Metrics {
-
- public static final Metric MESSAGE = new Metric.Builder("message_key", "Message", Metric.ValueType.STRING)
- .setDescription("This is a metric to store a well known message")
- .setDirection(Metric.DIRECTION_WORST)
- .setQualitative(false)
- .setDomain(CoreMetrics.DOMAIN_GENERAL)
- .create();
-
- public static final Metric RANDOM = new Metric.Builder("random", "Random", Metric.ValueType.FLOAT)
- .setDescription("Random value")
- .setDirection(Metric.DIRECTION_BETTER)
- .setQualitative(false)
- .setDomain(CoreMetrics.DOMAIN_GENERAL)
- .create();
-
- // getMetrics() method is defined in the Metrics interface and is used by
- // Sonar to retrieve the list of new metrics
- public List getMetrics() {
- return Arrays.asList(MESSAGE, RANDOM);
- }
-}
diff --git a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ExamplePlugin.java b/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ExamplePlugin.java
deleted file mode 100644
index 7f2792e3..00000000
--- a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ExamplePlugin.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.mycompany.sonar.reference;
-
-import com.mycompany.sonar.reference.batch.RandomDecorator;
-import com.mycompany.sonar.reference.batch.ExampleSensor;
-import com.mycompany.sonar.reference.ui.ExampleFooter;
-import com.mycompany.sonar.reference.ui.ExampleRubyWidget;
-import org.sonar.api.Properties;
-import org.sonar.api.Property;
-import org.sonar.api.SonarPlugin;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * This class is the entry point for all extensions
- */
-@Properties({
- @Property(
- key = ExamplePlugin.MY_PROPERTY,
- name = "Plugin Property",
- description = "A property for the plugin")})
-public final class ExamplePlugin extends SonarPlugin {
-
- public static final String MY_PROPERTY = "sonar.example.myproperty";
-
- // This is where you're going to declare all your Sonar extensions
- public List getExtensions() {
- return Arrays.asList(
- // Definitions
- ExampleMetrics.class,
-
- // Batch
- ExampleSensor.class, RandomDecorator.class,
-
- // UI
- ExampleFooter.class, ExampleRubyWidget.class);
- }
-}
\ No newline at end of file
diff --git a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/batch/ExampleSensor.java b/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/batch/ExampleSensor.java
deleted file mode 100644
index a8a2ec08..00000000
--- a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/batch/ExampleSensor.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.mycompany.sonar.reference.batch;
-
-import com.mycompany.sonar.reference.ExampleMetrics;
-import org.sonar.api.batch.Sensor;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Project;
-
-public class ExampleSensor implements Sensor {
-
- public boolean shouldExecuteOnProject(Project project) {
- // This sensor is executed on any type of projects
- return true;
- }
-
- public void analyse(Project project, SensorContext sensorContext) {
- Measure measure = new Measure(ExampleMetrics.MESSAGE, "Hello World!");
- sensorContext.saveMeasure(measure);
- }
-}
diff --git a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/batch/RandomDecorator.java b/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/batch/RandomDecorator.java
deleted file mode 100644
index 558e6412..00000000
--- a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/batch/RandomDecorator.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.mycompany.sonar.reference.batch;
-
-import com.mycompany.sonar.reference.ExampleMetrics;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.math.RandomUtils;
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.Scopes;
-
-public class RandomDecorator implements Decorator {
-
- public boolean shouldExecuteOnProject(Project project) {
- // Execute only on Java projects
- return StringUtils.equals(project.getLanguageKey(), Java.KEY);
- }
-
- public void decorate(Resource resource, DecoratorContext context) {
- // This method is executed on the whole tree of resources.
- // Bottom-up navigation : Java methods -> Java classes -> files -> packages -> modules -> project
- if (Scopes.isBlockUnit(resource)) {
- // Sonar API includes many libraries like commons-lang and google-collections
- double value = RandomUtils.nextDouble();
-
- // Add a measure to the current Java method
- context.saveMeasure(ExampleMetrics.RANDOM, value);
-
- } else {
- // we sum random values on resources different than method
- context.saveMeasure(ExampleMetrics.RANDOM, MeasureUtils.sum(true, context.getChildrenMeasures(ExampleMetrics.RANDOM)));
- }
- }
-}
diff --git a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ui/ExampleRubyWidget.java b/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ui/ExampleRubyWidget.java
deleted file mode 100644
index c53144ab..00000000
--- a/plugins/sonar-reference-plugin/src/main/java/com/mycompany/sonar/reference/ui/ExampleRubyWidget.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.mycompany.sonar.reference.ui;
-
-import org.sonar.api.web.*;
-
-@UserRole(UserRole.USER)
-@Description("Show how to use Ruby Widget API")
-@WidgetCategory("Sample")
-@WidgetProperties({
- @WidgetProperty(key = "param1",
- description = "This is a mandatory parameter",
- optional = false
- ),
- @WidgetProperty(key = "max",
- description = "max threshold",
- type = WidgetPropertyType.INTEGER,
- defaultValue = "80"
- ),
- @WidgetProperty(key = "param2",
- description = "This is an optional parameter"
- ),
- @WidgetProperty(key = "floatprop",
- description = "test description"
- )
-})
-public class ExampleRubyWidget extends AbstractRubyTemplate implements RubyRailsWidget {
-
- public String getId() {
- return "sample";
- }
-
- public String getTitle() {
- return "Sample";
- }
-
- @Override
- protected String getTemplatePath() {
- return "/example/example_widget.html.erb";
- }
-}
\ No newline at end of file
diff --git a/plugins/sonar-reference-plugin/src/main/resources/org/sonar/l10n/reference_fr.properties b/plugins/sonar-reference-plugin/src/main/resources/org/sonar/l10n/reference_fr.properties
deleted file mode 100644
index e38a7808..00000000
--- a/plugins/sonar-reference-plugin/src/main/resources/org/sonar/l10n/reference_fr.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-example.help=Aide
-example.jdbc_login=Compte JDBC
-example.plugin_property=Ma propriété
-example.eastwood_image=Image générée par JFreeChart Eastwood
-example.widget_properties=Propriétés de ce widget
\ No newline at end of file
diff --git a/plugins/tutorial/java-custom-rules-template/.gitignore b/plugins/tutorial/java-custom-rules-template/.gitignore
new file mode 100644
index 00000000..3c6daa09
--- /dev/null
+++ b/plugins/tutorial/java-custom-rules-template/.gitignore
@@ -0,0 +1,31 @@
+# ---- Maven
+target/
+dependency-reduced-pom.xml
+
+# ---- IntelliJ IDEA
+*.iws
+*.iml
+*.ipr
+.idea/
+
+# ---- Eclipse
+.classpath
+.project
+.settings
+
+# ---- Mac OS X
+.DS_Store?
+Icon?
+# Thumbnails
+._*
+# Files that might appear on external disk
+.Spotlight-V100
+.Trashes
+
+# ---- Windows
+# Windows image file caches
+Thumbs.db
+# Folder config file
+Desktop.ini
+
+.java-version
diff --git a/plugins/tutorial/java-custom-rules-template/completed/1_MyFirstCustomCheck.zip b/plugins/tutorial/java-custom-rules-template/completed/1_MyFirstCustomCheck.zip
new file mode 100644
index 00000000..17fa3814
Binary files /dev/null and b/plugins/tutorial/java-custom-rules-template/completed/1_MyFirstCustomCheck.zip differ
diff --git a/plugins/tutorial/java-custom-rules-template/pom.xml b/plugins/tutorial/java-custom-rules-template/pom.xml
new file mode 100644
index 00000000..1491e0f5
--- /dev/null
+++ b/plugins/tutorial/java-custom-rules-template/pom.xml
@@ -0,0 +1,136 @@
+
+
+ 4.0.0
+
+ org.sonar.samples
+ java-custom-rules-template
+ 1.0-SNAPSHOT
+ sonar-plugin
+
+
+ 5.1
+ 7.15.0.30507
+
+
+ Java Custom Rules - Template
+ Empty template for custom rules
+
+
+
+ org.codehaus.sonar
+ sonar-plugin-api
+ ${sonar.plugin.api.version}
+ provided
+
+
+
+ org.sonarsource.java
+ sonar-java-plugin
+ sonar-plugin
+ ${java.plugin.version}
+ provided
+
+
+
+ org.sonarsource.java
+ java-frontend
+ ${java.plugin.version}
+
+
+
+ org.sonarsource.sslr-squid-bridge
+ sslr-squid-bridge
+ 2.7.0.377
+
+
+ org.codehaus.sonar.sslr
+ sslr-core
+
+
+
+
+
+ org.sonarsource.java
+ java-checks-testkit
+ ${java.plugin.version}
+ test
+
+
+
+ org.codehaus.sonar.sslr
+ sslr-testing-harness
+ 1.19.2
+ test
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ org.easytesting
+ fest-assert
+ 1.4
+ test
+
+
+ ch.qos.logback
+ logback-classic
+ 0.9.30
+ test
+
+
+
+
+
+
+ org.sonarsource.sonar-packaging-maven-plugin
+ sonar-packaging-maven-plugin
+ 1.15
+ true
+
+ org.sonar.template.java.JavaCustomRulesPlugin
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ 1.7
+ 1.7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesCheckRegistrar.java b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesCheckRegistrar.java
new file mode 100644
index 00000000..8c5d018a
--- /dev/null
+++ b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesCheckRegistrar.java
@@ -0,0 +1,21 @@
+package org.sonar.template.java;
+
+import org.sonar.plugins.java.api.CheckRegistrar;
+
+/**
+ * Provide the "checks" (implementations of rules) classes that are going to be executed during
+ * source code analysis.
+ *
+ * This class is a batch extension by implementing the {@link org.sonar.plugins.java.api.CheckRegistrar} interface.
+ */
+public class JavaCustomRulesCheckRegistrar implements CheckRegistrar {
+
+ /**
+ * Register the classes that will be used to instantiate checks during analysis.
+ */
+ @Override
+ public void register(RegistrarContext registrarContext) {
+ // Call to registerClassesForRepository to associate the classes with the correct repository key
+ registrarContext.registerClassesForRepository(JavaCustomRulesDefinition.REPOSITORY_KEY, JavaCustomRulesList.getJavaChecks(), JavaCustomRulesList.getJavaTestChecks());
+ }
+}
diff --git a/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesDefinition.java b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesDefinition.java
new file mode 100644
index 00000000..da18ff78
--- /dev/null
+++ b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesDefinition.java
@@ -0,0 +1,29 @@
+package org.sonar.template.java;
+
+import com.google.common.collect.Iterables;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader;
+import org.sonar.plugins.java.Java;
+
+import java.util.List;
+
+/**
+ * Declare rule metadata in server repository of rules.
+ * That allows to list the rules in the page "Rules".
+ */
+public class JavaCustomRulesDefinition implements RulesDefinition {
+
+ public static final String REPOSITORY_KEY = "java-custom-rules-template";
+
+ @Override
+ public void define(Context context) {
+ NewRepository repository = context.createRepository(REPOSITORY_KEY, Java.KEY);
+ repository.setName("Java Custom Rules - Template");
+
+ List checks = JavaCustomRulesList.getChecks();
+ new RulesDefinitionAnnotationLoader().load(repository, Iterables.toArray(checks, Class.class));
+ repository.done();
+ }
+
+}
diff --git a/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesList.java b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesList.java
new file mode 100644
index 00000000..2dce6547
--- /dev/null
+++ b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesList.java
@@ -0,0 +1,29 @@
+package org.sonar.template.java;
+
+import com.google.common.collect.ImmutableList;
+
+import org.sonar.plugins.java.api.JavaCheck;
+
+import java.util.List;
+
+public final class JavaCustomRulesList {
+
+ private JavaCustomRulesList() {
+ }
+
+ public static List getChecks() {
+ return ImmutableList.builder().addAll(getJavaChecks()).addAll(getJavaTestChecks()).build();
+ }
+
+ public static List> getJavaChecks() {
+ return ImmutableList.>builder()
+ // add HERE rules targeting source files
+ .build();
+ }
+
+ public static List> getJavaTestChecks() {
+ return ImmutableList.>builder()
+ // add HERE rules targeting test files
+ .build();
+ }
+}
diff --git a/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesPlugin.java b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesPlugin.java
new file mode 100644
index 00000000..ca0d9e5a
--- /dev/null
+++ b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/JavaCustomRulesPlugin.java
@@ -0,0 +1,22 @@
+package org.sonar.template.java;
+
+import org.sonar.api.SonarPlugin;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Entry point of plugin
+ */
+public class JavaCustomRulesPlugin extends SonarPlugin {
+
+ @Override
+ public List getExtensions() {
+ return Arrays.asList(
+ // server extensions -> objects are instantiated during server startup
+ JavaCustomRulesDefinition.class,
+
+ // batch extensions -> objects are instantiated during code analysis
+ JavaCustomRulesCheckRegistrar.class);
+ }
+}
diff --git a/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/checks/package-info.java b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/checks/package-info.java
new file mode 100644
index 00000000..9a01ae4b
--- /dev/null
+++ b/plugins/tutorial/java-custom-rules-template/src/main/java/org/sonar/template/java/checks/package-info.java
@@ -0,0 +1,7 @@
+@ParametersAreNonnullByDefault
+package org.sonar.template.java.checks;
+
+/**
+ * This package contains the custom rules
+ */
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/plugins/tutorial/java-custom-rules-template/src/test/files/testFiles.txt b/plugins/tutorial/java-custom-rules-template/src/test/files/testFiles.txt
new file mode 100644
index 00000000..f3c26f4d
--- /dev/null
+++ b/plugins/tutorial/java-custom-rules-template/src/test/files/testFiles.txt
@@ -0,0 +1 @@
+Place your test files in this folder
\ No newline at end of file
diff --git a/plugins/tutorial/java-custom-rules-template/src/test/java/org/sonar/template/java/JavaCustomRulesDefinitionTest.java b/plugins/tutorial/java-custom-rules-template/src/test/java/org/sonar/template/java/JavaCustomRulesDefinitionTest.java
new file mode 100644
index 00000000..09682cad
--- /dev/null
+++ b/plugins/tutorial/java-custom-rules-template/src/test/java/org/sonar/template/java/JavaCustomRulesDefinitionTest.java
@@ -0,0 +1,22 @@
+package org.sonar.template.java;
+
+import org.junit.Test;
+import org.sonar.api.server.rule.RulesDefinition;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class JavaCustomRulesDefinitionTest {
+
+ @Test
+ public void registration_test() {
+ JavaCustomRulesDefinition definition = new JavaCustomRulesDefinition();
+ RulesDefinition.Context context = new RulesDefinition.Context();
+ definition.define(context);
+ RulesDefinition.Repository repository = context.repository("java-custom-rules-template");
+
+ assertThat(repository.key()).isEqualTo("java-custom-rules-template");
+ assertThat(repository.name()).isEqualTo("Java Custom Rules - Template");
+ assertThat(repository.language()).isEqualTo("java");
+ assertThat(repository.rules()).hasSize(JavaCustomRulesList.getChecks().size());
+ }
+}
diff --git a/projects/README.md b/projects/README.md
deleted file mode 100644
index d79d0756..00000000
--- a/projects/README.md
+++ /dev/null
@@ -1 +0,0 @@
-TO DO
diff --git a/projects/ant-modules/README.md b/projects/ant-modules/README.md
deleted file mode 100644
index fe0dc316..00000000
--- a/projects/ant-modules/README.md
+++ /dev/null
@@ -1 +0,0 @@
-This example demonstrates how to analyse project with [Ant](http://ant.apache.org/).
diff --git a/projects/ant-modules/build.xml b/projects/ant-modules/build.xml
deleted file mode 100644
index 93d5788c..00000000
--- a/projects/ant-modules/build.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
- Root Project
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/projects/c/README.md b/projects/c/README.md
deleted file mode 100644
index be1d05f1..00000000
--- a/projects/c/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-This example demonstrates how to analyse C project with Sonar Runner.
-
-Prerequisites
-=============
-
-* Sonar 2.6 or higher
-* Sonar C Plugin
-* Sonar Runner 1.1 or higher
diff --git a/projects/c/sonar-project.properties b/projects/c/sonar-project.properties
deleted file mode 100644
index c4baba1a..00000000
--- a/projects/c/sonar-project.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-# Required metadata
-sonar.projectKey=my:project
-sonar.projectName=My project
-sonar.projectVersion=1.0
-
-# Description of project (optional)
-sonar.projectDescription=C project inspected with Java Runner
-
-# Comma-separated paths to directories with sources (required)
-sources=src
-
-# Language must be specified, because default language is Java
-sonar.language=c
diff --git a/projects/c/src/hello.c b/projects/c/src/hello.c
deleted file mode 100644
index 97361a65..00000000
--- a/projects/c/src/hello.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include
-#include
-
-int main(void) {
- printf("Hello, world.");
-}
diff --git a/projects/ci-workaround-pom.xml b/projects/ci-workaround-pom.xml
new file mode 100644
index 00000000..8ab54387
--- /dev/null
+++ b/projects/ci-workaround-pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ org.sonarqube.examples
+ ci-workaround
+ 0.1-SNAPSHOT
+
+ CI Workaround
+ Temporary patch to have CI working fine with Orchestrator 3.7
+
+
+ UTF-8
+
+
+
+
+ org.sonarsource.flex
+ sonar-flex-plugin
+ 2.2.1
+
+
+ org.sonarsource.php
+ sonar-php-plugin
+ 2.7
+
+
+ org.sonarsource.javascript
+ sonar-javascript-plugin
+ 2.8
+
+
+
+
diff --git a/projects/gradle-modules/README.md b/projects/gradle-modules/README.md
deleted file mode 100644
index 46a7fd40..00000000
--- a/projects/gradle-modules/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-This example demonstrates how to analyse project with [Gradle](http://www.gradle.org/).
-
-Prerequisites
-=============
-
-* Sonar 2.9 or higher
-* Gradle 1.0-milestone-5 or higher
-
-Execution
-=========
-
-1. Build project and execute all tests:
-
- gradle build
-
-2. Analyse by Sonar:
-
- gradle sonar
-
diff --git a/projects/gradle-modules/build.gradle b/projects/gradle-modules/build.gradle
deleted file mode 100644
index 21a1e006..00000000
--- a/projects/gradle-modules/build.gradle
+++ /dev/null
@@ -1,31 +0,0 @@
-apply plugin: "sonar"
-
-sonar {
- server {
- url = System.getProperty("sonar.host.url") ?: "http://localhost:9000/"
- }
-
- database {
- url = System.getProperty("sonar.jdbc.url") ?: "jdbc:derby://localhost:1527/sonar"
- driverClassName = System.getProperty("sonar.jdbc.driver") ?: "org.apache.derby.jdbc.ClientDriver"
- username = System.getProperty("sonar.jdbc.username") ?: "sonar"
- password = System.getProperty("sonar.jdbc.password") ?: "sonar"
- }
-
- project {
- withProjectProperties { props ->
- props["sonar.core.codeCoveragePlugin"] = "jacoco"
- }
- }
-}
-
-subprojects {
- apply plugin: 'java'
-
- buildDir = "target"
-
- repositories {
- mavenCentral()
- mavenLocal()
- }
-}
diff --git a/projects/gradle/README.md b/projects/gradle/README.md
deleted file mode 100644
index 46a7fd40..00000000
--- a/projects/gradle/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-This example demonstrates how to analyse project with [Gradle](http://www.gradle.org/).
-
-Prerequisites
-=============
-
-* Sonar 2.9 or higher
-* Gradle 1.0-milestone-5 or higher
-
-Execution
-=========
-
-1. Build project and execute all tests:
-
- gradle build
-
-2. Analyse by Sonar:
-
- gradle sonar
-
diff --git a/projects/gradle/build.gradle b/projects/gradle/build.gradle
deleted file mode 100644
index 65072de9..00000000
--- a/projects/gradle/build.gradle
+++ /dev/null
@@ -1,42 +0,0 @@
-apply plugin: "java"
-apply plugin: "sonar"
-
-buildDir = "target"
-
-repositories {
- mavenCentral()
- mavenLocal()
-}
-
-configurations {
- jacoco
-}
-
-dependencies {
- testCompile group: "junit", name: "junit", version: "4.8.1"
-
- jacoco group: "org.jacoco", name: "org.jacoco.agent", version: "0.5.3.201107060350", classifier: "runtime"
-}
-
-test {
- jvmArgs "-javaagent:" + configurations.jacoco.asPath + "=destfile=" + buildDir + "/jacoco.exec,includes=example.*"
-}
-
-sonar {
- server {
- url = System.getProperty("sonar.host.url") ?: "http://localhost:9000/"
- }
-
- database {
- url = System.getProperty("sonar.jdbc.url") ?: "jdbc:derby://localhost:1527/sonar"
- driverClassName = System.getProperty("sonar.jdbc.driver") ?: "org.apache.derby.jdbc.ClientDriver"
- username = System.getProperty("sonar.jdbc.username") ?: "sonar"
- password = System.getProperty("sonar.jdbc.password") ?: "sonar"
- }
-
- project {
- withProjectProperties { props ->
- props["sonar.core.codeCoveragePlugin"] = "jacoco"
- }
- }
-}
diff --git a/projects/java-runner/README.md b/projects/java-runner/README.md
deleted file mode 100644
index 8b764cb1..00000000
--- a/projects/java-runner/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-This example demonstrates how to analyse Java project with Sonar Runner.
-
-Prerequisites
-=============
-
-* Sonar 2.6 or higher
-* Sonar Runner 1.1 or higher
diff --git a/projects/java-runner/build/classes/Helloworld.class b/projects/java-runner/build/classes/Helloworld.class
deleted file mode 100644
index eaab8ecb..00000000
Binary files a/projects/java-runner/build/classes/Helloworld.class and /dev/null differ
diff --git a/projects/java-runner/lib/deprecated.jar b/projects/java-runner/lib/deprecated.jar
deleted file mode 100644
index 65e3be99..00000000
Binary files a/projects/java-runner/lib/deprecated.jar and /dev/null differ
diff --git a/projects/java-runner/sonar-project.properties b/projects/java-runner/sonar-project.properties
deleted file mode 100644
index c996b309..00000000
--- a/projects/java-runner/sonar-project.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-# Required metadata
-sonar.projectKey=java-runner
-sonar.projectName=Java Runner
-sonar.projectVersion=1.0
-
-# Description of project (optional)
-sonar.projectDescription=Java project inspected with Java Runner
-
-# Comma-separated paths to directories with sources (required)
-sources=src
-
-# Comma-separated paths to directories with binaries (optional), in case of Java - directories with class files
-binaries=build/classes
-
-# Comma-separated paths to files with third-party libraries (optional), in case of Java - JAR files
-libraries=lib/deprecated.jar
-
-# Java is the default language, so the following property can be commented
-sonar.language=java
diff --git a/projects/java-runner/src/Helloworld.java b/projects/java-runner/src/Helloworld.java
deleted file mode 100644
index 8fd59684..00000000
--- a/projects/java-runner/src/Helloworld.java
+++ /dev/null
@@ -1,13 +0,0 @@
-public class Helloworld {
-
- private String field;
-
- public void use() {
- new DeprecatedExample().deprecatedMethod();
- System.exit(33); // violation on findbugs rule: DM_EXIT
- }
-
- public void useFieldForLcom4() {
- System.out.println(field);
- }
-}
diff --git a/projects/languages/abap/README.md b/projects/languages/abap/README.md
new file mode 100644
index 00000000..9e42c735
--- /dev/null
+++ b/projects/languages/abap/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze an SAP ABAP project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarSource ABAP Plugin](http://www.sonarsource.com/products/plugins/languages/abap/) 3.2.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/abap/sonar-project.properties b/projects/languages/abap/sonar-project.properties
new file mode 100644
index 00000000..3def2c0a
--- /dev/null
+++ b/projects/languages/abap/sonar-project.properties
@@ -0,0 +1,9 @@
+sonar.projectKey=org.sonarqube:abap-simple-sq-scanner
+sonar.projectName=ABAP :: Simple Project :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.sources=src
+
+sonar.language=abap
+
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/abap/src/ZBCMKZ17.abap b/projects/languages/abap/src/ZBCMKZ17.abap
new file mode 100644
index 00000000..936119df
--- /dev/null
+++ b/projects/languages/abap/src/ZBCMKZ17.abap
@@ -0,0 +1,147 @@
+REPORT ZBCMKZ17.
+*----------------------------------------------------------------------*
+* Description: Report and Transaction Starter *
+* It shows an individual list of reports/Trans. to start*
+* *
+* Authorization: S_PROGRAM, Reports starten *
+* *
+* Class: Utility *
+* *
+* Customizing: Needs Customer Table: ZBCMKZ1 *
+* Field: Key Type Length Descr. *
+* ZBCMKZ1-BNAME X CHAR C 12 User name *
+* ZBCMKZ1-NAME X CHAR C 8 Report/Trans. code *
+* ZBCMKZ1-NUMMER INT1 X 1 Priority level *
+* *
+* R/3 Release: 3.0d *
+* *
+* Programmer: Bence Toth *
+* Date: 1997 April *
+* *
+*----------------------------------------------------------------------*
+INCLUDE: .
+TABLES: ZBCMKZ1, TRDIR, TSTCT, TSTC.
+DATA: BEGIN OF BTAB OCCURS 50, "Hilfstabelle fuer Textpool
+ CODE(82),
+ END OF BTAB.
+DATA: BEGIN OF T OCCURS 100,
+ NUMMER LIKE ZBCMKZ1-NUMMER,
+ NAME LIKE TRDIR-NAME,
+ CODE(82),
+END OF T.
+DATA: FI(20).
+DATA BEGIN OF BDCDATA OCCURS 100.
+ INCLUDE STRUCTURE BDCDATA.
+DATA END OF BDCDATA.
+
+DATA BEGIN OF MESSTAB OCCURS 10.
+ INCLUDE STRUCTURE BDCMSGCOLL.
+DATA END OF MESSTAB.
+
+DATA REPORT.
+AUTHORITY-CHECK OBJECT 'S_PROGRAM'
+ ID 'P_GROUP' FIELD '*'
+ ID 'P_ACTION' FIELD '*'.
+IF SY-SUBRC NE 0. EXIT. ENDIF.
+WRITE: /2 'Er. Modus', 12 'Name', 22 'Text'.
+
+
+DETAIL.
+SKIP.
+SELECT * FROM ZBCMKZ1 WHERE BNAME EQ SY-UNAME.
+ CHECK ZBCMKZ1-NAME+5(1) EQ ' '.
+ SELECT SINGLE * FROM TSTC WHERE TCODE EQ ZBCMKZ1-NAME.
+ CHECK SY-SUBRC EQ 0.
+ CLEAR TSTCT.
+ SELECT SINGLE * FROM TSTCT WHERE SPRSL EQ SY-LANGU AND
+ TCODE EQ ZBCMKZ1-NAME.
+ T-CODE = TSTCT-TTEXT.
+ MOVE-CORRESPONDING ZBCMKZ1 TO T.
+ APPEND T.
+ CLEAR T.
+ENDSELECT.
+SORT T BY NUMMER CODE.
+REPORT = ' '.
+PERFORM LIST USING REPORT.
+SELECT * FROM ZBCMKZ1 WHERE BNAME EQ SY-UNAME.
+ CHECK ZBCMKZ1-NAME+5(1) NE ' '.
+ READ TEXTPOOL ZBCMKZ1-NAME INTO BTAB LANGUAGE SY-LANGU.
+ CHECK SY-SUBRC EQ 0.
+ LOOP AT BTAB.
+ IF BTAB-CODE(1) EQ 'R'.
+ EXIT.
+ ENDIF.
+ ENDLOOP.
+ MOVE BTAB-CODE+9(70) TO T-CODE.
+ MOVE-CORRESPONDING ZBCMKZ1 TO T.
+ APPEND T.
+ CLEAR T.
+ENDSELECT.
+SORT T BY NUMMER CODE.
+REPORT = 'X'.
+PERFORM LIST USING REPORT.
+
+AT LINE-SELECTION.
+ CHECK NOT ( T-NAME IS INITIAL ).
+ GET CURSOR FIELD FI.
+ IF T-NAME+5(1) EQ ' '.
+ REPORT = ' '.
+ ELSE.
+ REPORT = 'X'.
+ ENDIF.
+ IF FI = 'ICON_EXECUTE_OBJECT'.
+ PERFORM PERO USING T-NAME REPORT.
+ ELSEIF REPORT EQ ' '.
+* SELECT SINGLE * FROM TSTC WHERE TCODE EQ ZBCMKZ1-NAME.
+* IF T+5(1) EQ ' '.
+ CALL TRANSACTION T-NAME.
+ ELSE.
+ SUBMIT (T-NAME) VIA SELECTION-SCREEN AND RETURN.
+ ENDIF.
+ CLEAR T-NAME.
+*---------------------------------------------------------------------*
+* FORM LIST *
+*---------------------------------------------------------------------*
+* ........ *
+*---------------------------------------------------------------------*
+FORM LIST USING REPORT.
+ LOOP AT T.
+ IF REPORT = ' '.
+ WRITE: /5 ICON_EXECUTE_OBJECT AS ICON, T-NAME UNDER 'Name',
+ T-CODE UNDER 'Text'.
+ ELSE.
+ WRITE: / T-NAME UNDER 'Name', T-CODE UNDER 'Text'.
+ ENDIF.
+ HIDE T.
+ AT END OF NUMMER.
+ SKIP.
+ ENDAT.
+ ENDLOOP.
+ SKIP.
+ CLEAR T.
+ REFRESH T.
+ENDFORM.
+*---------------------------------------------------------------------*
+* FORM PERO *
+*---------------------------------------------------------------------*
+* ........ *
+*---------------------------------------------------------------------*
+* --> T-NAME *
+*---------------------------------------------------------------------*
+FORM PERO USING T-NAME REPORT.
+ CHECK REPORT EQ ' '.
+ MOVE T-NAME TO T-NAME+2(4).
+ MOVE '/o' TO T-NAME+0(2).
+ BDCDATA-PROGRAM = 'SAPMS01J'.
+ BDCDATA-DYNPRO = '0310'.
+ BDCDATA-DYNBEGIN = 'X'.
+ APPEND BDCDATA.
+ CLEAR BDCDATA.
+ BDCDATA-FNAM = 'BDC_OKCODE'.
+ BDCDATA-FVAL = T-NAME.
+ APPEND BDCDATA.
+ CALL TRANSACTION 'SU50' USING BDCDATA MODE 'N'
+ MESSAGES INTO MESSTAB.
+ CLEAR BDCDATA.
+ REFRESH BDCDATA.
+ENDFORM.
diff --git a/projects/languages/abap/src/ZZBGS106.abap b/projects/languages/abap/src/ZZBGS106.abap
new file mode 100644
index 00000000..cc3e07ca
--- /dev/null
+++ b/projects/languages/abap/src/ZZBGS106.abap
@@ -0,0 +1,194 @@
+REPORT ZZBGS106 MESSAGE-ID Z1.
+*----------------------------------------------------------------------*
+* Description: Utillity used for downloading abap/4 source code and *
+* text elements to the desktop using ws_download. *
+* Is useful as backup or for transporting to another site.*
+* You must run this program in foreground/online due to *
+* the use of ws_download throug the SAPGUI. *
+* *
+* Implementing The program is client independent. *
+* *
+* Authoriza. No Authorization check. *
+* *
+* Submitting: Run by SA38, SE38. *
+* *
+* Parametre: You can use generic values when filling the parameters *
+* except for the Path. *
+* *
+* Customizing: No need for customization. *
+* *
+* Change of You only need to do the syntax check at releasechanges. *
+* release: *
+* *
+* R/3 Release: Developed and tested in R/3 Release: *
+* 2.2F *
+* 3.0D *
+* *
+* Programmer: Benny G. Serensen, BGS-Consulting *
+* Date: Nov 1996. *
+* *
+* Version 1
+*-------------------------------Corrections----------------------------*
+* Date Userid Correction Text *
+* 11.11.1996 BGS :::::::::::::: Start of development *
+*----------------------------------------------------------------------*
+*----------------------------------------------------------------------*
+* Tables *
+*----------------------------------------------------------------------*
+TABLES: TRDIR "Application Masterdata
+ .
+*----------------------------------------------------------------------*
+* Parameters *
+*----------------------------------------------------------------------*
+SELECT-OPTIONS: REPO FOR TRDIR-NAME.
+PARAMETERS: PATH(60) TYPE C DEFAULT 'C:\SAP\'.
+
+*----------------------------------------------------------------------*
+* Work Variables and internal tables *
+*----------------------------------------------------------------------*
+DATA: BEGIN OF TABSOURCE OCCURS 10
+ ,SOURCE(72) TYPE C
+ ,END OF TABSOURCE.
+
+DATA: BEGIN OF TABTEXT OCCURS 50
+ ,TAB LIKE TEXTPOOL
+ ,END OF TABTEXT.
+
+DATA: BEGIN OF TABRDIR OCCURS 100
+ ,RDIR LIKE TRDIR
+ ,END OF TABRDIR.
+
+DATA: FILENAME LIKE RLGRAP-FILENAME
+ ,MODE TYPE C VALUE ' '
+ ,RDIRROWS TYPE I
+ ,SOURCEROWS TYPE I
+ ,RC TYPE I
+ ,LENGTH TYPE I
+ .
+FIELD-SYMBOLS:
.
+
+*----------------------------------------------------------------------*
+* Constants *
+*----------------------------------------------------------------------*
+DATA: OK TYPE I VALUE 0
+ ,FAIL TYPE I VALUE 1.
+
+*----------------------------------------------------------------------*
+* EVENT: validate users entries on the selection screen *
+*----------------------------------------------------------------------*
+AT SELECTION-SCREEN.
+DATA: I TYPE I.
+ DESCRIBE TABLE REPO LINES I.
+ IF I <= 0.
+ SET CURSOR FIELD REPO.
+ MESSAGE E065 WITH TEXT-101.
+ ENDIF.
+
+*----------------------------------------------------------------------*
+* EVENT: Start-Of-Selection *
+*----------------------------------------------------------------------*
+START-OF-SELECTION.
+* Set slash at the end of path if not speciefied by user
+ CONDENSE PATH NO-GAPS.
+ LENGTH = STRLEN( PATH ) .
+ SUBTRACT 1 FROM LENGTH.
+ ASSIGN PATH+LENGTH(1) TO
.
+ IF
<> '\'.
+ ADD 1 TO LENGTH.
+ ASSIGN PATH+LENGTH TO
+
+ altrow
+
+ ✘
+ Test Assembly Cleanup
+ Test Collection Cleanup
+ Test Class Cleanup
+ Test Method Cleanup
+ Test Case Cleanup
+ Test Cleanup
+ Fatal Error
+
+ ()
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/NUnitXml.xslt b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/NUnitXml.xslt
new file mode 100644
index 00000000..228fbedd
--- /dev/null
+++ b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/NUnitXml.xslt
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ True
+
+
+
+ False
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xUnit1.xslt b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xUnit1.xslt
new file mode 100644
index 00000000..a8425d36
--- /dev/null
+++ b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xUnit1.xslt
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.abstractions.dll b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.abstractions.dll
new file mode 100644
index 00000000..f6457097
Binary files /dev/null and b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.abstractions.dll differ
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.exe b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.exe
new file mode 100644
index 00000000..4adb57f5
Binary files /dev/null and b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.exe differ
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.exe.config b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.exe.config
new file mode 100644
index 00000000..6f7877d8
--- /dev/null
+++ b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.exe.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.x86.exe b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.x86.exe
new file mode 100644
index 00000000..0a9881d2
Binary files /dev/null and b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.x86.exe differ
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.x86.exe.config b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.x86.exe.config
new file mode 100644
index 00000000..f68633bd
--- /dev/null
+++ b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.console.x86.exe.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.runner.reporters.desktop.dll b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.runner.reporters.desktop.dll
new file mode 100644
index 00000000..8be2ed3d
Binary files /dev/null and b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.runner.reporters.desktop.dll differ
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.runner.utility.desktop.dll b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.runner.utility.desktop.dll
new file mode 100644
index 00000000..fc88513d
Binary files /dev/null and b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/tools/xunit.runner.utility.desktop.dll differ
diff --git a/projects/languages/csharp/packages/xunit.runner.console.2.1.0/xunit.runner.console.2.1.0.nupkg b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/xunit.runner.console.2.1.0.nupkg
new file mode 100644
index 00000000..29efca19
Binary files /dev/null and b/projects/languages/csharp/packages/xunit.runner.console.2.1.0/xunit.runner.console.2.1.0.nupkg differ
diff --git a/projects/languages/css/css-sonar-runner/README.md b/projects/languages/css/css-sonar-runner/README.md
new file mode 100644
index 00000000..9f33e906
--- /dev/null
+++ b/projects/languages/css/css-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a simple CSS project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube CSS Plugin](https://github.com/SonarCommunity/sonar-css) 1.8+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/css/css-sonar-runner/sonar-project.properties b/projects/languages/css/css-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..de6ebdf8
--- /dev/null
+++ b/projects/languages/css/css-sonar-runner/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:css-simple-sq-scanner
+sonar.projectName=CSS :: Simple Project :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=css
+
+# Encoding of sources files
+sonar.sourceEncoding=US-ASCII
diff --git a/projects/languages/css/css-sonar-runner/src/sample.css b/projects/languages/css/css-sonar-runner/src/sample.css
new file mode 100644
index 00000000..9622216a
--- /dev/null
+++ b/projects/languages/css/css-sonar-runner/src/sample.css
@@ -0,0 +1,89 @@
+.quality-gates-navigator .navigator-side {
+ display: table-cell;
+ vertical-align: top;
+ width: 250px;
+ min-width: 0;
+}
+.quality-gates-navigator .navigator-header {
+ margin-left: 0;
+}
+.quality-gates-navigator .navigator-header .spinner {
+ margin-top: 9px;
+}
+.quality-gates-navigator .navigator-actions {
+ height: 40px;
+ width: 230px;
+ margin: 10px;
+ padding: 0 10px;
+}
+.quality-gates-navigator .navigator-actions .navigator-header-title {
+ color: #444;
+ font-size: 13px;
+ font-weight: 700;
+ text-transform: uppercase;
+}
+.quality-gates-navigator .navigator-results {
+ width: 230px;
+ min-width: 0;
+}
+.quality-gates-navigator .navigator-details {
+ margin-left: 0;
+}
+.quality-gates-nav .navigator-results-list>li {
+ border-color: transparent;
+}
+.quality-gates-nav .navigator-results-list>li:hover:not(.active):not(.empty) {
+ background-color: #f3f3f3;
+}
+.quality-gates-nav .navigator-results-list>li.active {
+ border-color: #4B9FD5;
+}
+.quality-gates-nav .navigator-results-list>li.empty {
+ cursor: default;
+}
+.quality-gates-nav .navigator-results-list>li .line {
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.quality-gates-nav .navigator-results-list>li .subtitle {
+ text-transform: lowercase;
+}
+.quality-gate-section+.quality-gate-section {
+ margin-top: 10px;
+ padding-top: 20px;
+}
+.quality-gate-section-empty+.quality-gate-section {
+ border-top: 1px solid #e6e6e6;
+}
+.quality-gate-section-name {
+ margin-bottom: 10px;
+ font-weight: 700;
+ text-transform: uppercase;
+}
+.quality-gate-introduction {
+ margin-bottom: 20px;
+}
+.quality-gate-new-condition {
+ margin-bottom: 10px;
+}
+.quality-gate-condition-actions {
+ position: relative;
+}
+.quality-gate-default-message {
+ padding: 6px 5px;
+ border: 1px solid #ddd;
+ background-color: #efefef;
+}
+.quality-gate-conditions-wrap {
+ border-left: 1px solid #ddd;
+ border-right: 1px solid #ddd;
+}
+.quality-gate-conditions .deprecated {
+ color: #777;
+ text-transform: lowercase;
+ font-variant: small-caps;
+}
+.quality-gate-conditions tbody {
+ border-left: none!important;
+ border-right: none!important;
+}
\ No newline at end of file
diff --git a/projects/languages/css/css-sonar-runner/src/sonar.css b/projects/languages/css/css-sonar-runner/src/sonar.css
new file mode 100644
index 00000000..0fac7434
--- /dev/null
+++ b/projects/languages/css/css-sonar-runner/src/sonar.css
@@ -0,0 +1,7168 @@
+html {
+ color: #000;
+ background: #fff;
+}
+body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td {
+ margin: 0;
+ padding: 0;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+fieldset, img {
+ border: 0;
+}
+address, caption, cite, code, dfn, em, strong, th, var {
+ font-style: normal;
+ font-weight: 400;
+}
+ol, ul {
+ list-style: none;
+}
+caption, th {
+ text-align: left;
+}
+h1, h2, h3, h4, h5, h6 {
+ font-size: 100%;
+ font-weight: 400;
+}
+q:before, q:after {
+ content: ''}
+abbr, acronym {
+ border: 0;
+ font-variant: normal;
+}
+sup {
+ vertical-align: text-top;
+}
+sub {
+ vertical-align: text-bottom;
+}
+input, textarea, select {
+ font-family: inherit;
+ font-size: inherit;
+ font-weight: inherit;
+}
+input, textarea, select {
+ *font-size: 100%}
+legend {
+ color: #000;
+}
+body {
+ font: 13px/1.231 arial, helvetica, clean, sans-serif;
+ *font-size: small;
+ *font: x-small;
+}
+select, input, button, textarea {
+ font: 99% arial, helvetica, clean, sans-serif;
+}
+table {
+ font-size: inherit;
+ font: 100%}
+pre, code, kbd, samp, tt {
+ font-family: monospace;
+ *font-size: 108%;
+ line-height: 100%}
+/*! jQuery UI - v1.10.3 - 2013-06-18
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.button.css, jquery.ui.dialog.css
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */.no-close .ui-dialog-titlebar-close {
+ display: none;
+}
+.ui-dialog .ui-dialog-titlebar {
+ display: none;
+}
+.ui-widget-header {
+ color: #fff;
+ font-weight: 700;
+}
+.ui-widget-header a {
+ color: #fff;
+}
+.ui-widget-shadow {
+ margin: -5px 0 0 -5px;
+ padding: 5px;
+ background: #000 50% 50% repeat-x;
+ opacity: .2;
+ -moz-border-radius: 5px;
+ -khtml-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+}
+.ui-dialog {
+ position: absolute;
+ width: 300px;
+ overflow: hidden;
+ box-shadow: 10px 10px 20px rgba(0, 0, 0, .5);
+ background-color: #fff;
+}
+.ui-helper-hidden {
+ display: none;
+}
+.ui-helper-hidden-accessible {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+}
+.ui-helper-reset {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ line-height: 1.3;
+ text-decoration: none;
+ font-size: 100%;
+ list-style: none;
+}
+.ui-helper-clearfix:before, .ui-helper-clearfix:after {
+ content: "";
+ display: table;
+ border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+ clear: both;
+}
+.ui-helper-clearfix {
+ min-height: 0;
+}
+.ui-helper-zfix {
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ position: absolute;
+ opacity: 0;
+}
+.ui-front {
+ z-index: 100;
+}
+.ui-state-disabled {
+ cursor: default!important;
+}
+.ui-icon {
+ display: block;
+ text-indent: -99999px;
+ overflow: hidden;
+ background-repeat: no-repeat;
+}
+.ui-widget-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: #000;
+ opacity: .5;
+}
+.ui-resizable {
+ position: relative;
+}
+.ui-resizable-handle {
+ position: absolute;
+ font-size: .1px;
+ display: block;
+}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle {
+ display: none;
+}
+.ui-resizable-n {
+ cursor: n-resize;
+ height: 7px;
+ width: 100%;
+ top: -5px;
+ left: 0;
+}
+.ui-resizable-s {
+ cursor: s-resize;
+ height: 7px;
+ width: 100%;
+ bottom: -5px;
+ left: 0;
+}
+.ui-resizable-e {
+ cursor: e-resize;
+ width: 7px;
+ right: -5px;
+ top: 0;
+ height: 100%}
+.ui-resizable-w {
+ cursor: w-resize;
+ width: 7px;
+ left: -5px;
+ top: 0;
+ height: 100%}
+.ui-resizable-se {
+ cursor: se-resize;
+ width: 12px;
+ height: 12px;
+ right: 1px;
+ bottom: 1px;
+}
+.ui-resizable-sw {
+ cursor: sw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ bottom: -5px;
+}
+.ui-resizable-nw {
+ cursor: nw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ top: -5px;
+}
+.ui-resizable-ne {
+ cursor: ne-resize;
+ width: 9px;
+ height: 9px;
+ right: -5px;
+ top: -5px;
+}
+.ui-button {
+ display: inline-block;
+ position: relative;
+ padding: 0;
+ line-height: normal;
+ margin-right: .1em;
+ cursor: pointer;
+ vertical-align: middle;
+ text-align: center;
+ overflow: visible;
+}
+.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active {
+ text-decoration: none;
+}
+.ui-button-icon-only {
+ width: 2.2em;
+}
+button.ui-button-icon-only {
+ width: 2.4em;
+}
+.ui-button-icons-only {
+ width: 3.4em;
+}
+button.ui-button-icons-only {
+ width: 3.7em;
+}
+.ui-button .ui-button-text {
+ display: block;
+ line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+ padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text {
+ padding: .4em;
+ text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text {
+ padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text {
+ padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+ padding-left: 2.1em;
+ padding-right: 2.1em;
+}
+input.ui-button {
+ padding: .4em 1em;
+}
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon {
+ position: absolute;
+ top: 50%;
+ margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+ left: 50%;
+ margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary {
+ left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary {
+ right: .5em;
+}
+.ui-buttonset {
+ margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+ margin-left: 0;
+ margin-right: -.3em;
+}
+input.ui-button::-moz-focus-inner, button.ui-button::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+.ui-dialog {
+ position: absolute;
+ top: 0;
+ left: 0;
+ outline: 0;
+}
+.ui-dialog .ui-dialog-content {
+ position: relative;
+ border: 0;
+ background: 0 0;
+ overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+ text-align: left;
+ border-width: 1px 0 0;
+ background-image: none;
+ margin-top: .5em;
+ padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+ float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+ margin: .5em .4em .5em 0;
+ cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+ width: 12px;
+ height: 12px;
+ right: -5px;
+ bottom: -5px;
+ background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+ cursor: move;
+}
+.ui-datepicker {
+ width: 17em;
+ padding: 5px 5px 0;
+ display: none;
+ background-color: #fff;
+ border: 1px solid #e1e1e1;
+}
+.ui-datepicker .ui-datepicker-header {
+ position: relative;
+ padding: .2em 0;
+ color: #444;
+}
+.ui-datepicker .ui-widget-header a {
+ color: #444;
+}
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next {
+ position: absolute;
+ top: 7px;
+}
+.ui-datepicker .ui-datepicker-prev {
+ left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+ right: 2px;
+}
+.ui-datepicker .ui-datepicker-title {
+ margin: 0 48px;
+ line-height: 1.8em;
+ color: #444;
+ text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+ font-size: 1em;
+ margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year {
+ width: 49%}
+.ui-datepicker table {
+ width: 100%;
+ font-size: .9em;
+ border-collapse: collapse;
+ margin: 0 0 .4em;
+}
+.ui-datepicker th {
+ padding: .7em .3em;
+ text-align: center;
+ font-weight: 700;
+ border: 0;
+}
+.ui-datepicker td {
+ border: 0;
+ padding: 1px;
+}
+.ui-datepicker td span, .ui-datepicker td a {
+ display: block;
+ padding: .2em;
+ text-align: right;
+ text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+ background-image: none;
+ margin: .7em 0 0;
+ padding: 0 .2em;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+ float: right;
+ margin: .5em .2em .4em;
+ cursor: pointer;
+ padding: .2em .6em .3em;
+ width: auto;
+ overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+ float: left;
+}
+.ui-datepicker-today {
+ background-color: #eee1f8;
+}
+.ui-datepicker-current-day {
+ background-color: #4b9fd5;
+}
+.ui-datepicker-current-day a {
+ color: #fff;
+}
+.ui-datepicker.ui-datepicker-multi {
+ width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+ float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+ width: 95%;
+ margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+ width: 50%}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+ width: 33.3%}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+ width: 25%}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+ border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+ clear: left;
+}
+.ui-datepicker-row-break {
+ clear: both;
+ width: 100%;
+ font-size: 0;
+}
+.ui-datepicker .ui-icon {
+ text-indent: 0;
+}
+.ui-datepicker-rtl {
+ direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+ right: 2px;
+ left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+ left: 2px;
+ right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+ right: 1px;
+ left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+ left: 1px;
+ right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+ clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+ float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, .ui-datepicker-rtl .ui-datepicker-group {
+ float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+ border-right-width: 0;
+ border-left-width: 1px;
+}
+.select2-container {
+ position: relative;
+ display: inline-block;
+ zoom: 1;
+ *display: inline;
+ vertical-align: top;
+}
+.select2-container, .select2-drop, .select2-search, .select2-search input {
+ -moz-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -khtml-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.select2-container .select2-choice {
+ background-color: #fff;
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff));
+ background-image: -webkit-linear-gradient(center bottom, #eee 0, #fff 50%);
+ background-image: -moz-linear-gradient(center bottom, #eee 0, #fff 50%);
+ background-image: -o-linear-gradient(bottom, #eee 0, #fff 50%);
+ background-image: -ms-linear-gradient(top, #eee 0, #fff 50%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
+ background-image: linear-gradient(top, #eee 0, #fff 50%);
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -moz-background-clip: padding;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #aaa;
+ display: block;
+ overflow: hidden;
+ white-space: nowrap;
+ position: relative;
+ height: 26px;
+ line-height: 26px;
+ padding: 0 0 0 8px;
+ color: #444;
+ text-decoration: none;
+}
+.select2-container.select2-drop-above .select2-choice {
+ border-bottom-color: #aaa;
+ -webkit-border-radius: 0 0 4px 4px;
+ -moz-border-radius: 0 0 4px 4px;
+ border-radius: 0 0 4px 4px;
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff));
+ background-image: -webkit-linear-gradient(center bottom, #eee 0, #fff 90%);
+ background-image: -moz-linear-gradient(center bottom, #eee 0, #fff 90%);
+ background-image: -o-linear-gradient(bottom, #eee 0, #fff 90%);
+ background-image: -ms-linear-gradient(top, #eee 0, #fff 90%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
+ background-image: linear-gradient(top, #eee 0, #fff 90%);
+}
+.select2-container .select2-choice span {
+ margin-right: 26px;
+ display: block;
+ overflow: hidden;
+ white-space: nowrap;
+ -o-text-overflow: ellipsis;
+ -ms-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+}
+.select2-container .select2-choice abbr {
+ display: block;
+ position: absolute;
+ right: 26px;
+ top: 8px;
+ width: 12px;
+ height: 12px;
+ font-size: 1px;
+ background: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") right top no-repeat;
+ cursor: pointer;
+ text-decoration: none;
+ border: 0;
+ outline: 0;
+}
+.select2-container .select2-choice abbr:hover {
+ background-position: right -11px;
+ cursor: pointer;
+}
+.select2-drop {
+ background: #fff;
+ color: #000;
+ border: 1px solid #aaa;
+ border-top: 0;
+ position: absolute;
+ top: 100%;
+ -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
+ -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
+ -o-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
+ box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
+ z-index: 9999;
+ width: 100%;
+ margin-top: -1px;
+ -webkit-border-radius: 0 0 4px 4px;
+ -moz-border-radius: 0 0 4px 4px;
+ border-radius: 0 0 4px 4px;
+}
+.select2-drop.select2-drop-above {
+ -webkit-border-radius: 4px 4px 0 0;
+ -moz-border-radius: 4px 4px 0 0;
+ border-radius: 4px 4px 0 0;
+ margin-top: 1px;
+ border-top: 1px solid #aaa;
+ border-bottom: 0;
+ -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
+ -moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
+ -o-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
+ box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
+}
+.select2-container .select2-choice div {
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+ -moz-background-clip: padding;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ background: #ccc;
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
+ background-image: -webkit-linear-gradient(center bottom, #ccc 0, #eee 60%);
+ background-image: -moz-linear-gradient(center bottom, #ccc 0, #eee 60%);
+ background-image: -o-linear-gradient(bottom, #ccc 0, #eee 60%);
+ background-image: -ms-linear-gradient(top, #ccc 0, #eee 60%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#eeeeee', GradientType=0);
+ background-image: linear-gradient(top, #ccc 0, #eee 60%);
+ border-left: 1px solid #aaa;
+ position: absolute;
+ right: 0;
+ top: 0;
+ display: block;
+ height: 100%;
+ width: 18px;
+}
+.select2-container .select2-choice div b {
+ background: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") no-repeat 0 1px;
+ display: block;
+ width: 100%;
+ height: 100%}
+.select2-search {
+ display: inline-block;
+ white-space: nowrap;
+ z-index: 10000;
+ min-height: 26px;
+ width: 100%;
+ margin: 0;
+ padding-left: 4px;
+ padding-right: 4px;
+}
+.select2-search-hidden {
+ display: block;
+ position: absolute;
+ left: -10000px;
+}
+.select2-search input {
+ background: #fff url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") no-repeat 100% -22px;
+ background: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
+ background: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
+ background: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
+ background: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") no-repeat 100% -22px, -o-linear-gradient(bottom, #fff 85%, #eee 99%);
+ background: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") no-repeat 100% -22px, -ms-linear-gradient(top, #fff 85%, #eee 99%);
+ background: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") no-repeat 100% -22px, linear-gradient(top, #fff 85%, #eee 99%);
+ padding: 4px 20px 4px 5px;
+ outline: 0;
+ border: 1px solid #aaa;
+ font-family: sans-serif;
+ font-size: 1em;
+ width: 100%;
+ margin: 0;
+ height: auto!important;
+ min-height: 26px;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+ border-radius: 0;
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+}
+.select2-drop.select2-drop-above .select2-search input {
+ margin-top: 4px;
+}
+.select2-search input.select2-active {
+ background: #fff url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e") no-repeat 100%;
+ background: url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e") no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
+ background: url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e") no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
+ background: url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e") no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
+ background: url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e") no-repeat 100%, -o-linear-gradient(bottom, #fff 85%, #eee 99%);
+ background: url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e") no-repeat 100%, -ms-linear-gradient(top, #fff 85%, #eee 99%);
+ background: url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e") no-repeat 100%, linear-gradient(top, #fff 85%, #eee 99%);
+}
+.select2-container-active .select2-choice, .select2-container-active .select2-choices {
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ -moz-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ -o-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ border: 1px solid #5897fb;
+ outline: 0;
+}
+.select2-dropdown-open .select2-choice {
+ border: 1px solid #aaa;
+ border-bottom-color: transparent;
+ -webkit-box-shadow: 0 1px 0 #fff inset;
+ -moz-box-shadow: 0 1px 0 #fff inset;
+ -o-box-shadow: 0 1px 0 #fff inset;
+ box-shadow: 0 1px 0 #fff inset;
+ background-color: #eee;
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));
+ background-image: -webkit-linear-gradient(center bottom, #fff 0, #eee 50%);
+ background-image: -moz-linear-gradient(center bottom, #fff 0, #eee 50%);
+ background-image: -o-linear-gradient(bottom, #fff 0, #eee 50%);
+ background-image: -ms-linear-gradient(top, #fff 0, #eee 50%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+ background-image: linear-gradient(top, #fff 0, #eee 50%);
+ -webkit-border-bottom-left-radius: 0;
+ -webkit-border-bottom-right-radius: 0;
+ -moz-border-radius-bottomleft: 0;
+ -moz-border-radius-bottomright: 0;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.select2-dropdown-open .select2-choice div {
+ background: 0 0;
+ border-left: none;
+}
+.select2-dropdown-open .select2-choice div b {
+ background-position: -18px 1px;
+}
+.select2-results {
+ margin: 4px 4px 4px 0;
+ padding: 0 0 0 4px;
+ position: relative;
+ overflow-x: hidden;
+ overflow-y: auto;
+ max-height: 200px;
+}
+.select2-results ul.select2-result-sub {
+ margin: 0;
+}
+.select2-results ul.select2-result-sub>li .select2-result-label {
+ padding-left: 20px;
+}
+.select2-results ul.select2-result-sub ul.select2-result-sub>li .select2-result-label {
+ padding-left: 40px;
+}
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label {
+ padding-left: 60px;
+}
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label {
+ padding-left: 80px;
+}
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label {
+ padding-left: 100px;
+}
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label {
+ padding-left: 110px;
+}
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label {
+ padding-left: 120px;
+}
+.select2-results li {
+ list-style: none;
+ display: list-item;
+}
+.select2-results li.select2-result-with-children>.select2-result-label {
+ font-weight: 700;
+}
+.select2-results .select2-result-label {
+ padding: 3px 7px 4px;
+ margin: 0;
+ cursor: pointer;
+}
+.select2-results .select2-highlighted {
+ background: #3875d7;
+ color: #fff;
+}
+.select2-results li em {
+ background: #feffde;
+ font-style: normal;
+}
+.select2-results .select2-highlighted em {
+ background: 0 0;
+}
+.select2-results .select2-no-results, .select2-results .select2-searching, .select2-results .select2-selection-limit {
+ background: #f4f4f4;
+ display: list-item;
+}
+.select2-results .select2-disabled {
+ display: none;
+}
+.select2-more-results.select2-active {
+ background: #f4f4f4 url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e") no-repeat 100%}
+.select2-more-results {
+ background: #f4f4f4;
+ display: list-item;
+}
+.select2-container.select2-container-disabled .select2-choice {
+ background-color: #f4f4f4;
+ background-image: none;
+ border: 1px solid #ddd;
+ cursor: default;
+}
+.select2-container.select2-container-disabled .select2-choice div {
+ background-color: #f4f4f4;
+ background-image: none;
+ border-left: 0;
+}
+.select2-container-multi .select2-choices {
+ background-color: #fff;
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eee), color-stop(15%, #fff));
+ background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%);
+ background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%);
+ background-image: -o-linear-gradient(top, #eee 1%, #fff 15%);
+ background-image: -ms-linear-gradient(top, #eee 1%, #fff 15%);
+ background-image: linear-gradient(top, #eee 1%, #fff 15%);
+ border: 1px solid #aaa;
+ margin: 0;
+ padding: 0;
+ cursor: text;
+ overflow: hidden;
+ height: auto!important;
+ height: 1%;
+ position: relative;
+}
+.select2-container-multi .select2-choices {
+ min-height: 26px;
+}
+.select2-container-multi.select2-container-active .select2-choices {
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ -moz-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ -o-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ border: 1px solid #5897fb;
+ outline: 0;
+}
+.select2-container-multi .select2-choices li {
+ float: left;
+ list-style: none;
+}
+.select2-container-multi .select2-choices .select2-search-field {
+ white-space: nowrap;
+ margin: 0;
+ padding: 0;
+}
+.select2-container-multi .select2-choices .select2-search-field input {
+ color: #666;
+ background: transparent!important;
+ font-family: sans-serif;
+ font-size: 100%;
+ height: 15px;
+ padding: 5px;
+ margin: 1px 0;
+ outline: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ -o-box-shadow: none;
+ box-shadow: none;
+}
+.select2-container-multi .select2-choices .select2-search-field input.select2-active {
+ background: #fff url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e") no-repeat 100%!important;
+}
+.select2-default {
+ color: #999!important;
+}
+.select2-container-multi .select2-choices .select2-search-choice {
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ -moz-background-clip: padding;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ background-color: #e4e4e4;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+ background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+ background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+ background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+ -webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, .05);
+ -moz-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, .05);
+ box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, .05);
+ color: #333;
+ border: 1px solid #aaa;
+ line-height: 13px;
+ padding: 3px 5px 3px 18px;
+ margin: 3px 0 3px 5px;
+ position: relative;
+ cursor: default;
+}
+.select2-container-multi .select2-choices .select2-search-choice span {
+ cursor: default;
+}
+.select2-container-multi .select2-choices .select2-search-choice-focus {
+ background: #d4d4d4;
+}
+.select2-search-choice-close {
+ display: block;
+ position: absolute;
+ right: 3px;
+ top: 4px;
+ width: 12px;
+ height: 13px;
+ font-size: 1px;
+ background: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619") right top no-repeat;
+ outline: 0;
+}
+.select2-container-multi .select2-search-choice-close {
+ left: 3px;
+}
+.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
+ background-position: right -11px;
+}
+.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
+ background-position: right -11px;
+}
+.select2-container-multi.select2-container-disabled .select2-choices {
+ background-color: #f4f4f4;
+ background-image: none;
+ border: 1px solid #ddd;
+ cursor: default;
+}
+.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
+ background-image: none;
+ background-color: #f4f4f4;
+ border: 1px solid #ddd;
+ padding: 3px 5px;
+}
+.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close {
+ display: none;
+}
+.select2-result-selectable .select2-match, .select2-result-unselectable .select2-result-selectable .select2-match {
+ text-decoration: underline;
+}
+.select2-result-unselectable .select2-match {
+ text-decoration: none;
+}
+.select2-offscreen {
+ position: absolute;
+ left: -10000px;
+}
+@media (-webkit-min-device-pixel-ratio:2), (min-resolution:192dpi) {
+ .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b {
+ background-image: url("../images/select2x2.png?3edc3589b2afdcf04b18170ab6927ccb")!important;
+ background-repeat: no-repeat!important;
+ background-size: 60px 40px!important;
+}
+.select2-search input {
+ background-position: 100% -21px!important;
+}
+}.select2-container {
+ vertical-align: middle;
+}
+.select2-container .select2-choice {
+ height: 20px;
+ line-height: 20px;
+ border-color: #cdcdcd;
+ border-radius: 0;
+ background: #fff;
+ text-align: left;
+}
+.select2-container .select2-choice, .select2-container .select2-choices {
+ transition: border-color .2s ease;
+}
+.select2-container .select2-choice abbr {
+ top: 4px;
+}
+.select2-container .select2-choice div {
+ width: 19px;
+ border: none;
+ border-radius: 0;
+ background: #fff;
+}
+.select2-container .select2-choice div b {
+ top: 4px;
+ background-position: 1px -1px;
+}
+.select2-dropdown-open .select2-choice div b {
+ background-position: -17px -1px;
+}
+.select2-container-active .select2-choice, .select2-container-active .select2-choices {
+ border-color: #4b9fd5;
+ box-shadow: none;
+}
+.select2-dropdown-open .select2-choice {
+ box-shadow: none;
+}
+.select2-drop {
+ border-color: #cdcdcd;
+ border-radius: 0;
+}
+.select2-drop-active {
+ border-color: #4b9fd5;
+}
+.select2-dropdown-open.select2-drop-above .select2-choice, .select2-dropdown-open.select2-drop-above .select2-choices {
+ border-color: #4b9fd5;
+ border-radius: 0;
+ background: #fff;
+}
+.select2-drop.select2-drop-above.select2-drop-active {
+ border-color: #4b9fd5;
+ border-radius: 0;
+}
+.select2-drop.select2-drop-above .select2-search input {
+ margin-top: 0;
+}
+.select2-results {
+ margin: 0;
+ padding: 5px 0;
+ border-top: 1px solid #cdcdcd;
+}
+.select2-results .select2-result-label {
+ height: 20px;
+ line-height: 20px;
+ padding: 0 8px;
+ color: #444;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.select2-results .select2-no-results, .select2-results .select2-searching, .select2-results .select2-selection-limit, .select2-more-results.select2-active {
+ height: 20px;
+ line-height: 20px;
+ padding: 0 10px;
+}
+.select2-results .select2-highlighted {
+ background: 0 0;
+ color: #444;
+}
+.select2-results .select2-highlighted .select2-result-label {
+ background: #e2e2e2;
+}
+.select2-search {
+ padding: 4px;
+}
+.select2-search input {
+ height: 20px;
+ padding: 0 7px;
+ border-color: #cdcdcd;
+ background: #fff!important;
+}
+.select2-container-multi .select2-choices {
+ min-height: 19px;
+ padding-bottom: 1px;
+ border-color: #cdcdcd;
+ background: #fff;
+}
+.select2-container-multi.select2-container-active .select2-choices {
+ border-color: #4b9fd5;
+ box-shadow: none;
+}
+.select2-container-multi .select2-choices .select2-search-field input {
+ height: 16px;
+ padding: 0 3px;
+}
+.select2-container-multi .select2-choices .select2-search-choice {
+ margin: 1px 1px 0;
+ padding: 1px 5px 2px 18px;
+ border-radius: 0;
+ border-color: #cdcdcd;
+ background: #efefef;
+ box-shadow: none;
+}
+.select2-search-choice-close {
+ top: 2px;
+}
+.select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b {
+ background-image: url("../images/select2.png?829f9832d7c5fec528fe4119377a8619");
+}
+.select2-search input.select2-active, .select2-more-results.select2-active, .select2-container-multi .select2-choices .select2-search-field input.select2-active {
+ background-image: url("../images/spinner.gif?5725ac941d218f159a383774f1e09a0e");
+}
+@media (-webkit-min-device-pixel-ratio:2), (min-resolution:192dpi) {
+ .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b {
+ background-image: url("../images/select2x2.png?3edc3589b2afdcf04b18170ab6927ccb")!important;
+}
+}@media print {
+ html, body {
+ font-size: 8pt;
+}
+a, a:link, a:visited {
+ text-decoration: none;
+ border-bottom: 0;
+}
+.noprint {
+ display: none!important;
+}
+.print {
+ display: inline;
+ position: static;
+ left: 0;
+}
+#hd, #sidebar, #crumbs {
+ display: none;
+}
+.with_sidebar, .wo_sidebar {
+ padding: 0!important;
+ margin: 0;
+}
+#content {
+ margin-left: 0!important;
+}
+}@media screen {
+ .print {
+ display: none;
+}
+}body, a {
+ color: #444;
+}
+#container {
+ height: auto!important;
+ min-width: 940px;
+ min-height: 500px;
+}
+#hd {
+ color: #FFF;
+ background: #262626;
+ padding: 0 10px;
+ height: 30px;
+ line-height: 30px;
+ font-size: 93%;
+ margin: 0;
+ position: relative;
+}
+#hd #nav-left>ul>li {
+ height: 30px;
+}
+#hd a {
+ color: #fff;
+ border-bottom: none;
+}
+#hd a.selected, #hd a:hover, #hd a:focus {
+ color: #4b9fd5;
+}
+#nav-left {
+ float: left;
+ vertical-align: middle;
+}
+#nav {
+ float: right;
+ padding: 0 0 0 20px;
+ vertical-align: middle;
+}
+#nav-left img, #nav img {
+ vertical-align: text-bottom;
+}
+#nav-left>ul>li {
+ float: left;
+ padding: 0 20px 0 0;
+}
+#nav-left>ul>li>a, #nav>ul>li>a {
+ font-size: 12px;
+ font-weight: 300;
+ letter-spacing: .05em;
+}
+#nav>ul>li {
+ float: right;
+ height: 30px;
+ padding: 0 0 0 15px;
+}
+#searchResourcesResults {
+ position: absolute;
+ float: right;
+ width: 600px;
+ top: 30px;
+ right: 0;
+}
+#crumbs {
+ color: #444;
+ background: #EFEFEF;
+ height: 26px;
+ line-height: 26px;
+ font-size: 93%;
+ margin: 0;
+ padding: 0 10px;
+ border-bottom: 1px solid #CCC;
+}
+#crumbs img {
+ vertical-align: text-bottom;
+}
+#bc li {
+ float: left;
+ background: #efefef url("../images/bc-gray.png?6ec133698d492b4ad1f227aba4d6fe03") no-repeat right;
+ border-bottom: 1px solid #CCC;
+ padding: 0 20px 0 0;
+ margin: 0 10px 0 0;
+}
+#bc li img {
+ margin-right: -5px;
+}
+#bc li a {
+ border-bottom: none;
+}
+#crumbs-ops {
+ float: right;
+ padding: 0 5px 0 0;
+}
+#crumbs-ops li {
+ float: left;
+ padding: 0 0 0 10px;
+}
+#crumbs-ops li a {
+ border-bottom: none;
+}
+#hd .dropdown-menu a {
+ color: #000;
+}
+#project-settings-menu {
+ float: right;
+ right: 20px;
+}
+#nonav {
+ text-align: left;
+ margin: 50px 180px 0;
+}
+#footer {
+ padding: 4px 0;
+ clear: both;
+}
+#body {
+ position: relative;
+}
+.with_sidebar {
+ margin: 0 0 0 160px;
+ padding: 10px;
+}
+.wo_sidebar {
+ margin: 0 8px;
+}
+#sidebar {
+ position: absolute;
+ top: 0;
+ left: 10px;
+ width: 150px;
+}
+#sidebar.sticky {
+ position: fixed;
+}
+ul.sidebar {
+ text-align: left;
+ border-top: none;
+ padding: 10px 0;
+}
+ul.sidebar li {
+ list-style-type: none;
+ padding: 3px 10px;
+}
+ul.sidebar li>a {
+ border-bottom: none;
+}
+ul.sidebar li.active {
+ background-color: #4b9fd5;
+}
+ul.sidebar li.active a, ul.sidebar li.active a:hover {
+ color: #FFF;
+}
+ul.sidebar li.active [class^=icon-], ul.sidebar li.active [class*=" icon-"] {
+ color: #FFF;
+}
+li.sidebar-title {
+ text-transform: uppercase;
+ font-size: 93%;
+ font-weight: 700;
+}
+ul.sidebar li.spacer {
+ border: 0 none;
+ height: 10px;
+ margin: 0;
+ padding: 0;
+}
+ul.sidebar select, ul.sidebar input {
+ font-size: 93%}
+#logo {
+ text-align: center;
+ padding: 10px 0 0;
+}
+#logo a {
+ text-decoration: none;
+ border-bottom-width: 0;
+}
+#logo img {
+ display: block;
+}
+.page {
+ padding: 10px;
+}
+.page-split-left {
+ min-width: 200px;
+ max-width: 200px;
+ width: 200px;
+ margin: 0;
+ display: block;
+ vertical-align: top;
+ border-top: none;
+ border-left: none;
+ float: left;
+}
+.page-split-right {
+ display: block;
+ margin: 0;
+ vertical-align: top;
+ padding: 0 0 0 200px;
+}
+.gray-sidebar {
+ background-color: #EFEFEF;
+ border: 1px solid #CCC;
+ color: #666;
+ border-top: none;
+}
+.blue-sidebar {
+ height: 100%;
+ border-left: 1px solid #4b9fd5;
+ border-right: 1px solid #4b9fd5;
+ border-bottom: 1px solid #4b9fd5;
+ background-color: #cae3f2;
+ color: #444;
+}
+.nolayout {
+ padding: 10px;
+}
+#projectSearch {
+ color: #444;
+ margin: 4px 0 0;
+}
+#ftlinks {
+ background: #fff;
+ color: #262626;
+ text-align: center;
+ border-top: 1px solid #fff;
+ font-size: 85%;
+ padding: 10px 0;
+ line-height: 1.4;
+}
+.ie-warn {
+ color: #EEE;
+ background: #FF5252;
+ padding: 0 5px;
+}
+.ie-warn a {
+ color: #EEE;
+ text-decoration: underline;
+}
+a {
+ cursor: pointer;
+}
+a.icon-favorite, a.icon-not-favorite {
+ border-bottom: none;
+}
+.loading {
+ background: url("../images/loading.gif?e2a9308e1360f28fb8fe7ad05eed2e38") no-repeat 4px 2px;
+ color: #444;
+ padding: 3px 25px;
+}
+.right {
+ text-align: right;
+}
+.left {
+ text-align: left;
+}
+.center {
+ text-align: center;
+}
+.top {
+ vertical-align: top;
+}
+.bottom {
+ vertical-align: bottom;
+}
+.middle {
+ vertical-align: middle;
+}
+.nowrap {
+ white-space: nowrap;
+}
+code {
+ font-size: 93%}
+.hidden {
+ display: none;
+ visibility: hidden;
+}
+.clear {
+ height: 0;
+ clear: both;
+}
+.note {
+ color: #777;
+ font-size: 93%;
+ font-weight: 400;
+ line-height: 13px;
+}
+.note img {
+ vertical-align: bottom;
+}
+.crossout {
+ text-decoration: line-through;
+}
+.small {
+ font-size: 12px;
+}
+small {
+ color: #AAA;
+ font-size: 85%;
+ font-style: normal;
+}
+em {
+ font-weight: 700;
+}
+em.mandatory {
+ color: #900;
+ font-style: italic;
+}
+a.external {
+ background: url("../images/links/external.png?c4631db232b81958abf720e423de13b1") no-repeat 100% 0;
+ padding: 0 16px 0 0;
+}
+.fav {
+ display: inline-block;
+ background: url("../images/star.png?d9e2d314eea5020e5f8f8490e74bbd7a") no-repeat 100% 0;
+ width: 16px;
+ height: 16px;
+ vertical-align: text-bottom;
+}
+.notfav {
+ display: inline-block;
+ background: url("../images/star_off.png?ac5da9e28e8bb5b3aa06b60c69bd6029") no-repeat 100% 0;
+ width: 16px;
+ height: 16px;
+ vertical-align: text-bottom;
+}
+.red-button {
+ color: #900!important;
+}
+.red-button:hover {
+ color: #FFF!important;
+ border: solid 1px #CD504A!important;
+ background: #B33630!important;
+ background: -webkit-gradient(linear, left top, left bottom, from(#dc5f59), to(#b33630))!important;
+ background: -moz-linear-gradient(top, #dc5f59, #b33630)!important;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#DC5F59', endColorstr='#B33630')!important;
+}
+.red-button:active {
+ color: #FFF!important;
+ border: solid 1px #CD504A!important;
+ background: #B33630!important;
+ background: -webkit-gradient(linear, left top, left bottom, from(#ac2f29), to(#d35650))!important;
+ background: -moz-linear-gradient(top, #ac2f29, #d35650)!important;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#AC2F29', endColorstr='#D35650')!important;
+}
+.red-button[disabled] {
+ position: relative;
+ top: 0;
+ text-shadow: 1px 1px 0 #FFF;
+ color: #BBB;
+ border: solid 1px #DDD;
+ background: #EBEBEB;
+ background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e1e1e1));
+ background: -moz-linear-gradient(top, #fff, #e1e1e1);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#E1E1E1');
+ cursor: default;
+}
+h1, .h1 {
+ color: #444;
+ font-size: 16px;
+}
+h2, .h2 {
+ color: #444;
+ font-size: 16px;
+ font-weight: 400;
+}
+h3, .h3 {
+ color: #444;
+ font-size: 100%;
+ font-weight: 700;
+}
+h4, .h4 {
+ color: #444;
+ font-size: 85%;
+ color: #777;
+}
+h1 img, .h1 img, h2 img, .h2 img, h3 img, .h3 img, h4 img, .h4 img {
+ vertical-align: middle;
+}
+.subtitle {
+ color: #777;
+ font-size: 85%;
+ margin: 0;
+ padding: 0;
+}
+.notes {
+ color: #777;
+ font-size: 11px;
+ margin-bottom: 10px;
+ background-color: #EFEFEF;
+ border: 1px solid #cdcdcd;
+ line-height: 16px;
+ height: 16px;
+ padding: 2px 4px;
+}
+.treemap {
+ position: relative;
+ cursor: pointer;
+}
+.treemap a {
+ color: #FFF;
+ text-decoration: none;
+ font-size: 12px;
+ padding: 1px;
+}
+.treemap a:hover {
+ text-decoration: underline;
+}
+.warning, .modal-warning {
+ border: solid 1px #FFD324;
+ background-color: #FFF6BF;
+ color: #514721;
+ margin: 0 0 4px;
+ padding: 4px;
+}
+.error, .modal-error {
+ border: 1px solid red;
+ background-color: #FF5252;
+ color: #eee;
+ margin: 0 0 4px;
+ padding: 4px;
+}
+.error a, .modal-error a {
+ color: #eee;
+}
+.notice, .modal-notice {
+ border: 1px solid #9c9;
+ background-color: #e2f9e3;
+ color: #060;
+ margin: 0 0 4px;
+ padding: 4px;
+}
+.info {
+ background-color: #CAE3F2;
+ padding: 5px;
+ border: 1px solid #4B9FD5;
+}
+.migration {
+ background-image: url("../images/logo.png?c37a88b91098aeae04bcfdf3b4388837");
+ background-repeat: no-repeat;
+ background-position: top right;
+}
+#login_form {
+ border: 2px solid #4b9fd5;
+ width: 230px;
+ text-align: left;
+ background-color: #CAE3F2;
+ padding: 15px 20px;
+}
+#login_form h4 {
+ text-align: left;
+ font-weight: 700;
+ color: #036;
+}
+#login_form p {
+ padding: 3px 0 10px;
+}
+#login_form a {
+ border-bottom-color: #4b9fd5;
+}
+#login_form .desc {
+ font-size: 85%;
+ font-weight: 400;
+}
+.doc h2 {
+ margin-top: 8px;
+}
+.doc p {
+ margin: 8px 0;
+}
+.doc pre, pre.code {
+ color: #777;
+ background-color: #EFEFEF;
+ padding: 10px;
+ margin: 10px 0;
+ border: 1px dashed #777;
+ font-size: 93%;
+ line-height: 1.5em;
+}
+.doc li {
+ list-style: disc outside;
+ padding: 2px;
+}
+.doc ul {
+ list-style: none outside;
+ padding-left: 30px;
+}
+.odd {
+ background-color: #fff;
+}
+.odd.selected, .even.selected, .odd.selected a, .even.selected a, .even.selected span, .odd.selected span {
+ background-color: #cae3f2;
+ color: #444;
+}
+table.data>thead>tr>th {
+ vertical-align: top;
+ font-size: 93%;
+ padding: 4px 7px 4px 3px;
+ line-height: 1.4;
+ text-transform: uppercase;
+}
+table.data>thead>tr>th>.small {
+ text-transform: none;
+}
+table.data>tfoot>tr>td {
+ font-size: 93%;
+ color: #777;
+ padding: 5px;
+}
+table.data>tbody>tr>td {
+ padding: 5px;
+ vertical-align: text-top;
+}
+table.data td.small, table.data th.small {
+ padding: 0;
+ white-space: nowrap;
+}
+table.data th img, table.data td img {
+ vertical-align: sub;
+}
+table.data.zebra tbody tr:nth-child(odd) {
+ background-color: #f5f5f5;
+}
+.data thead tr.total {
+ background-color: #EFEFEF;
+ font-weight: 400;
+ border: 1px solid #DDD;
+}
+.data thead tr.total th {
+ font-weight: 400;
+}
+.data thead tr.blank {
+ background-color: #fff;
+ line-height: 15px;
+}
+.data tr.highlight {
+ background-color: #cae3f2;
+}
+.data input, .data select, .data button {
+ vertical-align: baseline;
+}
+.data td.category {
+ padding-right: 15px;
+}
+.categoryDescription {
+ padding: 10px 5px;
+}
+.data td.category.withSubcategories {
+ background-image: url("../images/bullet_arrow_down.gif?1c3bb7944d54b3f1bfdb8afb824ace93");
+ background-position: right center;
+ background-repeat: no-repeat;
+}
+.data td.subcategory {
+ padding-left: 20px;
+}
+.hoverable:hover {
+ background-color: #CAE3F2;
+}
+.hoverable:hover a {
+ color: #111;
+}
+table.sortable .sortcol {
+ cursor: pointer;
+ padding-left: 15px;
+ background-repeat: no-repeat;
+ background-position: right center;
+}
+table.sortable .sortasc {
+ background-image: url("../images/bullet_arrow_up.gif?09792aedf077cad45ba64d5c07ac339c");
+ background-position: left center;
+}
+table.sortable .sortdesc {
+ background-image: url("../images/bullet_arrow_down.gif?1c3bb7944d54b3f1bfdb8afb824ace93");
+ background-position: left center;
+}
+table.sortable .righticon {
+ padding-right: 15px;
+ background-position: right center;
+}
+table.sortable .nosort {
+ cursor: default;
+}
+table.spaced th {
+ font-weight: 700;
+ color: #333;
+ padding: 4px 5px;
+}
+table.spaced td, table.matrix tfoot td {
+ padding: 3px 5px;
+ line-height: 18px;
+}
+table.spaced td img {
+ vertical-align: text-bottom;
+}
+table.spacedicon th {
+ font-weight: 700;
+ color: #333;
+ padding: 4px 5px;
+}
+table.spacedicon td {
+ padding: 0 5px;
+ height: 24px;
+}
+.thin {
+ width: 1%}
+td.sep {
+ width: 10px;
+}
+.spacer {
+ width: 5px;
+ display: inline-block;
+}
+.formError {
+ display: inline-block;
+ background-color: #FF9090;
+ color: #000;
+ padding: 0 5px;
+}
+table.form td {
+ padding: 2px 5px;
+ vertical-align: top;
+}
+table.form td.keyCell {
+ width: 1%;
+ white-space: nowrap;
+ text-align: right;
+ font-weight: 700;
+ vertical-align: top;
+}
+table.form td img {
+ vertical-align: bottom;
+}
+.admin hr {
+ background: 0 0;
+ border-left: none;
+ border-right: none;
+ border-top: none;
+ border-bottom: 1px dashed #FFD324;
+ height: 1px;
+}
+table#project-history tr>td {
+ vertical-align: top;
+}
+#page-operations {
+ display: inline-block;
+ width: 100%}
+div.operations {
+ float: right;
+ margin: 0;
+}
+ul.operations {
+ float: right;
+ height: 20px;
+ line-height: 20px;
+ list-style-type: none;
+ margin: 0;
+ background-color: #EFEFEF;
+ border: 1px solid #cdcdcd;
+ border-radius: 3px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+}
+ul.operations li {
+ float: left;
+ margin: 0;
+ padding: 0 8px;
+ font-size: 85%;
+ border-right: 1px solid #cdcdcd;
+}
+ul.operations li.selected {
+ background-color: #d4d4d4;
+}
+ul.operations li.last {
+ border-right-width: 0;
+}
+ul.operations li a {
+ color: #444;
+ outline: 0;
+ text-decoration: none;
+ transition: all .2s ease;
+ color: #555;
+}
+ul.operations li a:hover {
+ color: #4b9fd5;
+}
+ul.operations li a:active, ul.operations li a:focus {
+ color: #236a97;
+}
+ul.operations li img {
+ vertical-align: middle;
+ margin-right: 5px;
+}
+th.operations, td.operations {
+ text-align: right;
+}
+.resourceName h1 {
+ margin: 5px 0;
+}
+.sources2 {
+ width: 100%;
+ border: 0;
+ margin: 0;
+ background-color: #FFF;
+}
+.sources2 td.lid {
+ background-color: #EFEFEF;
+ border-right: 1px solid #DDD;
+ text-align: right;
+ padding: 2px .5em 0;
+ vertical-align: top;
+ font-size: 85%}
+.sources2 td.lid a {
+ text-decoration: none;
+ color: #AAA;
+}
+.sources2 td.scm {
+ border-right: 1px solid #DDD;
+ background-color: #EFEFEF;
+}
+.sources2 td.revision {
+ border-top: 1px solid #DDD;
+ vertical-align: top;
+ padding: 0 .3em;
+ white-space: nowrap;
+}
+.sources2 tr:first-child td.revision {
+ border-top: none;
+}
+.sources2 tr.row td.plus {
+ background-color: #EFEFEF;
+ padding: 0;
+ width: 16px;
+}
+.sources2 tr.row:hover td.plus {
+ background: url("../images/add.png?4ea982641458a260ca3bc0575b5c687e") no-repeat scroll left 0 #efefef;
+}
+.sources2 td.plus a {
+ display: block;
+ cursor: pointer;
+ height: 16px;
+ width: 16px;
+}
+.sources2 td.gray {
+ background-color: #EFEFEF;
+ padding: 2px .5em 0;
+}
+.sources2 td.white {
+ border-left: 1px solid #DDD;
+ background-color: #FFF;
+}
+.sources2 span.date, .sources2 span.date a {
+ color: #AAA;
+ font-size: 85%;
+ text-decoration: none;
+}
+.sources2 span.author, .sources2 span.author a {
+ font-size: 85%}
+.sources2 div.violation, #global_violations div.violation {
+ background-color: #FFF;
+ margin: 0;
+ border: 1px solid #DDD;
+ font-size: 12px;
+}
+.rulename, .rulename a {
+ color: #444;
+ font-weight: 700;
+}
+.rulename a:hover {
+ text-decoration: underline;
+}
+.sources2 td.line {
+ width: 100%}
+.sources2 td.line pre {
+ font-size: 12px;
+ font-family: monospace;
+}
+.sources2 td.ind {
+ border-right: 1px solid #DDD;
+ padding: 0 .3em;
+ text-align: center;
+ vertical-align: middle;
+}
+.sources2 td.ind a, .sources2 td.ind span {
+ padding: 0 3px;
+}
+.sources2 td.ok {
+ background-color: #ACE97C;
+}
+.sources2 td.warn {
+ background-color: #FFF6BF;
+}
+.sources2 td.ko {
+ background-color: #FF9090;
+}
+.sources2 td.new_section {
+ border-width: 1px 0;
+ border-style: solid;
+ border-color: #EEE #DDD;
+ height: 30px;
+ background: url("../images/gray-stripes.png?c0affd395b7ae52801fcae4cbc50fd81");
+}
+.sources2 td.violations {
+ background-color: #FFF;
+ padding: 10px;
+ border-left: 1px solid #DDD;
+}
+.source_title {
+ padding: 10px 5px;
+}
+.source_title span.h1 {
+ font-size: 16px;
+ margin-right: 10px;
+}
+.source_links {
+ font-size: 11px;
+}
+.global_violations {
+ width: 100%}
+.global_violations>tbody>tr>td {
+ padding-bottom: 10px;
+}
+.global_violations td {
+ padding: 3px 0;
+}
+.global_violations td img, #source_title img {
+ vertical-align: text-bottom;
+}
+.code-issue-create-form {
+ padding: 10px;
+}
+.code-global-issues {
+ padding: 10px 10px 0;
+}
+.code-issues {
+ padding: 10px 10px 0;
+ line-height: 0;
+}
+.code-issue {
+ margin: 0;
+ font-size: 12px;
+ padding: 0 0 10px;
+ transition: border-color .2s ease;
+}
+.code-issue .error {
+ line-height: normal;
+}
+.code-issue strong {
+ font-weight: 700;
+}
+.code-issue-toggle {
+ cursor: pointer;
+}
+.code-issue-name {
+ position: relative;
+ background-color: #E4ECF3;
+ margin: 0;
+ padding: 5px 10px;
+ line-height: 16px;
+ color: #777;
+ border: 1px solid #DDD;
+ border-bottom: medium none;
+}
+.code-issue-msg {
+ line-height: 1.5;
+ padding: 5px 10px;
+ border-left: 1px solid #DDD;
+ border-right: 1px solid #DDD;
+ background-color: #EFEFEF;
+}
+.code-issue-name img {
+ vertical-align: text-bottom;
+}
+.code-issue-name-rule {
+ max-width: 90%;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.code-issue-permalink {
+ position: absolute;
+ top: 4px;
+ right: 4px;
+}
+.code-issue-permalink a {
+ text-decoration: none;
+}
+.code-issue-name-extra {
+ margin-top: 6px;
+ line-height: 12px;
+}
+.code-issue-name-extra li {
+ font-size: 11px!important;
+}
+.code-issue-name-right {
+ position: absolute;
+ top: 5px;
+ right: 26px;
+}
+.code-issue-comment, .code-issue-msg, .code-issue-actions, .code-issue-form {
+ background-color: #EFEFEF;
+ border: 1px solid #DDD;
+ border-top: none;
+ line-height: 1.5em;
+ margin: 0;
+ padding: 5px 10px;
+}
+.code-issue-form input[type=submit], .code-issue-form input[type=button], .code-issue-form button, .code-issue-form .action {
+ vertical-align: middle;
+}
+.code-issue-comment h4 {
+ font-size: 11px;
+ margin-bottom: 2px;
+}
+.code-issue-comment h4 img {
+ vertical-align: sub;
+}
+.code-issue-comment ul li {
+ list-style: square inside;
+}
+.code-issue-comment ol li {
+ list-style: decimal inside;
+}
+.code-issue-comment pre {
+ padding: 10px;
+ border: 1px dashed #DDD;
+ color: #444;
+ font-size: 12px;
+}
+.code-issue-details {
+ padding: 0 10px 5px;
+ border-left: 1px solid #DDD;
+ border-right: 1px solid #DDD;
+ border-bottom: 1px solid #DDD;
+ background-color: #EFEFEF;
+ line-height: 1.3;
+}
+.code-issue-tabs {
+ margin-bottom: 5px;
+ font-size: 0;
+}
+.code-issue-tabs>li {
+ display: inline-block;
+ padding: 4px 0;
+ color: #777;
+ font-size: 12px;
+}
+.code-issue-tabs>li+li {
+ margin-left: 15px;
+}
+.code-issue-details-list>li {
+ font-size: 0;
+}
+.code-issue-details-term, .code-issue-details-value {
+ display: inline-block;
+ vertical-align: top;
+ font-size: 12px;
+ line-height: 20px;
+}
+.code-issue-details-term {
+ width: 90px;
+}
+.code-issue-details-term:after {
+ content: ":"}
+.code-issue-list {
+ background-color: #E4ECF3;
+}
+.code-issue-bar, .code-issue-list {
+ font-size: 0;
+ white-space: nowrap;
+}
+.code-issue-list>li, .code-issue-bar>li {
+ display: inline-block;
+ vertical-align: middle;
+ height: 14px;
+ line-height: 14px;
+ padding: 0 8px;
+ border-left: 1px solid #fff;
+ border-right: 1px solid #bfbfbf;
+ font-size: 12px;
+}
+.code-issue-list>li:first-child, .code-issue-bar>li:first-child {
+ padding-left: 0;
+ border-left: none;
+}
+.code-issue-list>li:last-child, .code-issue-bar>li:last-child {
+ padding-right: 0;
+ border-right: none;
+}
+.code-issue-collapsed .code-issue-msg, .code-issue-collapsed .code-issue-details {
+ display: none;
+}
+.code-issue-errors {
+ margin-top: 10px;
+}
+.tab_header {
+ padding: 5px 10px;
+}
+.tab_header td {
+ padding-right: 7px;
+}
+.tab_header td.name {
+ text-align: left;
+ white-space: nowrap;
+}
+.tab_header td.value {
+ text-align: right;
+ white-space: nowrap;
+ font-weight: 700;
+}
+.extension-close {
+ position: absolute;
+ top: 5px;
+ right: 10px;
+}
+.source_options {
+ margin-top: 5px;
+ padding-top: 5px;
+ border-top: 1px solid #ddd;
+ font-size: 85%}
+.source_options td {
+ background: url("../images/sep12.png?34e9868dc63be6f09690aa30ea1397d8") no-repeat scroll 0 50% transparent;
+ padding: 0 10px;
+}
+.source_options td.first {
+ background: 0 0;
+ padding: 0 10px 0 0;
+}
+.duplications {
+ max-width: 100%}
+.duplications td.item {
+ text-align: right;
+ vertical-align: top;
+ padding: 0;
+}
+.duplications td.item p {
+ padding: 3px 5px;
+}
+.duplications td.fileItem {
+ text-align: left;
+ vertical-align: top;
+ padding: 0;
+ white-space: nowrap;
+}
+.duplications td.fileItem p {
+ padding: 3px 5px;
+}
+.duplications td.item p.selected, .duplications td.fileItem p.selected {
+ background-color: #EFEFEF;
+ border-top: 1px solid #DDD;
+ border-bottom: 1px solid #DDD;
+ padding: 3px 5px;
+}
+.duplications td.fileItem p.selected a {
+ text-decoration: none;
+}
+.duplications td.sourceItem {
+ padding: 0;
+ background-color: #EFEFEF;
+ border: 1px solid #DDD;
+ border-left: none;
+}
+.duplications td.sourceItem p {
+ padding: 3px;
+}
+.duplicationsMessage {
+ padding: 10px;
+}
+.discussion {
+ width: 100%;
+ border: 1px solid #DDD;
+}
+.discussionComment.first {
+ border-top: none;
+}
+.discussionComment {
+ background-color: #EFEFEF;
+ border-top: 1px solid #DDD;
+ line-height: 1.5em;
+ margin: 0;
+ padding: 5px 10px;
+}
+.discussionComment h4 {
+ font-size: 90%;
+ margin-bottom: 2px;
+}
+.discussionComment h4 img {
+ vertical-align: sub;
+}
+.discussionComment ol li {
+ list-style: decimal inside;
+}
+.discussionComment ul li {
+ list-style: square inside;
+}
+.discussionComment pre {
+ padding: 10px;
+ border: 1px dashed #DDD;
+ color: #444;
+ font-size: 12px;
+}
+div.comment-excerpt {
+ background-color: transparent;
+ margin-top: 5px;
+ margin-bottom: 5px;
+ color: #777;
+ font-size: 90%}
+table.actionPlans {
+ margin-top: 10px;
+}
+table.actionPlans td.progress {
+ width: 300px;
+ padding: 0 40px;
+}
+table.actionPlans td.noprogress {
+ color: #777;
+ font-size: 93%;
+ padding-left: 43px;
+ padding-right: 40px;
+}
+table.actionPlans td.over-due {
+ color: #C00;
+ font-weight: 700;
+}
+div.progress {
+ width: 100%;
+ margin: 4px;
+}
+div.progress table {
+ width: 100%}
+div.progress td {
+ height: 10px;
+}
+div.progress td a {
+ display: block;
+ width: 100%;
+ height: 100%}
+div.progress td.resolved {
+ background-color: #078C00;
+}
+div.progress td.open {
+ background-color: #C00;
+}
+div.progress div.note {
+ color: #777;
+ font-size: 93%;
+ font-weight: 400;
+ white-space: nowrap;
+}
+div.note a {
+ color: #777;
+}
+#searchInput {
+ color: #444;
+ font-size: 13px;
+ padding-right: 20px;
+}
+#searchingResources {
+ position: absolute;
+ top: 8px;
+ right: 18px;
+}
+div.autocomplete {
+ position: absolute;
+ width: 600px;
+ right: 10px;
+ top: 10px;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ margin: 0;
+ padding: 0;
+ color: #111;
+ line-height: 18px;
+ box-shadow: 10px 10px 20px rgba(0, 0, 0, .5);
+ z-index: 999999;
+}
+div.autocomplete ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+div.autocomplete ul li {
+ list-style-type: none;
+ display: block;
+ margin: 0;
+ padding: 3px 5px;
+ cursor: pointer;
+ color: #333;
+ line-height: 18px;
+ height: 18px;
+ vertical-align: middle;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+div.autocomplete div.q {
+ font-size: 93%;
+ color: #777;
+ width: 90px;
+ text-align: right;
+ margin-right: 5px;
+ display: inline-block;
+ zoom: 1;
+ *display: inline;
+}
+div.autocomplete ul li img {
+ vertical-align: middle;
+}
+div.autocomplete ul li.selected {
+ background-color: #cae3f2;
+}
+div.autocomplete strong {
+ font-weight: 700;
+}
+div.autocompleteNote {
+ color: #777;
+ font-size: 85%;
+ background-color: #EFEFEF;
+ border-top: 1px solid #CCC;
+ padding: 1px 10px;
+}
+#gwtpage {
+ width: 100%}
+.gwt-SourcePanel {
+ font-size: 12px;
+ background-color: #fff;
+ border-top: 1px solid silver;
+ border-bottom: 1px solid silver;
+ width: 100%}
+.gwt-SourcePanel .ln {
+ background-color: #EFEFEF;
+ white-space: nowrap;
+ text-align: right;
+ font-size: 85%;
+ color: #AAA;
+ border-right: 1px solid #DDD;
+ padding: 0 3px;
+ height: 14px;
+}
+.gwt-SourcePanel .src {
+ padding: 0 5px;
+ height: 14px;
+}
+.gwt-SourcePanel .val {
+ background-color: #EFEFEF;
+ border-right: 1px solid #DDD;
+ text-align: right;
+ color: #777;
+ padding: 0 3px;
+ height: 14px;
+ white-space: nowrap;
+}
+.gwt-SourcePanel .red {
+ background-color: #F0C8C8;
+}
+.gwt-SourcePanel .orange {
+ background-color: #FFF6BF;
+ color: #514721;
+}
+.gwt-SourcePanel .green {
+ background-color: #ACE97C;
+}
+.gwt-SourcePanel .msg {
+ font-family: sans-serif;
+ vertical-align: top;
+ padding: 3px 0;
+ height: 1.3em;
+ background-position: 5px 1px;
+ background-repeat: no-repeat;
+}
+.gwt-SourcePanel .bigln {
+ font-family: sans-serif;
+ vertical-align: top;
+ padding: 3px 0;
+ height: 1.6em;
+ background-position: 5px 1px;
+ background-repeat: no-repeat;
+ background-color: #EFEFEF;
+}
+.gwt-SourcePanel .warn {
+ font-family: sans-serif;
+ vertical-align: top;
+ background-color: #FFFFC9;
+ border: 1px solid #DCDCDC;
+ border-top: none;
+ color: #000;
+ line-height: 1.6em;
+ margin: 0;
+ padding: 0 0 2px 5px;
+}
+.gwt-SourcePanel .msg.error {
+ background-image: url("../images/exclamation.png?ce271080701989135bfe2211fc44bb52");
+}
+.gwt-SourcePanel .msg.warning {
+ background-image: url("../images/warning.png?afd11ba47b28942073cdc83be5f9a585");
+}
+.gwt-SourcePanel .msg.BLOCKER {
+ padding: 1px 5px 1px 25px;
+ background-image: url("../images/priority/BLOCKER.gif?c949e4e4fcd27032b9293b5e10f42712");
+ background-color: #FF5252;
+ color: #eee;
+ border: 1px solid red;
+ margin: 1px 0 1px 5px;
+ height: 100%}
+.gwt-SourcePanel .msg.CRITICAL {
+ padding: 1px 5px 1px 25px;
+ background-image: url("../images/priority/CRITICAL.gif?f206a6d8f76787e9a2fee6b20d1b08ab");
+ background-color: #FF5252;
+ color: #eee;
+ border: 1px solid red;
+ margin: 1px 0 1px 5px;
+ height: 100%}
+.gwt-SourcePanel .msg.MAJOR {
+ padding: 1px 5px 1px 25px;
+ background-image: url("../images/priority/MAJOR.gif?03a144017ac15577a0689992f310e5d3");
+ background-color: #FF5252;
+ color: #eee;
+ border: 1px solid red;
+ margin: 1px 0 1px 5px;
+ height: 100%}
+.gwt-SourcePanel .msg.MINOR {
+ padding: 1px 5px 1px 25px;
+ background-image: url("../images/priority/MINOR.gif?7c6095fa30e19e007c8e6d77dddfddbc");
+ background-color: #FFF6BF;
+ border: 1px solid #FFD324;
+ margin: 1px 0 1px 5px;
+ height: 100%}
+.gwt-SourcePanel .msg.INFO {
+ padding: 1px 5px 1px 25px;
+ background-image: url("../images/priority/INFO.gif?5ea2d33455a15853170a173ab42ac437");
+ background-color: #FFF6BF;
+ border: 1px solid #FFD324;
+ margin: 1px 0 1px 5px;
+ height: 100%}
+.gwt-ViewerHeader {
+ background-color: #EFEFEF;
+ border: 1px solid #DDD;
+ border-top: none;
+ margin-bottom: 8px;
+ color: #333;
+ vertical-align: bottom;
+}
+.gwt-ViewerHeader .metric {
+ padding: 8px 2px 5px 10px;
+ font-size: 93%;
+ text-align: right;
+ font-weight: 700;
+}
+.gwt-ViewerHeader .value {
+ padding: 8px 15px 5px 2px;
+ font-size: 93%;
+ text-align: left;
+ font-weight: 400;
+}
+.gwt-ViewerHeader .cell {
+ padding: 3px 10px;
+}
+.gwt-ViewerHeader .big {
+ padding: 4px 10px 2px;
+ font-size: 152%;
+ font-weight: 700;
+}
+.page_title {
+ margin: 0 0 7px;
+}
+.color_OK {
+ border: 2px solid #85bb43!important;
+ color: #85bb43!important;
+}
+.color_WARN {
+ border: 2px solid #f90!important;
+ color: #f90!important;
+}
+.color_ERROR {
+ border: 2px solid #d4333f!important;
+ color: #d4333f!important;
+}
+#alerts_widget {
+ margin-bottom: 10px;
+ padding: 5px 5px 5px 10px;
+}
+#alerts_widget img {
+ vertical-align: bottom;
+}
+span.empty_widget {
+ color: #777;
+ font-size: 93%}
+.dashbox {
+ float: left;
+ vertical-align: top;
+ text-align: left;
+ padding: 0 10px 7px 0;
+}
+.dashbox h3 {
+ line-height: 1.2;
+ font-size: 16px;
+ font-weight: 300;
+}
+.dashbox a {
+ color: #236a97;
+ outline: 0;
+ text-decoration: none;
+ transition: all .2s ease;
+ border-bottom: 1px solid #cae3f2;
+}
+.dashbox a:hover {
+ color: #4b9fd5;
+}
+.dashbox a:active, .dashbox a:focus {
+ color: #236a97;
+}
+.dashbox a .rating {
+ color: #fff;
+}
+.big {
+ font-size: 152%;
+ font-weight: 700;
+}
+.adminportlet {
+ border: 2px dashed #ccc;
+ margin-bottom: 10px;
+ padding: 10px;
+}
+table.header1 {
+ background-color: #EFEFEF;
+ color: #444;
+ border: 1px solid #DDD;
+ margin: 0 0 10px;
+ width: 100%}
+table.header1 td {
+ padding: 10px 0 10px 10px;
+ text-align: left;
+ vertical-align: top;
+}
+.headerLine {
+ background-color: #EFEFEF;
+ color: #444;
+ border: 1px solid #DDD;
+ margin: 0 0 10px;
+ line-height: 28px;
+ height: 28px;
+}
+ul.headerLine li {
+ float: left;
+ display: block;
+ padding: 0 10px;
+ height: 28px;
+ vertical-align: middle;
+}
+ul.headerLine li.sep {
+ background: url("../images/sep12.png?34e9868dc63be6f09690aa30ea1397d8") no-repeat scroll 50% 50% transparent;
+ padding: 0 5px;
+}
+ul.headerLine select, ul.headerLine input, ul.headerLine button, ul.headerLine textarea, ul.headerLine span {
+ vertical-align: middle;
+}
+select.withIcons option, span.withIcons {
+ background-repeat: no-repeat;
+ background-position: 2px 0;
+ padding: 0 2px 0 22px;
+ vertical-align: middle;
+}
+option.status_open {
+ background-image: url("../images/status/OPEN.png?93470244b51797cb5c435a34167b05b6");
+}
+option.status_reopened {
+ background-image: url("../images/status/REOPENED.png?510859cfbda0d26c7cab6e9f1cc79ebc");
+}
+option.status_resolved {
+ background-image: url("../images/status/RESOLVED.png?869f86bf2642e99417689f4a5a94670b");
+}
+option.status_closed {
+ background-image: url("../images/status/CLOSED.png?60be2fa5dd39904af6532bf57a6c0a60");
+}
+option.sev_INFO, span.sev_INFO {
+ background-image: url("../images/priority/INFO.png?092726fdd9e95ac273b6d7f54d0eddbe");
+}
+option.sev_MINOR, span.sev_MINOR {
+ background-image: url("../images/priority/MINOR.png?e0c036e9432170fe7e3f298fcec2eef6");
+}
+option.sev_MAJOR, span.sev_MAJOR {
+ background-image: url("../images/priority/MAJOR.png?bc3cfc6c0a0dc1a51a19feb96afd837e");
+}
+option.sev_CRITICAL, span.sev_CRITICAL {
+ background-image: url("../images/priority/CRITICAL.png?ed0c398b4ff5e18fbeee90f7d81c5741");
+}
+option.sev_BLOCKER, span.sev_BLOCKER {
+ background-image: url("../images/priority/BLOCKER.png?9fb61c8155cd5dbcf54afa837cc33269");
+}
+.var {
+ color: #444!important;
+}
+.varb {
+ color: #85bb43!important;
+}
+.varw {
+ color: #d4333f!important;
+}
+.help {
+ border: 1px solid #DDD;
+ background-color: #EFEFEF;
+ color: #444;
+ padding: 5px;
+}
+.help h2 {
+ padding-left: 23px;
+ color: #444;
+ vertical-align: bottom;
+ font-weight: 700;
+ background: url("../images/information.png?441b7712b4c687fd869663595f2d2841") no-repeat left center;
+}
+.help p {
+ padding: 5px 0;
+}
+.inline-help {
+ padding: 5px;
+ margin: 5px;
+ background-color: #FFF6BF;
+ border: 1px solid #FFD324;
+}
+.admintable {
+ border: solid 1px #FFD324;
+ background-color: #FFF6BF;
+ color: #111;
+}
+.admintable td {
+ padding: 5px 10px;
+}
+.admintable span.desc {
+ font-size: 85%;
+ font-weight: 400;
+}
+.box {
+ border: 1px solid #ccc;
+ background-color: #EFEFEF;
+ margin-bottom: 5px;
+ color: #444;
+ padding: 10px;
+}
+.box a, .box a:visited {
+ color: #555;
+}
+.admin {
+ border: solid 1px #FFD324;
+ background-color: #FFF6BF;
+ color: #514721;
+ margin-bottom: 5px;
+ padding: 5px;
+}
+.admin h3 {
+ font-size: 100%;
+ text-align: left;
+ font-weight: 700;
+ color: #333;
+}
+.column {
+ vertical-align: top;
+ text-align: left;
+ padding: 0 0 0 10px;
+}
+.column.first {
+ padding: 0;
+}
+.column h3 {
+ padding: 3px 0;
+}
+.scrollable {
+ height: 144px;
+ overflow: auto;
+ border: 1px solid #e6e6e6;
+}
+.scroll-ie {
+ overflow-x: hidden;
+ padding-right: 17px;
+}
+.red {
+ color: #8B0000;
+}
+.green {
+ color: #050;
+}
+ul.bullet {
+ margin: 3px 0 3px 25px;
+}
+ul.bullet li {
+ padding: 2px 0;
+ list-style-image: url("../images/bullet.png?da7c8093227679496892e74f2dfd8d58");
+}
+.rule_title {
+ font-size: 110%}
+.tablinks {
+ float: right;
+ padding: 0 5px 0 10px;
+ text-align: right;
+}
+.tablinks li {
+ float: left;
+ text-align: right;
+ margin-left: 5px;
+ padding: 0 0 0 5px;
+}
+.tablinks li.first {
+ background: 0 0;
+}
+.tablinks a {
+ text-decoration: underline;
+ color: #777;
+ font-size: 85%}
+.tabs-panel {
+ border-right: 1px solid #DDD;
+ border-bottom: 1px solid #DDD;
+ border-left: 1px solid #DDD;
+ border-top-width: 0;
+ padding: 10px;
+}
+.tabs2, .tabs {
+ height: 20px;
+ border-bottom: 1px solid #DDD;
+ margin: 0;
+ padding: 0;
+ font-size: 93%}
+.tabs2 li, .tabs li {
+ display: inline;
+ list-style-type: none;
+ font-weight: 400;
+ color: #777;
+ vertical-align: baseline;
+ white-space: nowrap;
+ margin: 0;
+ border: 0;
+ padding: 0;
+}
+.tabs2 li a, .tabs li a {
+ float: left;
+ color: #777;
+ vertical-align: bottom;
+ height: 17px;
+ margin: 0 1px 0 0;
+ padding: 1px 5px;
+ border-bottom: none;
+}
+.tabs2 li a.selected, .tabs li a.selected, .tabs .ui-tabs-active a {
+ text-decoration: none;
+ color: #555!important;
+ font-weight: 700;
+ margin: 0 1px 0 0;
+}
+.tabbed {
+ border: 1px solid silver;
+ border-top: 0;
+ padding: 5px;
+}
+.comments {
+ color: #777;
+ font-size: 12px;
+ margin-bottom: 10px;
+ padding: 4px;
+}
+.little {
+ font-size: 80%}
+.tooltip {
+ position: absolute;
+ background-color: #CAE3F2;
+ border: 1px solid #4b9fd5;
+ max-width: 480px;
+ text-align: left;
+ color: #262626;
+}
+.tooltip .content {
+ color: #111;
+ padding: 4px;
+}
+.tooltip .title {
+ color: #111;
+ font-weight: 700;
+ font-size: 100%;
+ padding: 2px 4px;
+}
+.tooltip td {
+ margin: 0;
+ padding: 2px;
+}
+.tooltip p {
+ margin: 0;
+ padding: 0;
+}
+.alert_WARN {
+ background-color: #f90;
+ color: #fff;
+ margin: 0;
+ padding: 0 3px;
+}
+a>.alert_WARN {
+ margin-bottom: -1px;
+ border-bottom: 1px solid #f90;
+ transition: all .2s ease;
+}
+a>.alert_WARN:hover {
+ opacity: .8;
+}
+.alert_ERROR {
+ background-color: #d4333f;
+ color: #fff;
+ margin: 0;
+ padding: 0 3px;
+}
+a>.alert_ERROR {
+ margin-bottom: -1px;
+ border-bottom: 1px solid #d4333f;
+ transition: all .2s ease;
+}
+a>.alert_ERROR:hover {
+ opacity: .8;
+}
+#comparison span.best {
+ font-size: 108%;
+ font-weight: 700;
+}
+.gwt-TabBar {
+ font-size: 93%;
+ width: 100%;
+ border-bottom: 1px solid #cdcdcd;
+}
+.gwt-TabBarFirst {
+ width: 0;
+}
+.gwt-TabBar .gwt-TabBarItem {
+ cursor: pointer;
+ font-weight: 400;
+ text-decoration: underline;
+ color: #555;
+ background-color: #EFEFEF;
+ vertical-align: middle;
+ white-space: nowrap;
+ padding: .3em .6em;
+ border: 1px solid #cdcdcd;
+ border-bottom: none;
+ border-radius: 4px 4px 0 0;
+ -moz-border-radius: 4px 4px 0 0;
+ -webkit-border-radius: 4px 4px 0 0;
+}
+.gwt-TabBar .gwt-TabBarItem-wrapper {
+ padding: 0 0 0 1px;
+}
+.gwt-TabBar .gwt-TabBarItem-selected {
+ cursor: default;
+ font-weight: 700;
+ text-decoration: underline;
+ color: #efefef;
+ background-color: #4B9FD5;
+ border-bottom: none;
+ vertical-align: middle;
+ white-space: nowrap;
+ padding: .3em .6em;
+}
+.gwt-TabPanelBottom {
+ width: 100%}
+.markdown-tips {
+ font-size: 12px;
+ color: #777;
+}
+.rule-desc h2 {
+ margin-top: 16px;
+ font-size: 16px;
+ line-height: 1.5;
+ color: #444;
+}
+.rule-desc h3 {
+ margin-top: 16px;
+ font-size: 12px;
+ line-height: 1.5;
+ color: #444;
+ font-weight: 700;
+}
+.rule-desc p, .property p {
+ margin-top: 10px;
+}
+.rule-desc pre, .property pre, .bubble-popup pre, .coding-rules-detail-parameter pre {
+ margin: 10px 0!important;
+ padding: 10px!important;
+ border: 1px dashed #aaa;
+ font-size: 12px;
+ font-family: monospace;
+}
+.rule-desc blockquote, .property blockquote, .bubble-popup blockquote, .coding-rules-detail-parameter blockquote {
+ margin-top: 10px;
+ padding: 10px;
+}
+.rule-desc ul, .property ul {
+ list-style-type: disc;
+ list-style-position: inside;
+ margin: 10px;
+}
+.rule-desc ol, .property ol {
+ list-style-type: decimal;
+ list-style-position: inside;
+ margin: 10px;
+}
+.rule-table {
+ margin-top: 10px;
+ overflow-x: auto;
+ border-collapse: collapse;
+}
+.rule-table th {
+ background: none no-repeat scroll right center #efefef;
+ border: 1px solid #DDD;
+ padding: 5px 10px;
+ font-weight: 700;
+}
+.rule-table td {
+ background: none no-repeat scroll right center transparent;
+ border: 1px solid #DDD;
+ padding: 5px 10px;
+}
+.tip:hover {
+ background: #FFF;
+ position: relative;
+ z-index: 100;
+}
+.tip span {
+ display: none;
+ margin-left: -20px;
+ padding: 4px 5px;
+}
+.tip:hover span {
+ display: inline;
+ position: absolute;
+ background: #CAE3F2;
+ border: 1px solid #4b9fd5;
+ color: #262626;
+ white-space: nowrap;
+ text-decoration: none;
+}
+.hbar {
+ float: left;
+ border: none;
+ clear: both;
+ width: 4em;
+ margin: 0;
+ padding: 2px 0 0;
+}
+.hbar li {
+ background-color: #777;
+ color: #FFF;
+ font-family: Verdana, Tahoma, Arial, sans-serif;
+ font-size: xx-small;
+ letter-spacing: -.075em;
+ list-style: none;
+ line-height: 1.1em;
+ text-align: right;
+ vertical-align: middle;
+ padding: .1em;
+}
+div.barchart {
+ border: 0;
+ margin: 0;
+ padding: 0;
+ float: left;
+}
+div.barchart>div {
+ background-color: #236a97;
+ height: .9em;
+}
+table.matrix thead {
+ background-color: #CAE3F2;
+ border: 1px solid #4b9fd5;
+}
+table.matrix thead th {
+ text-align: right;
+ border-right: 1px solid #4b9fd5;
+ padding: 4px 5px;
+}
+table.matrix tbody td {
+ border: 1px solid #ddd;
+ margin: 0;
+ padding: 4px 5px;
+}
+table.matrix tbody td.title {
+ border: none;
+ font-weight: 700;
+ margin: 0;
+ padding: 5px 0 0 5px;
+}
+a.nolink {
+ border-bottom: none;
+}
+h1 strong, .dashbox .title, .gwt-SourcePanel .sources .msg li strong {
+ font-weight: 700;
+}
+h4 a, h4 a:visited, .gray {
+ color: #777;
+}
+.even, table.sortable tr.rowodd {
+ background-color: #f5f5f5;
+}
+.bordered {
+ border-bottom: 1px solid #ddd;
+}
+table.data, table.spaced, .gwt-SourcePanel .sources {
+ width: 100%}
+table.data td.barchart {
+ width: 100px;
+}
+table.without-header {
+ border-top: 1px solid #ddd;
+}
+.hoverable.selected a {
+ color: #fff;
+}
+.gwt-SourcePanel .sources td {
+ vertical-align: top;
+}
+.line-block {
+ display: block;
+ width: 100%;
+ height: 24px;
+ line-height: 22px;
+ margin-bottom: 5px;
+}
+.line-info {
+ background: url("../images/information.png?441b7712b4c687fd869663595f2d2841") no-repeat scroll left 50% transparent;
+ padding-left: 18px;
+}
+div.break10 {
+ height: 10px;
+}
+div.break30 {
+ height: 30px;
+}
+.marginbottom10 {
+ margin-bottom: 10px;
+}
+.marginbottom5 {
+ margin-bottom: 5px;
+}
+.marginright10 {
+ margin-right: 10px;
+}
+.marginleft10 {
+ margin-left: 10px;
+}
+.width100 {
+ width: 100%}
+ul.horizontal {
+ list-style-type: none;
+}
+ul.horizontal li {
+ float: left;
+ position: relative;
+}
+table.nowrap td, td.nowrap, th.nowrap {
+ white-space: nowrap;
+}
+table.nowrap td.small, td.nowrap.small, th.nowrap.small {
+ line-height: 16px;
+}
+.background-gray {
+ background-color: #EFEFEF;
+ color: #444;
+}
+.bulk-edit {
+ display: block;
+ padding: 2px 0 2px 2px;
+}
+.csv {
+ display: block;
+ background: url("../images/csv.png?275d8839c05801c18013f3ec706d30bc") no-repeat scroll left 50% transparent;
+ padding: 2px 0 2px 20px;
+}
+.add {
+ display: block;
+ background: url("../images/add.png?4ea982641458a260ca3bc0575b5c687e") no-repeat scroll left 50% transparent;
+ padding: 2px 0 2px 20px;
+}
+.restore {
+ display: block;
+ background: url("../images/restore.gif?cbdc69992987d3ee037585b955cff796") no-repeat scroll left 50% transparent;
+ padding: 2px 0 2px 20px;
+}
+.compare {
+ display: block;
+ background: url("../images/compare.png?36ad68e78b5c90f3a75e1017d60618d0") no-repeat scroll left 50% transparent;
+ padding: 2px 0 2px 20px;
+}
+.diffParam {
+ font-family: 'Bitstream Vera Sans Mono', Courier, monospace;
+}
+.yellowHighlight {
+ background: #FFFBCC;
+}
+.link-action {
+ color: #236a97;
+ outline: 0;
+ text-decoration: none;
+ transition: all .2s ease;
+ border-bottom: 1px solid #cae3f2;
+}
+.link-action:hover {
+ color: #4b9fd5;
+}
+.link-action:active, .link-action:focus {
+ color: #236a97;
+}
+.link-action.link-red {
+ color: #d4333f;
+ border-bottom-color: #d49f98;
+}
+.link-action.link-red:hover, .link-action.link-red:active, .link-action.link-red:focus {
+ color: #d4333f;
+ border-bottom-color: #d4333f;
+}
+.link-red {
+ color: #d4333f!important;
+}
+.link-more {
+ background-image: url("../images/bullet_arrow_down.png?66181fb292ee9928a30e1777a8e6ad28");
+ background-repeat: no-repeat;
+ padding-right: 20px;
+ background-position: right center;
+ cursor: pointer;
+}
+.dropdown {
+ cursor: pointer;
+ display: inline-block;
+ text-decoration: none!important;
+ zoom: 1;
+ *display: inline;
+}
+.dropdown-menu {
+ background-clip: padding-box;
+ background-color: #FFF;
+ border: 1px solid #DDD;
+ box-shadow: 10px 10px 20px rgba(0, 0, 0, .5);
+ float: left;
+ margin: 0;
+ max-width: 220px;
+ min-width: 160px;
+ padding: 0;
+ position: absolute;
+ z-index: 1000;
+}
+.dropdown-menu h2 {
+ padding: 0 8px;
+ font-size: 100%;
+ font-weight: 700;
+}
+.dropdown-menu li {
+ list-style-type: none!important;
+ line-height: 24px;
+ height: 24px;
+ padding: 0 8px;
+ cursor: pointer!important;
+ float: none!important;
+}
+.dropdown-menu li:hover {
+ background-color: #cae3f2!important;
+}
+.dropdown-menu a {
+ text-decoration: none!important;
+ border-bottom: none!important;
+ color: #444!important;
+}
+.form-key-cell {
+ padding: 2px 8px 4px 10px;
+ text-align: right;
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: top;
+}
+.form-val-cell {
+ padding: 2px 8px 4px 0;
+ text-align: left;
+ white-space: normal;
+}
+.form-val-cell li {
+ margin-bottom: 5px;
+}
+.form-val-note {
+ color: #999;
+}
+blockquote {
+ border-left: 3px solid #E5E5E5;
+ padding: 0 8px;
+ line-height: 16px;
+}
+blockquote cite {
+ line-height: 16px;
+ background-image: url("../images/reviews/comment.png?dbcb8faed1d503559cdfc5ab6cee060e");
+ background-repeat: no-repeat;
+ padding-left: 20px;
+ background-position: left center;
+ font-size: 12px;
+ color: #888;
+}
+.spacer-left {
+ margin-left: 8px;
+}
+.spacer-right {
+ margin-right: 8px;
+}
+.spacer-bottom {
+ margin-bottom: 8px;
+}
+.spacer-top {
+ margin-top: 8px;
+}
+td.spacer-left {
+ padding-left: 8px;
+}
+td.spacer-right {
+ padding-right: 8px;
+}
+td.spacer-bottom {
+ padding-bottom: 8px;
+}
+td.spacer-top {
+ padding-top: 8px;
+}
+.bordered {
+ border: 1px solid #DDD;
+}
+.bordered-left {
+ border-left: 1px solid #DDD;
+}
+.bordered-right {
+ border-right: 1px solid #DDD;
+}
+.bordered-bottom {
+ border-bottom: 1px solid #DDD;
+}
+.bordered-top {
+ border-top: 1px solid #DDD;
+}
+.table>thead>tr>th {
+ border-top: 0 none;
+ font-weight: 700;
+ line-height: 16px;
+ padding: 4px 5px;
+ vertical-align: bottom;
+}
+.table>tbody>tr>td {
+ line-height: 16px;
+ padding: 4px 5px;
+ vertical-align: top;
+}
+.table>tfoot>tr>td {
+ font-size: 93%;
+ color: #777;
+ padding: 4px 5px;
+}
+.table>tfoot>tr>td a {
+ color: #777;
+}
+.table-bordered>tbody {
+ border-left: 1px solid #DDD;
+ border-right: 1px solid #DDD;
+ border-bottom: 1px solid #DDD;
+}
+.table-bordered>tbody>tr>td {
+ border-top: 1px solid #DDD;
+}
+select.small-width {
+ max-width: 120px;
+}
+select.medium-width {
+ max-width: 175px;
+ width: 175px;
+}
+.modal-head {
+ padding: 0 10px;
+ background-color: #EFEFEF;
+ border-bottom: 1px solid #DDD;
+}
+.modal-head h1, .modal-head h2 {
+ line-height: 30px;
+ min-height: 30px;
+}
+ul.modal-head-metadata {
+ overflow: hidden;
+ padding: 0 0 5px;
+}
+ul.modal-head-metadata li {
+ float: left;
+ position: relative;
+ font-size: 85%;
+ color: #777;
+}
+.modal-body {
+ padding: 10px;
+}
+.modal-body-select2 {
+ margin-bottom: 10px;
+}
+.modal-body .notes {
+ height: auto;
+}
+.modal-field {
+ clear: both;
+ display: block;
+ padding: 5px 0 5px 130px;
+}
+.modal-field label {
+ display: block;
+ float: left;
+ text-align: right;
+ width: 130px;
+ left: -140px;
+ margin-right: -130px;
+ line-height: 1;
+ word-wrap: break-word;
+ position: relative;
+ padding-top: 5px;
+}
+.modal-field label.simple-label {
+ display: inline-block;
+ vertical-align: middle;
+ float: none;
+ position: static;
+ margin: 0 0 0 -5px;
+ padding: 0;
+ text-align: left;
+}
+.readonly-field {
+ padding-top: 5px;
+ margin-left: -5px;
+ line-height: 1;
+}
+.modal-field input {
+ margin-right: 5px;
+ margin-bottom: 10px;
+}
+.modal-field input[type=text], .modal-field input[type=password], .modal-field textarea {
+ width: 250px;
+}
+.modal-field .text {
+ line-height: 20px;
+}
+.modal-foot {
+ text-align: right;
+ padding: 2px 10px;
+ border-top: 1px solid #CCC;
+ line-height: 30px;
+ height: 30px;
+ background-color: #EFEFEF;
+}
+.modal-foot input {
+ margin-right: 10px;
+}
+.modal-field-description {
+ clear: both;
+ font-size: 93%;
+ color: #777;
+}
+.modal-error, .modal-warning, .modal-notice {
+ display: none;
+}
+textarea.width100 {
+ width: 100%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.property {
+ margin-bottom: 10px;
+}
+.property h3 {
+ float: none;
+ max-width: 20em;
+}
+.property>th, .property>td {
+ vertical-align: top;
+ padding: 10px;
+}
+.property>th {
+ text-align: right;
+}
+.property table.data {
+ width: 480px;
+}
+.property textarea {
+ vertical-align: text-top;
+}
+.property .note {
+ margin-top: 5px;
+}
+.accordion-item {
+ border: 1px solid #e6e6e6;
+ margin-bottom: 20px;
+}
+.accordion-item table.data {
+ border-collapse: separate;
+}
+.accordion-item-body-medium {
+ max-height: 200px;
+ overflow: auto;
+}
+.rule-search {
+ display: inline-block;
+ line-height: 16px;
+}
+div.rule-title {
+ display: inline-block;
+ float: left;
+ clear: right;
+}
+#result_table .rule-desc {
+ width: 100%;
+ float: left;
+ clear: right;
+}
+.rule-status, .rule-tags {
+ display: inline-block;
+ margin-left: 10px;
+ float: right;
+ padding: 3px 5px 0 0;
+ font-size: 85%;
+ color: #777;
+}
+.rule-tags a {
+ color: inherit;
+ text-decoration: none;
+}
+.rule-status span {
+ text-transform: uppercase;
+}
+.rule-tags span {
+ background-color: #eee;
+ padding: 3px 4px;
+ margin: 4px 2px;
+ border-radius: 2px;
+ box-shadow: 0 -1px 0 rgba(0, 0, 0, .12)inset;
+}
+.project-search {
+ display: inline-block;
+ line-height: 16px;
+ padding: 4px 2px;
+}
+.sonar-d3 .axis path {
+ fill: none;
+ stroke: #444;
+}
+.sonar-d3 .tick line {
+ stroke: #444;
+}
+.sonar-d3 .tick text {
+ fill: #444;
+}
+.sonar-d3 .plot {
+ transition: all .2s ease;
+}
+.sonar-d3 .plot:hover .arc, .sonar-d3 .plot.hover .arc {
+ opacity: .4;
+}
+.sonar-d3 .plot .arc:hover, .sonar-d3 .plot .arc.hover {
+ opacity: 1;
+}
+.sonar-d3 .plot .line {
+ fill: none;
+ stroke: #000;
+ stroke-width: 2;
+}
+.sonar-d3 .plot .line-marker {
+ fill: #fff;
+ stroke: #000;
+ stroke-width: 2;
+ opacity: 0;
+}
+.sonar-d3 .plot .scanner {
+ stroke: #000;
+ opacity: .25;
+}
+.sonar-d3 .arc, .sonar-d3 .bar rect {
+ cursor: pointer;
+ stroke: #fff;
+ stroke-width: 1px;
+ transition: all .2s ease;
+}
+.sonar-d3 .bar, .sonar-d3 .bar .legend-text, .sonar-d3 .pie-legend, .sonar-d3 .pie-legend .legend-text {
+ cursor: pointer;
+}
+.sonar-d3 .legend-bullet {
+ transition: all .2s ease;
+}
+.sonar-d3 .legend-text {
+ font-size: 12px;
+ cursor: default;
+}
+.sonar-d3 .legend-active .legend-bullet {
+ -webkit-transform: scale(1.4);
+ -webkit-transform-origin: center;
+}
+.sonar-d3 .legend-html {
+ margin-bottom: 10px;
+ color: #777;
+}
+.sonar-d3 .legend-html .legend-text+.legend-text {
+ margin-left: 15px;
+}
+.sonar-d3 .legend-html .legend-text-main {
+ font-weight: 500;
+}
+.sonar-d3 .details-color-indicator {
+ fill: #fff;
+ transition: fill .2s ease;
+}
+.sonar-d3 .details-metric {
+ font-size: 12px;
+}
+.sonar-d3 .details-metric-main {
+ font-weight: 700;
+}
+.sonar-d3 .info-text {
+ font-size: 13px;
+}
+.sonar-d3 .info-text-bold {
+ font-weight: 700;
+}
+.sonar-d3 .info-text-small {
+ font-size: 12px;
+}
+.sonar-d3 .event-tick {
+ fill: none;
+ stroke: #000;
+ stroke-width: 1px;
+ transition: all .3s ease;
+}
+.sonar-d3.cloud-widget {
+ text-align: center;
+}
+.sonar-d3 .cloud-word {
+ display: inline-block;
+ vertical-align: baseline;
+ white-space: nowrap;
+ margin-right: 14px;
+ text-decoration: none;
+ border-bottom: 1px solid transparent;
+}
+.sonar-d3 .cloud-word:hover {
+ border-bottom: 1px solid;
+}
+.sonar-d3 .max-results-reached-message {
+ font-size: 12px;
+}
+.sonar-d3 div.max-results-reached-message {
+ margin-top: 10px;
+ color: #777;
+ text-align: center;
+}
+.sonar-d3 text.max-results-reached-message {
+ fill: #777;
+}
+.sonar-d3 .treemap-container {
+ position: relative;
+}
+.sonar-d3 .treemap-cell {
+ position: absolute;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ text-align: center;
+}
+.sonar-d3 .treemap-cell-drilldown {
+ cursor: pointer;
+ transition: opacity .2s ease;
+}
+.sonar-d3 .treemap-cell-drilldown:hover {
+ opacity: .8;
+}
+.sonar-d3 .treemap-inner {
+ display: inline-block;
+ vertical-align: middle;
+ line-height: 1.2;
+ padding: 5px;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ color: #fff;
+ font-weight: 300;
+ text-align: left;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.sonar-d3 .treemap-link {
+ position: absolute;
+ z-index: 2;
+ top: 5px;
+ right: 5px;
+ line-height: 14px;
+ color: #fff;
+ opacity: .5;
+ border-bottom: none;
+}
+.sonar-d3 .treemap-link:hover {
+ opacity: 1;
+}
+.sonar-d3 .treemap-link i, .sonar-d3 .treemap-link i:before {
+ vertical-align: top;
+ font-size: inherit;
+ line-height: inherit;
+}
+.sonar-d3 .treemap-cell-small .treemap-inner {
+ display: none;
+}
+.sonar-d3 .treemap-cell-very-small .treemap-inner {
+ display: none;
+}
+.sonar-d3 .treemap-cell-very-small .treemap-link {
+ display: none;
+}
+.sonar-d3 .treemap-breadcrumbs {
+ margin-top: 10px;
+ padding-top: 7px;
+ border-top: 1px solid #E6E6E6;
+}
+.sonar-d3 .treemap-breadcrumbs-item {
+ color: #777;
+}
+.sonar-d3 .treemap-breadcrumbs-item>[class^=icon-qualifier-] {
+ margin-right: 4px;
+}
+.sonar-d3 .treemap-breadcrumbs-item+.treemap-breadcrumbs-item {
+ margin-left: 10px;
+}
+.sonar-d3 .treemap-breadcrumbs-item+.treemap-breadcrumbs-item>.icon-chevron-right {
+ margin-right: 10px;
+}
+.admin-page-title {
+ margin-bottom: 0;
+}
+.admin-page-description {
+ font-size: 85%;
+ font-weight: 400;
+ margin-bottom: 25px;
+}
+.bubble-popup {
+ position: absolute;
+ z-index: 100;
+ margin-top: -16px;
+ margin-left: 8px;
+ padding: 10px;
+ border: 1px solid #e6e6e6;
+ border-radius: 3px;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ background-color: #fff;
+ box-shadow: 10px 10px 20px rgba(0, 0, 0, .5);
+}
+.bubble-popup-arrow, .bubble-popup-arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border: 8px solid transparent;
+}
+.bubble-popup-arrow {
+ top: 15px;
+ left: -8px;
+ border-left-width: 0;
+ border-right-color: #e6e6e6;
+}
+.bubble-popup-arrow:after {
+ content: " ";
+ left: 1px;
+ bottom: -8px;
+ border-left-width: 0;
+ border-right-color: #fff;
+}
+.bubble-popup-bottom {
+ margin-top: 8px;
+ margin-left: -16px;
+}
+.bubble-popup-bottom .bubble-popup-arrow {
+ top: -8px;
+ left: 15px;
+ border-left-width: 8px;
+ border-top-width: 0;
+ border-right-color: transparent;
+ border-bottom-color: #e6e6e6;
+}
+.bubble-popup-bottom .bubble-popup-arrow:after {
+ left: -8px;
+ bottom: -9px;
+ border-left-width: 8px;
+ border-top-width: 0;
+ border-right-color: transparent;
+ border-bottom-color: #fff;
+}
+.bubble-popup-bottom-right {
+ margin-top: 8px;
+ margin-left: -16px;
+ margin-left: 0;
+ margin-right: -8px;
+}
+.bubble-popup-bottom-right .bubble-popup-arrow {
+ top: -8px;
+ left: 15px;
+ border-left-width: 8px;
+ border-top-width: 0;
+ border-right-color: transparent;
+ border-bottom-color: #e6e6e6;
+}
+.bubble-popup-bottom-right .bubble-popup-arrow:after {
+ left: -8px;
+ bottom: -9px;
+ border-left-width: 8px;
+ border-top-width: 0;
+ border-right-color: transparent;
+ border-bottom-color: #fff;
+}
+.bubble-popup-bottom-right .bubble-popup-arrow {
+ left: auto;
+ right: 15px;
+}
+.bubble-popup-container {
+ max-width: 560px;
+ max-height: 300px;
+ overflow: auto;
+}
+.bubble-popup-title {
+ margin-bottom: 5px;
+ font-weight: 600;
+}
+.bubble-popup-section {
+ width: 450px;
+ padding-bottom: 2px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.bubble-popup-section.fluid {
+ width: auto;
+ max-width: 450px;
+}
+.bubble-popup-section+.bubble-popup-section, .bubble-popup-section+.bubble-popup-title {
+ margin-top: 10px;
+}
+.bubble-popup-list {
+ margin-top: 5px;
+}
+.bubble-popup-list>li {
+ padding: 2px 0;
+}
+@font-face {
+ font-family: sonar;
+ src: url("../fonts/sonar.eot??528bf402310afebac23d469d3ca3329a");
+ src: url("../fonts/sonar.eot?#iefix?528bf402310afebac23d469d3ca3329a") format('embedded-opentype'), url("../fonts/sonar.woff??092aa12b52e10b720f58185b9a0a4979") format('woff'), url("../fonts/sonar.ttf??403688ec2ef4aa8a613b29d3ced24d75") format('truetype'), url("../fonts/sonar.svg?#sonar?1e882586786bb43a2d60d232dabb3a1f") format('svg');
+ font-weight: 400;
+ font-style: normal;
+}
+[class^=icon-], [class*=" icon-"] {
+ font-family: sonar;
+ speak: none;
+ font-style: normal;
+ font-weight: 400;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+ vertical-align: middle;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+a[class^=icon-], a[class*=" icon-"] {
+ border-bottom: none;
+}
+.icon-black {
+ color: #444;
+}
+.icon-red {
+ color: #d4333f;
+}
+.icon-green {
+ color: #85bb43;
+}
+[class^=icon-severity-], [class*=" icon-severity"] {
+ position: relative;
+ top: -1px;
+}
+.icon-severity-blocker:before, .icon-severity-4:before {
+ content: "\f000";
+ color: #d4333f;
+ font-size: 14px;
+}
+.icon-severity-critical:before, .icon-severity-3:before {
+ content: "\f001";
+ color: #d4333f;
+ font-size: 14px;
+}
+.icon-severity-major:before, .icon-severity-2:before {
+ content: "\f003";
+ color: #d4333f;
+ font-size: 14px;
+}
+.icon-severity-minor:before, .icon-severity-1:before {
+ content: "\f006";
+ color: #85bb43;
+ font-size: 14px;
+}
+.icon-severity-info:before, .icon-severity-0:before {
+ content: "\f004";
+ color: #85bb43;
+ font-size: 14px;
+}
+[class^=icon-status-], [class*=" icon-status"] {
+ position: relative;
+ top: -1px;
+}
+.icon-status-open:before {
+ content: "\f010";
+ color: #4b9fd5;
+ font-size: 14px;
+ line-height: 12px;
+}
+.icon-status-confirmed:before {
+ content: "\f011";
+ color: #4b9fd5;
+ font-size: 14px;
+ line-height: 12px;
+}
+.icon-status-reopened:before {
+ content: "\f012";
+ color: #4b9fd5;
+ font-size: 14px;
+ line-height: 12px;
+}
+.icon-status-resolved:before {
+ content: "\f013";
+ color: #444;
+ font-size: 14px;
+ line-height: 12px;
+}
+.icon-status-closed:before {
+ content: "\f014";
+ color: #444;
+ font-size: 14px;
+ line-height: 12px;
+}
+.icon-test-status-ok:before {
+ content: "\f013";
+ color: #85bb43;
+ font-size: 16px;
+}
+.icon-test-status-failure:before {
+ content: "\f000";
+ color: #f90;
+ font-size: 16px;
+}
+.icon-test-status-error:before {
+ content: "\f057";
+ color: #d4333f;
+ font-size: 16px;
+}
+.icon-test-status-skipped:before {
+ content: "\f056";
+ color: #b4b4b4;
+ font-size: 16px;
+}
+.icon-alert-ok:before {
+ content: "\f013";
+ color: #85bb43;
+ font-size: 16px;
+}
+.icon-alert-warn:before {
+ content: "\f000";
+ color: #f90;
+ font-size: 16px;
+}
+.icon-alert-error:before {
+ content: "\f057";
+ color: #d4333f;
+ font-size: 16px;
+}
+.icon-alert-none:before {
+ content: "\f056";
+ color: #b4b4b4;
+ font-size: 16px;
+}
+[class^=icon-qualifier-], [class*=" icon-qualifier-"] {
+ position: relative;
+ top: -1px;
+ color: #444;
+ font-size: 16px;
+ text-shadow: 0 1px 0 #fff;
+}
+.icon-qualifier-dir:before, .icon-qualifier-pac:before {
+ content: "\f114"}
+.icon-qualifier-trk:before, .icon-qualifier-brc:before, .icon-qualifier-dev_prj:before {
+ content: "\e600"}
+.icon-qualifier-cla:before, .icon-qualifier-fil:before {
+ content: "\f0f6"}
+.icon-qualifier-uts:before {
+ content: "\e602"}
+.icon-qualifier-lib:before {
+ content: "\e604"}
+.icon-qualifier-vw:before, .icon-qualifier-svw:before {
+ content: "\e608"}
+.icon-qualifier-dev:before {
+ content: "\e60a"}
+.icon-qualifier-dir:before, .icon-qualifier-pac:before {
+ color: #f90;
+}
+.icon-qualifier-cla:before, .icon-qualifier-fil:before, .icon-qualifier-trk:before, .icon-qualifier-brc:before, .icon-qualifier-uts:before, .icon-qualifier-lib:before, .icon-qualifier-vw:before, .icon-qualifier-svw:before, .icon-qualifier-dev:before, .icon-qualifier-dev_prj:before {
+ color: #2d87c0;
+}
+[class^=icon-trend-], [class*=" icon-trend-"] {
+ position: relative;
+ top: -1px;
+ font-size: 14px;
+}
+.icon-trend-big {
+ font-size: 16px;
+}
+.icon-trend-0:before {
+ content: "\e607"}
+.icon-trend-1:before {
+ content: "\e605"}
+.icon-trend--1:before {
+ content: "\e601"}
+.icon-trend-2:before {
+ content: "\e606"}
+.icon-trend--2:before {
+ content: "\e603"}
+.icon-checkbox {
+ position: relative;
+ top: -1px;
+ color: #777;
+ font-size: 16px;
+}
+.icon-checkbox:before {
+ content: "\e60c"}
+.icon-checkbox-checked:after {
+ color: #4b9fd5;
+}
+.icon-checkbox-checked:after {
+ content: "\e60d";
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+.icon-checkbox-checked.icon-checkbox-single:after {
+ content: "\e60e"}
+.icon-checkbox-invisible {
+ visibility: hidden;
+}
+.icon-list:before {
+ content: "\f039"}
+.icon-bullet-list:before {
+ content: "\f03a"}
+.icon-settings:before {
+ content: "\f015"}
+.icon-bulk-change:before {
+ content: "\f085";
+ font-size: 16px;
+}
+.icon-arrow-down:before {
+ content: "\f0d7";
+ position: relative;
+ top: -2px;
+}
+.icon-arrow-up:before {
+ content: "\f0d8";
+ position: relative;
+ top: -2px;
+}
+.icon-arrow-left:before {
+ content: "\f0d9"}
+.icon-arrow-right:before {
+ content: "\f0da"}
+.icon-dropdown:before {
+ content: "\f0d7";
+ position: relative;
+ top: -1px;
+}
+.icon-sort-desc:before {
+ content: "\f0d7";
+ position: relative;
+ top: -1px;
+}
+.icon-sort-asc:before {
+ content: "\f0d8";
+ position: relative;
+ top: -1px;
+}
+.icon-emoticon-smiley:before {
+ content: "\f118"}
+.icon-emoticon-sad:before {
+ content: "\f119"}
+.icon-emoticon-speechless:before {
+ content: "\f11a"}
+.icon-rect-check:before {
+ content: "\f046"}
+.icon-check:before {
+ content: "\f00c";
+ color: #85bb43;
+ font-size: 16px;
+}
+.icon-default:before {
+ position: relative;
+ top: -.1em;
+ content: "\f00c"}
+.icon-lang:before {
+ content: "\f024";
+ font-size: 14px;
+}
+.icon-quality-profile:before {
+ content: "\f022";
+ font-size: 14px;
+}
+.icon-tags:before {
+ content: "\f02c";
+ font-size: 14px;
+}
+.icon-calendar:before {
+ content: "\f073";
+ font-size: 16px;
+}
+.icon-favorite {
+ font-size: 16px;
+}
+.icon-favorite:before {
+ content: "\f005";
+ color: #f90;
+ font-size: 16px;
+}
+.icon-not-favorite {
+ font-size: 16px;
+}
+.icon-not-favorite:before {
+ content: "\f005";
+ color: #cdcdcd;
+ font-size: 16px;
+}
+.icon-help:before {
+ content: "\f059";
+ color: #4b9fd5;
+ font-size: 16px;
+}
+.icon-info:before {
+ content: "\f05a";
+ color: #4b9fd5;
+ font-size: 16px;
+}
+.icon-uniF060:before {
+ content: "\f060"}
+.icon-uniF061:before {
+ content: "\f061"}
+.icon-uniF062:before {
+ content: "\f062"}
+.icon-uniF063:before {
+ content: "\f063"}
+.icon-comment:before {
+ content: "\f075";
+ font-size: 14px;
+}
+.icon-delete:before {
+ content: "\f00d";
+ color: #d4333f;
+ font-size: 16px;
+}
+.icon-compare:before {
+ content: "\f0c5";
+ font-size: 14px;
+}
+.icon-restore:before {
+ content: "\f122";
+ font-size: 14px;
+}
+.icon-inheritance:before {
+ content: "\f126"}
+.icon-plus:before {
+ content: "\f067";
+ font-size: 16px;
+}
+.icon-link:before {
+ content: "\f127";
+ font-size: 14px;
+}
+.icon-move-down:before {
+ content: "\f063";
+ color: #236a97;
+ font-size: 16px;
+}
+.icon-move-up:before {
+ content: "\f062";
+ color: #236a97;
+ font-size: 16px;
+}
+.icon-move-left:before {
+ content: "\f060";
+ color: #236a97;
+ font-size: 16px;
+}
+.icon-move-right:before {
+ content: "\f061";
+ color: #236a97;
+ font-size: 16px;
+}
+.icon-scm:before {
+ content: "\f017";
+ font-size: 14px;
+}
+.icon-scm_dev:before {
+ content: "\f015";
+ font-size: 14px;
+}
+.icon-ci:before {
+ content: "\f021";
+ font-size: 14px;
+}
+.icon-issue:before {
+ content: "\f188";
+ font-size: 14px;
+}
+.icon-homepage:before {
+ content: "\f016";
+ font-size: 14px;
+}
+.icon-resizer:before {
+ content: "\f142";
+ color: #cdcdcd;
+ font-size: 16px;
+}
+.icon-expand:before {
+ content: "\e60b";
+ font-size: 16px;
+}
+.icon-period:before {
+ content: "\f018";
+ font-size: 16px;
+}
+.icon-filter:before {
+ content: "\f03a";
+ font-size: 16px;
+}
+.icon-detach:before {
+ content: "\f08e";
+ font-size: 14px;
+}
+.icon-chevron-left:before {
+ content: "\f104";
+ font-size: 14px;
+}
+.icon-chevron-right:before {
+ content: "\f105";
+ font-size: 14px;
+}
+.icon-double-chevron-left:before {
+ content: "\f100";
+ font-size: 14px;
+}
+.icon-double-chevron-right:before {
+ content: "\f101";
+ font-size: 14px;
+}
+.icon-extension:before {
+ content: "\f069";
+ font-size: 16px;
+}
+.icon-home:before {
+ content: "\f016";
+ font-size: 16px;
+}
+.spinner {
+ position: relative;
+ vertical-align: middle;
+ width: 16px;
+ height: 16px;
+ border: 2px solid #0cf;
+ border-radius: 50%;
+ -webkit-animation: spin .75s infinite linear;
+ animation: spin .75s infinite linear;
+}
+.ie9 .spinner {
+ background-image: url("../images/loading.gif?e2a9308e1360f28fb8fe7ad05eed2e38");
+ background-repeat: no-repeat;
+ background-position: 0 0;
+ border: none;
+}
+.spinner:before, .spinner:after {
+ left: -2px;
+ top: -2px;
+ display: none;
+ position: absolute;
+ content: '';
+ width: inherit;
+ height: inherit;
+ border: inherit;
+ border-radius: inherit;
+}
+.spinner, .spinner:before, .spinner:after {
+ display: inline-block;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ border-color: transparent;
+ border-top-color: #4b9fd5;
+ -webkit-animation-duration: 1.2s;
+ animation-duration: 1.2s;
+}
+.spinner:before {
+ -webkit-transform: rotate(120deg);
+ -ms-transform: rotate(120deg);
+ transform: rotate(120deg);
+}
+.spinner:after {
+ -webkit-transform: rotate(240deg);
+ -ms-transform: rotate(240deg);
+ transform: rotate(240deg);
+}
+.spinner-margin {
+ margin: 10px;
+}
+@-webkit-keyframes spin {
+ from {
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+}
+to {
+ -webkit-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ transform: rotate(360deg);
+}
+}@keyframes spin {
+ from {
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+}
+to {
+ -webkit-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ transform: rotate(360deg);
+}
+}@font-face {
+ font-family: Roboto;
+ src: url("../fonts/Roboto-Light-webfont.eot?efd91b453f819684984ca83fd8db381a");
+ src: url("../fonts/Roboto-Light-webfont.eot?#iefix?efd91b453f819684984ca83fd8db381a") format('embedded-opentype'), url("../fonts/Roboto-Light-webfont.woff?e2a80e99a7a0f73f9d5eb0a76c3291a2") format('woff'), url("../fonts/Roboto-Light-webfont.ttf?469c9049e5e80133a02a56c86a8b1e03") format('truetype'), url("../fonts/Roboto-Light-webfont.svg#robotolight?344300b18a23acb2504fbade4caceb01") format('svg');
+ font-weight: 300;
+ font-style: normal;
+}
+@font-face {
+ font-family: Roboto;
+ src: url("../fonts/Roboto-Regular-webfont.eot?b9c2d82a0eaf54330a07c7b29e7fa0f5");
+ src: url("../fonts/Roboto-Regular-webfont.eot?#iefix?b9c2d82a0eaf54330a07c7b29e7fa0f5") format('embedded-opentype'), url("../fonts/Roboto-Regular-webfont.woff?5e4fa07b945a148d5e5789709cae4210") format('woff'), url("../fonts/Roboto-Regular-webfont.ttf?76a334ee91f49c94df0f3676b6ed84cd") format('truetype'), url("../fonts/Roboto-Regular-webfont.svg#robotoregular?f9ede3e38f01dfdbf4902cdf626eaffb") format('svg');
+ font-weight: 400;
+ font-style: normal;
+}
+@font-face {
+ font-family: Roboto;
+ src: url("../fonts/Roboto-Medium-webfont.eot?6f2aff0dfddc7a7a5deff19f5d4197d5");
+ src: url("../fonts/Roboto-Medium-webfont.eot?#iefix?6f2aff0dfddc7a7a5deff19f5d4197d5") format('embedded-opentype'), url("../fonts/Roboto-Medium-webfont.woff?b1bf937b4340988b2886a8407d978ba4") format('woff'), url("../fonts/Roboto-Medium-webfont.ttf?5713ededcd04f2d4fb2e5c63f2a7b2c6") format('truetype'), url("../fonts/Roboto-Medium-webfont.svg#robotomedium?72f6bae64658cd141ce8c1cafd12791e") format('svg');
+ font-weight: 500;
+ font-style: normal;
+}
+@font-face {
+ font-family: Roboto;
+ src: url("../fonts/Roboto-Bold-webfont.eot?6813d1b15f40ce5c9897625c3e49d874");
+ src: url("../fonts/Roboto-Bold-webfont.eot?#iefix?6813d1b15f40ce5c9897625c3e49d874") format('embedded-opentype'), url("../fonts/Roboto-Bold-webfont.woff?c691a29cc74d0e4e35797a73dec6361c") format('woff'), url("../fonts/Roboto-Bold-webfont.ttf?efde55770658360bdc459dfc334ac845") format('truetype'), url("../fonts/Roboto-Bold-webfont.svg#robotobold?1dc03cd3af72747bc130840b97611d44") format('svg');
+ font-weight: 700;
+ font-style: normal;
+}
+body {
+ font-family: Roboto, 'Helvetica Neue', Helvetica, Arial, sans-serif;
+}
+select, input, button, textarea {
+ font-size: 99%;
+ font-family: Roboto, 'Helvetica Neue', Helvetica, Arial, sans-serif;
+}
+select::-moz-focus-inner, input::-moz-focus-inner, button::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+.nowrap {
+ white-space: nowrap;
+}
+.text-ellipsis {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.justify {
+ margin-bottom: -1em;
+ text-align: justify;
+}
+.justify>.ib {
+ display: inline-block;
+}
+.justify:after {
+ display: inline-block;
+ width: 100%;
+ content: " "}
+.no-transform {
+ text-transform: none;
+}
+.base-link {
+ color: #444;
+ outline: 0;
+ text-decoration: none;
+ transition: all .2s ease;
+}
+.base-link:hover {
+ color: #4b9fd5;
+}
+.base-link:active, .base-link:focus {
+ color: #236a97;
+}
+.icon-with-link {
+ outline: 0;
+ text-decoration: none;
+}
+.widget-link {
+ color: #236a97;
+ outline: 0;
+ text-decoration: none;
+ transition: all .2s ease;
+ border-bottom: 1px solid #cae3f2;
+}
+.widget-link:hover {
+ color: #4b9fd5;
+}
+.widget-link:active, .widget-link:focus {
+ color: #236a97;
+}
+.widget-link-red {
+ color: #d4333f;
+ border-bottom-color: #d49f98;
+}
+.widget-link-red:hover, .widget-link-red:active, .widget-link-red:focus {
+ color: #d4333f;
+ border-bottom-color: #d4333f;
+}
+.link-no-underline {
+ border-bottom: none;
+}
+a {
+ cursor: pointer;
+ color: #236a97;
+ outline: 0;
+ text-decoration: none;
+ transition: all .2s ease;
+ border-bottom: 1px solid #cae3f2;
+}
+a:hover {
+ color: #4b9fd5;
+}
+a:active, a:focus {
+ color: #236a97;
+}
+a.link-red {
+ color: #d4333f;
+ border-bottom-color: #d49f98;
+}
+a.link-red:hover, a.link-red:active, a.link-red:focus {
+ color: #d4333f;
+ border-bottom-color: #d4333f;
+}
+a.active-link {
+ border-bottom: none;
+ font-weight: 500;
+}
+input[type=text], input[type=password], input[type=email], textarea {
+ border: 1px solid #cdcdcd;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ background: #fff;
+ color: #444;
+ transition: border-color .2s ease;
+}
+input[type=text]:active, input[type=password]:active, input[type=email]:active, textarea:active, input[type=text]:focus, input[type=password]:focus, input[type=email]:focus, textarea:focus {
+ border-color: #4b9fd5;
+ box-shadow: none;
+ outline: 0;
+}
+input[type=text].invalid, input[type=password].invalid, input[type=email].invalid, textarea.invalid {
+ border-color: #d4333f;
+}
+input[type=text], input[type=password], input[type=email] {
+ height: 22px;
+ padding: 0 3px;
+}
+textarea {
+ padding: 3px;
+}
+button, .button, input[type=submit], input[type=button] {
+ display: inline-block;
+ vertical-align: baseline;
+ height: 22px;
+ margin: 0 1px;
+ padding: 0 10px;
+ border: 1px solid #cdcdcd;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ background: #f4f4f4;
+ color: #444;
+ font-weight: 700;
+ font-size: 13px;
+ text-align: center;
+ text-decoration: none;
+ cursor: pointer;
+ outline: 0;
+ transition: border-color .2s ease;
+}
+button:hover, .button:hover, input[type=submit]:hover, input[type=button]:hover, button.active, .button.active, input[type=submit].active, input[type=button].active {
+ border-color: #5281a0;
+ background: #4b9fd5;
+ color: #fff;
+}
+button:active, .button:active, input[type=submit]:active, input[type=button]:active {
+ border-color: #2790c0;
+ background: #78bdea;
+ color: #fff;
+}
+button:focus, .button:focus, input[type=submit]:focus, input[type=button]:focus {
+ border-color: #4b9fd5;
+}
+button[disabled], .button[disabled], input[type=submit][disabled], input[type=button][disabled], button[disabled]:hover, .button[disabled]:hover, input[type=submit][disabled]:hover, input[type=button][disabled]:hover, button[disabled]:active, .button[disabled]:active, input[type=submit][disabled]:active, input[type=button][disabled]:active, button[disabled]:focus, .button[disabled]:focus, input[type=submit][disabled]:focus, input[type=button][disabled]:focus {
+ color: #bbb;
+ border-color: #ddd;
+ background: #ebebeb;
+ cursor: default;
+}
+.button {
+ line-height: 22px;
+}
+.button-red:hover, .button-red:focus {
+ border-color: #900;
+ background: #c00;
+ color: #fff;
+}
+.button-red:active {
+ border-color: #900;
+ background: red;
+}
+.button-clean, .button-clean:hover, .button-clean:focus {
+ margin: 0;
+ padding: 0;
+ border: none;
+ background: 0 0;
+ color: #444;
+}
+.button-group {
+ display: inline-block;
+ vertical-align: middle;
+ font-size: 0;
+ white-space: nowrap;
+}
+.button-group>button, .button-group>.button {
+ position: relative;
+ z-index: 2;
+ display: inline-block;
+ vertical-align: middle;
+ margin: 0;
+ padding: 2px 8px;
+ font-size: 12px;
+ font-weight: 400;
+ cursor: pointer;
+}
+.button-group>button:hover, .button-group>.button:hover, .button-group>button:focus, .button-group>.button:focus, .button-group>button:active, .button-group>.button:active, .button-group>button.active, .button-group>.button.active {
+ z-index: 3;
+}
+.button-group>.button {
+ line-height: 16px;
+}
+.button-group>button+button, .button-group>button+.button, .button-group>.button+button, .button-group>.button+.button {
+ margin-left: -1px;
+}
+.button-group>a:not(.button) {
+ vertical-align: middle;
+ margin: 0 8px;
+ font-size: 12px;
+}
+.message-alert {
+ display: block;
+ padding: 5px 8px;
+ border: 2px solid #f90;
+}
+.message-error {
+ display: block;
+ padding: 5px 8px;
+ background-color: #d4333f;
+ color: #fff;
+}
+.markdown a {
+ color: #236a97;
+ outline: 0;
+ text-decoration: none;
+ transition: all .2s ease;
+ border-bottom: 1px solid #cae3f2;
+}
+.markdown a:hover {
+ color: #4b9fd5;
+}
+.markdown a:active, .markdown a:focus {
+ color: #236a97;
+}
+.markdown a.link-red {
+ color: #d4333f;
+ border-bottom-color: #d49f98;
+}
+.markdown a.link-red:hover, .markdown a.link-red:active, .markdown a.link-red:focus {
+ color: #d4333f;
+ border-bottom-color: #d4333f;
+}
+.rating {
+ display: inline-block;
+ width: 1em;
+ height: 1.3em;
+ line-height: 1.3;
+ color: #fff;
+ font-weight: 300;
+ text-align: center;
+}
+a>.rating {
+ margin-bottom: -1px;
+ border-bottom: 1px solid;
+ transition: all .2s ease;
+}
+a>.rating:hover {
+ opacity: .8;
+}
+.rating-A {
+ background-color: #0A0;
+}
+a .rating-A {
+ border-bottom-color: #0A0;
+}
+.rating-B {
+ background-color: #80CC00;
+}
+a .rating-B {
+ border-bottom-color: #80CC00;
+}
+.rating-C {
+ background-color: #FE0;
+ color: #444;
+}
+a .rating-C {
+ border-bottom-color: #FE0;
+}
+.rating-D {
+ background-color: #F77700;
+}
+a .rating-D {
+ border-bottom-color: #F77700;
+}
+.rating-E {
+ background-color: #E00;
+}
+a .rating-E {
+ border-bottom-color: #E00;
+}
+.code {
+ font-size: 12px;
+}
+.code pre {
+ font-family: Monospace;
+ padding: 0 5px;
+ color: #111;
+ margin: 0;
+}
+.code .a {
+ color: olive;
+}
+.code .c {
+ color: #660E80;
+ font-style: italic;
+ font-weight: 700;
+}
+.code .j {
+ color: #666;
+ font-style: normal;
+}
+.code .cd {
+ color: #666;
+ font-style: italic;
+}
+.code .cppd {
+ color: #666;
+ font-style: italic;
+}
+.code .k {
+ color: navy;
+ font-weight: 700;
+}
+.code .s {
+ color: green;
+ font-weight: 700;
+}
+.code .h {
+ color: navy;
+ font-weight: 400;
+}
+.code .p {
+ color: #347235;
+ font-weight: 400;
+}
+.sym {
+ cursor: hand;
+ cursor: pointer;
+}
+.highlighted {
+ background-color: #B3D4FF;
+}
+.dashboard-page {
+ background-color: #f3f3f3;
+}
+.dashboard-page #ftlinks {
+ border-top-color: #e6e6e6;
+ background-color: #f3f3f3;
+}
+#dashboard {
+ position: relative;
+ width: 100%}
+#dashboard .transparent {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ background: url("../images/transparent.gif?e3a98b896a81dbc5b02ca14b5646e2ac") repeat;
+ z-index: 1000;
+}
+#dashboard .widget {
+ position: relative;
+ overflow-x: auto;
+ overflow-y: hidden;
+ padding: 10px;
+ margin: 0;
+}
+#dashboard .widget .big {
+ line-height: 1.5;
+ font-size: 24px;
+ font-weight: 300;
+}
+#dashboard .block {
+ margin: 0 0 10px;
+ border: 1px solid #e6e6e6;
+ background-color: #fff;
+}
+#dashboard .configure_widget {
+ display: block;
+ position: relative;
+}
+#dashboard .widget_props {
+ background-color: #FFFBE2;
+ border: 1px solid #FCE174;
+ margin: 5px;
+ padding: 5px;
+}
+#dashboard .widget-title {
+ padding: 10px;
+ line-height: 1;
+ border-bottom: 1px solid #e6e6e6;
+ color: #444;
+ font-size: 14px;
+ font-weight: 400;
+ text-transform: uppercase;
+}
+#dashboard .widget-title a {
+ border-bottom: none;
+}
+#dashboard #configure {
+ position: relative;
+ height: 260px;
+ margin: 5px 0 10px;
+}
+#dashboard #widget_defs, #dashboard #edit-layout {
+ background-color: #FFFBE2;
+ border: 1px solid #FCE174;
+ padding: 5px;
+ overflow-x: hidden;
+}
+#dashboard #widget_defs {
+ margin-right: 104px;
+ overflow-y: auto;
+ height: 250px;
+}
+#dashboard #edit-layout {
+ width: 86px;
+ height: 248px;
+ position: absolute;
+ right: 0;
+ top: 0;
+ padding-top: 5px;
+}
+#dashboard #edit-layout p {
+ margin-bottom: 5px;
+}
+#dashboard .widget_def {
+ display: inline-block;
+ vertical-align: top;
+ border: 1px solid #FCE174;
+ padding: 5px;
+ margin: 5px;
+ white-space: normal;
+ width: 250px;
+ min-height: 100px;
+}
+#dashboard ul.widget_categs li {
+ padding-right: 5px;
+}
+#dashboard ul.widget_categs li.selected a {
+ font-weight: 700;
+ text-decoration: none;
+}
+#dashboard .select-layout {
+ float: left;
+}
+#dashboard .select-layout img {
+ border: 3px solid #FFF6BF;
+}
+#dashboard .select-layout.selected img {
+ border: 3px solid #4B9FD5;
+}
+.admin_page {
+ position: relative;
+}
+.admin_page table {
+ margin-top: 10px;
+ margin-bottom: 50px;
+}
+.admin_page .empty {
+ font-style: italic;
+}
+.admin_page .operations {
+ width: 260px;
+ text-align: right;
+}
+.admin_page .operations .link-action {
+ margin-left: 4px;
+}
+.admin_page .owner {
+ width: 140px;
+ text-align: center;
+}
+.admin_page .shared {
+ width: 40px;
+ text-align: center;
+}
+.admin_page .order, .admin_page .global {
+ width: 45px;
+ text-align: center;
+}
+#dashboard #dashboard-operations {
+ position: relative;
+ display: inline-block;
+ width: 100%}
+#dashboard #dashboard-operations ul.operations {
+ float: left;
+ list-style-type: none;
+ border: 1px solid #cdcdcd;
+ padding: 0;
+ margin: 0;
+ border-radius: 3px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+}
+#dashboard #dashboard-operations ul.operations li {
+ float: left;
+ margin: 0;
+ padding: 2px 10px;
+ position: relative;
+ background-color: #f4f4f4;
+ font-size: 85%;
+ border-right: 1px solid #cdcdcd;
+}
+#dashboard #dashboard-operations ul.operations li.last {
+ border-right-width: 0;
+}
+#dashboard #dashboard-operations ul.operations li.selected {
+ background-color: #d4d4d4;
+}
+#dashboard #dashboard-operations ul.operations li a {
+ color: #555;
+}
+#dashboard .dashboard-column {
+ margin: 0;
+ padding: 0;
+ overflow: visible;
+}
+#dashboard .dashboard-column-wrapper {
+ float: left;
+ margin: 0;
+ padding: 0;
+}
+#dashboard .column-handle {
+ height: 30px;
+ width: 100%;
+ margin: 0;
+ padding: 0;
+ display: inline-block;
+ line-height: 100px;
+ text-align: center;
+ font-size: x-large;
+ vertical-align: middle;
+ background-color: #eee;
+}
+#dashboard .block {
+ position: relative;
+ width: 100%}
+#dashboard .widget-header {
+ line-height: 16px;
+ padding: 3px 5px 5px;
+ background-color: #efefef;
+ border: 1px solid #ddd;
+ border-bottom: 0;
+}
+#dashboard .widget-handle {
+ cursor: move;
+ margin: 0;
+ background-image: url("../images/move.png?c9696f1a9ec509ca83a5300f6fa0e99f");
+ background-position: left center;
+ background-repeat: no-repeat;
+ padding-left: 20px;
+}
+#dashboard .widget-actions {
+ float: right;
+}
+#dashboard .widget-actions a {
+ cursor: pointer;
+}
+#dashboard .block-hover {
+ outline: 2px dashed #ddd;
+}
+#dashboard .shadow-block {
+ box-shadow: 8px 8px 8px #ddd;
+ -moz-box-shadow: 8px 8px 8px #ddd;
+ -webkit-box-shadow: 8px 8px 8px #ddd;
+}
+.widget-row {
+ font-size: 0;
+ margin: 0 -10px -20px;
+}
+.widget-span {
+ display: inline-block;
+ vertical-align: top;
+ padding: 0 10px 20px;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ font-size: 13px;
+}
+.widget-span-1 {
+ width: 8.33333333333333%}
+.widget-span-2 {
+ width: 16.66666666666667%}
+.widget-span-3 {
+ width: 25%}
+.widget-span-3-5 {
+ width: 29.16666666666667%}
+.widget-span-4 {
+ width: 33.33333333333333%}
+.widget-span-5 {
+ width: 41.66666666666667%}
+.widget-span-6 {
+ width: 50%}
+.widget-span-7 {
+ width: 58.33333333333333%}
+.widget-span-8 {
+ width: 66.666666666667%}
+.widget-span-9 {
+ width: 75%}
+.widget-span-10 {
+ width: 83.333333333333%}
+.widget-span-11 {
+ width: 91.666666666667%}
+.widget-span-12 {
+ width: 100%}
+@media (max-width:1279px) {
+ .widget-span-1 {
+ width: 50%}
+.widget-span-2 {
+ width: 50%}
+.widget-span-3 {
+ width: 50%}
+.widget-span-3-5 {
+ width: 50%}
+.widget-span-4 {
+ width: 50%}
+.widget-span-5 {
+ width: 50%}
+.widget-span-6 {
+ width: 50%}
+.widget-span-7 {
+ width: 100%}
+.widget-span-8 {
+ width: 100%}
+.widget-span-9 {
+ width: 100%}
+.widget-span-10 {
+ width: 100%}
+.widget-span-11 {
+ width: 100%}
+.widget-span-12 {
+ width: 100%}
+}.widget-label {
+ display: block;
+ font-size: 13px;
+ line-height: 1.2;
+ font-weight: 300;
+}
+.widget-number {
+ color: #236a97;
+}
+.widget-big {
+ line-height: 1.5;
+ font-size: 24px;
+ font-weight: 300;
+}
+.widget-medium {
+ line-height: 1.5;
+ font-size: 18px;
+ font-weight: 300;
+}
+.widget-measure {
+ display: inline-block;
+ vertical-align: top;
+ margin: 0 15px 10px 0;
+}
+.widget-measure .widget-link, .widget-measure .widget-number {
+ line-height: 1.5;
+ font-size: 18px;
+ font-weight: 300;
+}
+.widget-measure .widget-label {
+ text-transform: capitalize;
+}
+.widget-measure-main {
+ display: block;
+ margin-top: 10px;
+}
+.widget-measure-main .widget-link, .widget-measure-main .widget-number {
+ line-height: 1.5;
+ font-size: 24px;
+ font-weight: 300;
+}
+.widget-measure-main .widget-label {
+ font-size: 16px;
+}
+.widget-measure-container {
+ margin: -10px 0;
+}
+.widget-measure-delta {
+ margin-top: -5px;
+ margin-bottom: 10px;
+ line-height: 1.5;
+}
+.widget-barchar {
+ line-height: 1;
+}
+.widget-barchar td {
+ vertical-align: middle!important;
+}
+.widget-barchar div.barchart div {
+ height: 1em;
+}
+.widget-measure-container .widget-barchar {
+ margin-bottom: 10px;
+}
+.widget-measure-container .widget-barchart-more {
+ margin-top: -5px;
+ margin-bottom: 10px;
+ padding-left: 5px;
+}
+.description-widget-project {
+ display: inline-block;
+ line-height: 1.5;
+ margin-right: 10px;
+ font-size: 16px;
+ font-weight: 300;
+ white-space: nowrap;
+}
+.description-widget-description {
+ margin: 7px 0;
+ line-height: 1.5;
+}
+.description-widget-key {
+ color: #777;
+ font-size: 12px;
+ font-weight: 300;
+ white-space: nowrap;
+}
+.description-widget-links>li {
+ display: inline-block;
+ vertical-align: top;
+ padding: 5px 25px 5px 0;
+}
+.description-widget-links>li>a {
+ font-size: 13px;
+}
+.description-widget-links>li>a>i, .description-widget-links>li>a>i:before {
+ vertical-align: top;
+ font-size: 16px;
+}
+.description-widget-link-data {
+ margin-top: 7px;
+}
+.select-list-container {
+ min-width: 500px;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.select-list-control {
+ margin-bottom: 10px;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.select-list-list-container {
+ border: 1px solid #bfbfbf;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.select-list-list-container.loading .select-list-list {
+ display: none;
+}
+.select-list-list-container-readonly {
+ border: none;
+}
+.select-list-list-container-readonly .select-list-list {
+ overflow: visible;
+}
+.select-list-list-container-readonly .select-list-list>li {
+ border: none;
+}
+.select-list-list {
+ overflow-x: hidden;
+}
+.select-list-list>li {
+ position: relative;
+ display: block;
+ margin-top: -1px;
+ padding: 5px 10px;
+ border-top: 1px solid #e0e0e0;
+ color: #404040;
+ transition: -webkit-transform .3s ease;
+ transition: -ms-transform .3s ease;
+ transition: transform .3s ease;
+}
+.select-list-list>li.removed {
+ -webkit-transform: translateX(100%);
+ -moz-transform: translateX(100%);
+ -ms-transform: translateX(100%);
+ -o-transform: translateX(100%);
+ transform: translateX(100%);
+}
+.select-list-list>li.added {
+ -webkit-transform: translateX(-100%);
+ -moz-transform: translateX(-100%);
+ -ms-transform: translateX(-100%);
+ -o-transform: translateX(-100%);
+ transform: translateX(-100%);
+}
+.select-list-list>li.progress {
+ background: url("../images/loading.gif?e2a9308e1360f28fb8fe7ad05eed2e38") no-repeat 10px 5px;
+}
+.select-list-list>li.progress .select-list-list-checkbox {
+ visibility: hidden;
+}
+.select-list-list>li.empty-message {
+ padding: 6px 5px;
+ border: 1px solid #ddd;
+ background-color: #efefef;
+}
+.select-list-list-checkbox {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 10px;
+}
+.select-list-list-item {
+ display: inline-block;
+ vertical-align: middle;
+}
+.select-list-control {
+ height: 27px;
+}
+.select-list-check-control {
+ float: left;
+}
+.select-list-check-control.disabled {
+ filter: alpha(opacity=60);
+ opacity: .6;
+}
+.select-list-check-control.disabled .select-list-control-button {
+ background-color: #fff!important;
+}
+.select-list-control-button {
+ position: relative;
+ z-index: 1;
+ display: inline-block;
+ vertical-align: middle;
+ width: 110px;
+ height: 27px;
+ line-height: 25px;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ border: 1px solid #bfbfbf;
+ color: #444;
+ text-align: center;
+ cursor: pointer;
+ transition: background-color .2s ease;
+}
+.select-list-control-button:hover {
+ background-color: #f6f6f6;
+ color: #444;
+}
+.select-list-control-button:active, .select-list-control-button.active {
+ z-index: 2;
+ background-color: #efefef;
+ color: #444;
+}
+.select-list-control-button+.select-list-control-button {
+ margin-left: -1px;
+}
+.select-list-search-control {
+ position: relative;
+ float: right;
+ height: 27px;
+}
+.select-list-search-control input {
+ width: 170px;
+ height: 100%;
+ line-height: 27px\9;
+ padding: 0 40px 0 10px;
+ border: 1px solid #bfbfbf;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ transition: all .3s ease;
+}
+.select-list-search-control input:focus {
+ outline: 0;
+ box-shadow: none;
+}
+.select-list-search-control input::-ms-clear {
+ display: none;
+}
+.select-list-search-control-clear {
+ position: absolute;
+ top: 2px;
+ right: 2px;
+ width: 23px;
+ height: 23px;
+ line-height: 24px;
+ background-color: #e0e0e0;
+ color: #fff;
+ cursor: pointer;
+ font-size: 18px;
+ text-align: center;
+ transition: all .3s ease;
+}
+.select-list-search-control.disabled .select-list-search-control-clear {
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+.select-list-search-control-clear:hover {
+ background-color: #d6d6d6;
+}
+.navigator-header {
+ height: 40px;
+ margin: 10px;
+ border: 1px solid #e6e6e6;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.navigator-filters {
+ position: relative;
+ margin: 10px;
+ border: 1px solid #e6e6e6;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.navigator-content {
+ display: table;
+ width: 100%}
+.navigator-side {
+ position: relative;
+ display: table-cell;
+ vertical-align: top;
+ width: 340px;
+ min-width: 295px;
+ max-width: 620px;
+}
+.navigator-main {
+ display: table-cell;
+ vertical-align: top;
+}
+.navigator-facets {
+ margin: 10px;
+ border: 1px solid #e6e6e6;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.navigator-results {
+ position: relative;
+ z-index: 2;
+ width: 320px;
+ min-width: 275px;
+ max-width: 600px;
+ margin: 10px 10px 0;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.navigator-actions {
+ position: relative;
+ z-index: 4;
+ margin: 0 10px 10px;
+ border: 1px solid #e6e6e6;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.navigator-actions:before, .navigator-actions:after {
+ display: table;
+ content: "";
+ line-height: 0;
+}
+.navigator-actions:after {
+ clear: both;
+}
+.navigator-details {
+ position: relative;
+ margin: 0 10px 10px;
+}
+.navigator-resizer {
+ position: absolute;
+ top: 50%;
+ right: -1px;
+ cursor: col-resize;
+}
+.navigator-notes {
+ display: none;
+}
+.navigator-with-notes .navigator-notes {
+ display: block;
+}
+.measures-page .navigator-details {
+ overflow: visible;
+}
+.measures-page .page {
+ padding: 0 0 0 10px;
+}
+.navigator-fetching:before {
+ content: " ";
+ position: absolute;
+ z-index: 3;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: #fff url("../images/loading.gif?e2a9308e1360f28fb8fe7ad05eed2e38") no-repeat 4px 4px;
+}
+.navigator-fetching#tab-issue-rule {
+ position: relative;
+}
+.navigator-fetching#tab-issue-rule:before {
+ z-index: 3;
+ background-color: #EFEFEF;
+}
+.navigator-fetching.code-issue-actions {
+ position: relative;
+}
+.navigator-fetching.code-issue-actions:before {
+ z-index: 3;
+ background-color: #E4ECF3;
+}
+.navigator-page-loader {
+ padding: 10px 0 0 10px;
+}
+.navigator-header {
+ padding: 0 10px;
+ background-color: #f3f3f3;
+ font-size: 0;
+}
+.navigator-header-favorite {
+ padding-left: 58px;
+}
+.navigator-header-title {
+ display: inline-block;
+ vertical-align: middle;
+ color: #444;
+ font-size: 20px;
+ line-height: 37px;
+}
+.navigator-header-title-note {
+ vertical-align: middle;
+ color: #777;
+ font-size: 12px;
+}
+.navigator-header-description {
+ display: inline-block;
+ vertical-align: middle;
+ margin-left: 16px;
+ font-size: 12px;
+ font-style: italic;
+}
+.navigator-header-actions {
+ margin-left: 20px;
+}
+.navigator-header-actions>a {
+ vertical-align: middle;
+ margin: 0 8px;
+ font-size: 12px;
+}
+.navigator-header-menu-toggle {
+ display: inline-block;
+ vertical-align: top;
+ height: 36px;
+ margin-right: 10px;
+ margin-left: -10px;
+ padding: 10px;
+ border-right: 1px solid transparent;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ cursor: pointer;
+ transition: all .2s ease;
+}
+.navigator-header-menu-toggle:hover {
+ background-color: #e6e6e6;
+}
+.navigator-header-menu-toggle.active {
+ border-color: #cdcdcd;
+ background-color: #fff;
+}
+.navigator-header-menu-toggle [class^=icon-], .navigator-header-menu-toggle [class*=" icon-"] {
+ font-size: 16px;
+}
+.navigator-notes {
+ margin: 0 10px 10px;
+ padding: 0 10px;
+ border: 1px solid #e6e6e6;
+ background-color: #f3f3f3;
+ color: #777;
+ font-size: 12px;
+ line-height: 20px;
+}
+.navigator-facets {
+ padding: 10px;
+ border-bottom: 1px solid #e6e6e6;
+ background-color: #f3f3f3;
+}
+.navigator-facets-list-item {
+ font-size: 0;
+ margin-bottom: -6px;
+}
+.navigator-facets-list-item+.navigator-facets-list-item {
+ margin-top: 10px;
+}
+.navigator-facets-list-item-name {
+ float: left;
+ line-height: 22px;
+ min-width: 120px;
+ margin-right: 10px;
+ font-size: 12px;
+ font-weight: 400;
+ text-transform: uppercase;
+}
+.navigator-facets-list-item-options {
+ overflow: hidden;
+}
+.navigator-facets-list-item-option {
+ display: inline-block;
+ vertical-align: middle;
+ line-height: 1;
+ margin: 0 6px 6px;
+ padding: 4px 5px;
+ border: 1px solid #e6e6e6;
+ border-radius: 2px;
+ background-color: #f8f8f8;
+ font-size: 0;
+ font-weight: 300;
+ cursor: pointer;
+ transition: all .2s ease;
+}
+.navigator-facets-list-item-option:hover {
+ border: 1px solid #4b9fd5;
+ text-decoration: none;
+}
+.navigator-facets-list-item-option.active {
+ border: 1px solid #4b9fd5;
+ background-color: #cae3f2;
+ text-decoration: none;
+}
+.navigator-facets-list-item-option.active .navigator-facets-list-item-option-stat {
+ border-color: #4b9fd5;
+}
+.navigator-facets-list-item-option-name {
+ font-size: 12px;
+}
+.navigator-facets-list-item-option-stat {
+ margin-left: 5px;
+ padding-left: 5px;
+ border-left: 1px solid #e6e6e6;
+ color: #777;
+ font-size: 12px;
+ transition: all .2s ease;
+}
+.navigator-results {
+ background-color: #fff;
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+.navigator-results.fetching .navigator-results-list {
+ visibility: hidden;
+}
+.navigator-results.fetching .navigator-results-loader {
+ display: block;
+}
+.navigator-results-loader {
+ position: fixed;
+ z-index: 10;
+ display: none;
+ background-color: #fff;
+}
+.navigator-results-list>li {
+ position: relative;
+ z-index: 1;
+ padding: 5px 0;
+ border: 1px solid;
+ border-color: #e6e6e6 transparent;
+ cursor: pointer;
+ transition: all .2s ease;
+}
+.navigator-results-list>li .line {
+ padding: 5px 10px;
+ line-height: 1.2;
+}
+.navigator-results-list>li .line-small {
+ font-size: 11px;
+ line-height: 14px;
+}
+.navigator-results-list>li .line-right {
+ float: right;
+}
+.navigator-results-list>li .line-nowrap {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.navigator-results-list>li:hover {
+ background-color: #f3f3f3;
+}
+.navigator-results-list>li.active {
+ z-index: 2;
+ background-color: #CAE3F2;
+ border-color: #4B9FD5;
+}
+.navigator-results-list>li+li {
+ margin-top: -1px;
+}
+.navigator-results-no-results {
+ padding-top: 20%!important;
+ background: #fff!important;
+ border-color: transparent!important;
+ color: #999;
+ cursor: default!important;
+ text-align: center;
+}
+.navigator-details {
+ background-color: #fff;
+ overflow: auto;
+}
+.navigator-details.loading {
+ background: #fff url("../images/loading.gif?e2a9308e1360f28fb8fe7ad05eed2e38") no-repeat 4px 2px;
+}
+.navigator-details .code-issue-name {
+ border-bottom: none;
+}
+.navigator-details .code-issue-actions {
+ background-color: #E4ECF3;
+}
+.navigator-details .source_title {
+ z-index: 3;
+ top: 160px;
+ left: 320px;
+ right: 0;
+ padding: 0 0 10px;
+ background-color: #fff;
+}
+.navigator-details .source>table {
+ border: 1px solid #DDD;
+}
+.navigator-details .scm .author {
+ display: inline-block;
+ vertical-align: middle;
+ max-width: 100px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.navigator-actions {
+ padding: 0 10px 0 0;
+ border-right: 1px solid #e6e6e6;
+ border-bottom: 1px solid #e6e6e6;
+ background-color: #f3f3f3;
+ font-size: 12px;
+}
+.navigator-actions strong {
+ font-weight: 700;
+}
+.navigator-actions-order {
+ float: left;
+ padding: 0 10px;
+ line-height: 30px;
+ cursor: pointer;
+ transition: all .2s ease;
+}
+.navigator-actions-order:hover {
+ background-color: #e6e6e6;
+}
+.navigator-actions-order-choices {
+ position: absolute;
+ top: 100%;
+ left: -1px;
+ min-width: 160px;
+ background-color: #fff;
+ border: 1px solid #e6e6e6;
+ box-shadow: 10px 10px 20px rgba(0, 0, 0, .5);
+ overflow: hidden;
+ display: none;
+}
+.navigator-actions-order-choices>li {
+ height: 30px;
+ line-height: 30px;
+ padding: 0 10px;
+ cursor: pointer;
+ transition: all .2s ease;
+}
+.navigator-actions-order-choices>li:hover {
+ background-color: #f3f3f3;
+}
+.navigator-actions-order-choices.open {
+ display: block;
+}
+.navigator-actions-total {
+ float: right;
+ height: 30px;
+ line-height: 30px;
+}
+.navigator-actions-bulk {
+ position: relative;
+ top: -1px;
+ margin-left: 8px;
+ font-size: 16px;
+ text-decoration: none;
+}
+.navigator-page #footer {
+ margin: 0;
+ border-top: 1px solid #e6e6e6;
+}
+.navigator-page #ftlinks {
+ margin-top: 0;
+}
+.navigator-filters {
+ padding-right: 85px;
+ background-color: #f3f3f3;
+ font-size: 0;
+}
+.navigator-filters-list {
+ display: inline-block;
+ vertical-align: middle;
+ font-size: 0;
+ margin-bottom: -1px;
+}
+.navigator-filter-submit, .navigator-filter-new-search {
+ vertical-align: middle;
+ margin-left: 15px;
+ font-size: 13px;
+}
+.navigator-filter-submit {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ width: 85px;
+ height: 40px;
+ margin: -1px -1px -1px 0;
+ padding: 0;
+ border: 1px solid #2d87c0;
+ background: #4b9fd5;
+ color: #fff;
+ font-weight: 400;
+ transition: all .2s ease;
+}
+.navigator-filter-submit::-moz-focus-inner {
+ border: 0;
+}
+.navigator-filter-submit:hover, .navigator-filter-submit:focus {
+ border-color: #4b9fd5;
+ background-color: #74b5df;
+}
+.navigator-filter-list-favorite {
+ position: relative;
+ padding-left: 36px;
+ overflow: hidden;
+}
+.navigator-filters-actions {
+ display: inline-block;
+ vertical-align: middle;
+ margin-left: 20px;
+ font-size: 13px;
+}
+.navigator-filter {
+ position: relative;
+ z-index: 1;
+ display: inline-block;
+ vertical-align: top;
+ height: 40px;
+ line-height: 37px;
+ margin: -1px 0 0 -1px;
+ padding: 0 15px;
+ border: 1px solid #e6e6e6;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ white-space: nowrap;
+ cursor: pointer;
+ transition: all .2s ease;
+}
+.navigator-filter:hover {
+ z-index: 2;
+ border-color: #e6e6e6;
+ background-color: #e6e6e6;
+}
+.navigator-filter.active {
+ border-color: #cdcdcd;
+ background: #fff;
+}
+.navigator-filter-disabled {
+ display: none;
+}
+.navigator-filter-optional {
+ padding-right: 0;
+}
+.navigator-filter-inline, .navigator-filter-read-only, .navigator-filter-inactive {
+ cursor: default;
+}
+.navigator-filter-inline:hover, .navigator-filter-read-only:hover, .navigator-filter-inactive:hover, .navigator-filter-inline.active, .navigator-filter-read-only.active, .navigator-filter-inactive.active {
+ border-color: transparent;
+ background: 0 0;
+}
+.navigator-filter-inline .navigator-filter-label:after {
+ content: ""}
+.navigator-filter-inactive {
+ opacity: .5;
+}
+.navigator-filter-context {
+ z-index: 3;
+ background-color: #eee1f8;
+ border-color: #d7b7ef;
+}
+.navigator-filter-label {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 5px;
+ color: #333;
+ font-size: 13px;
+}
+.navigator-filter-label:after {
+ content: ":"}
+.navigator-filter-value {
+ display: inline-block;
+ vertical-align: middle;
+ max-width: 120px;
+ color: #333;
+ font-size: 13px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.navigator-filter-value.default {
+ color: #666;
+}
+.navigator-filter-disable {
+ display: inline-block;
+ vertical-align: middle;
+ width: 20px;
+ height: 20px;
+ line-height: 20px;
+ margin: 0 0 0 5px;
+ font-size: 18px;
+ text-align: center;
+ transition: background .3s ease;
+}
+.navigator-filter-disable:hover {
+ background-color: #d4d4d4;
+}
+.navigator-filter-range-input {
+ width: 120px;
+}
+.navigator-filter-details {
+ display: none;
+ position: absolute;
+ z-index: 1200;
+ min-width: 100px;
+ border: 1px solid #cdcdcd;
+ background: #fff;
+ box-shadow: 10px 10px 20px rgba(0, 0, 0, .5);
+ font-size: 13px;
+ transition: opacity .3s ease;
+}
+.navigator-filter-details.active {
+ display: block;
+}
+@media screen and (-ms-high-contrast:active), (-ms-high-contrast:none) {
+ .navigator-filter-details {
+ width: 250px;
+}
+}.navigator-filter-details-inner {
+ max-width: 300px;
+ padding: 5px 10px;
+}
+.navigator-filter-details-inner .select2-container, .navigator-filter-details-inner input {
+ margin: 5px 0;
+ vertical-align: middle;
+}
+.navigator-filter-select-list {
+ min-width: 150px;
+ max-width: 300px;
+ max-height: 182px;
+ padding: 5px 0;
+ overflow-y: auto;
+ -ms-overflow-style: scrollbar;
+}
+.navigator-filter-select-list::-webkit-scrollbar {
+ width: 11px;
+ background-color: transparent;
+ background-clip: content-box;
+}
+.navigator-filter-select-list::-webkit-scrollbar-button {
+ background-color: transparent;
+}
+.navigator-filter-select-list::-webkit-scrollbar-corner {
+ background-color: transparent;
+}
+.navigator-filter-select-list::-webkit-scrollbar-thumb {
+ border: solid transparent;
+ border-width: 1px 1px 1px 2px;
+ background-color: #c5c5c5;
+ background-clip: content-box;
+}
+.navigator-filter-select-list::-webkit-scrollbar-track {
+ border: solid #fff;
+ border-width: 1px 1px 1px 2px;
+ background-color: #fff;
+ background-clip: content-box;
+}
+.navigator-filter-select-list::-webkit-scrollbar-track-piece {
+ border-left: 1px solid #ccc;
+ background-color: transparent;
+}
+.navigator-filter-select-list label {
+ display: block;
+ padding: 5px 10px;
+ cursor: pointer;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ transition: background .2s ease;
+}
+.navigator-filter-select-list label:hover, .navigator-filter-select-list label.current {
+ background-color: #ededed;
+}
+.navigator-filter-select-list label>input[type=checkbox] {
+ vertical-align: baseline;
+ cursor: pointer;
+}
+.navigator-filter-select-list label>img {
+ vertical-align: text-bottom;
+}
+.navigator-filter-select-list label.special {
+ font-style: italic;
+}
+.navigator-filter-select-list label.special>span {
+ text-decoration: underline;
+}
+.navigator-filter-select-list label.inactive {
+ cursor: default;
+ opacity: .5;
+}
+.navigator-filter-select-list label.inactive:hover {
+ background-color: transparent;
+}
+.navigator-filter-select-list .single {
+ padding: 5px 10px;
+}
+.navigator-filter-select-list .line {
+ height: 1px;
+ margin: 5px 0;
+ background: #cdcdcd;
+}
+.navigator-filter-select-list:not(.hidden)+.navigator-filter-select-list {
+ margin-top: 5px;
+ border-top: 1px solid #cdcdcd;
+}
+.navigator-filter-search {
+ position: relative;
+ margin: 10px 26px 10px 10px;
+}
+.navigator-filter-search input {
+ width: 100%;
+ height: 26px;
+ padding: 0 7px;
+ border: 1px solid #cdcdcd;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.fetching .navigator-filter-search:after {
+ content: ' ';
+ position: absolute;
+ top: 6px;
+ right: -21px;
+ display: block;
+ width: 16px;
+ height: 16px;
+ background: #fff url("../images/loading.gif?e2a9308e1360f28fb8fe7ad05eed2e38") no-repeat center center;
+}
+.navigator-filter-search.fetching-error input {
+ border: 2px solid #d4333f;
+}
+.navigator-filter-load-more {
+ display: none;
+ height: 26px;
+ line-height: 26px;
+ background-color: #efefef;
+ text-align: center;
+ cursor: pointer;
+ transition: background .3s ease;
+}
+.navigator-filter-load-more:hover {
+ background-color: #ddd;
+}
+.navigator-filter-favorite {
+ position: absolute;
+ top: -50px;
+ left: 0;
+}
+.navigator-filter-favorite-toggle {
+ width: 16px;
+ height: 40px;
+ background: url("../images/navigator/favorite-filters.png?b417118b9e88b0379652f50519aa0e72") no-repeat center center;
+}
+@media (-webkit-min-device-pixel-ratio:2), (min-resolution:192dpi) {
+ .navigator-filter-favorite-toggle {
+ background-image: url("../images/navigator/favorite-filters@2x.png?10d370e67289463f8791f86812b89e4b");
+ background-size: 16px 14px;
+}
+}.navigator-filter-more-criteria {
+ font-size: 13px;
+}
+.api-documentation-navigator .navigator-side {
+ display: table-cell;
+ vertical-align: top;
+ width: 250px;
+ min-width: 0;
+}
+.api-documentation-navigator .navigator-header {
+ margin-left: 0;
+}
+.api-documentation-navigator .navigator-header .spinner {
+ margin-top: 9px;
+}
+.api-documentation-navigator .navigator-actions {
+ height: 40px;
+ width: 230px;
+ margin: 10px;
+ padding: 0 10px;
+}
+.api-documentation-navigator .navigator-actions .navigator-header-title {
+ color: #444;
+ font-size: 13px;
+ font-weight: 700;
+ text-transform: uppercase;
+}
+.api-documentation-navigator .api-documentation-show-internals {
+ margin: 10px;
+ padding: 0 10px;
+}
+.api-documentation-navigator .navigator-results {
+ width: 230px;
+ min-width: 0;
+}
+.api-documentation-navigator .navigator-details {
+ margin-left: 0;
+}
+.api-documentation-navigator .internal {
+ color: #f3f3f3;
+ background-color: #7f7f7f;
+ border-radius: 2px;
+ padding: 1px 5px;
+}
+.api-documentation-nav .navigator-results-list>li {
+ border-color: transparent;
+}
+.api-documentation-nav .navigator-results-list>li:hover:not(.active):not(.empty) {
+ background-color: #f3f3f3;
+}
+.api-documentation-nav .navigator-results-list>li.active {
+ border-color: #4B9FD5;
+}
+.api-documentation-nav .navigator-results-list>li.empty {
+ cursor: default;
+}
+.api-documentation-nav .navigator-results-list>li .line {
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.api-documentation-actions {
+ margin-top: 10px;
+ margin-left: 5px;
+}
+.api-documentation-actions ol li {
+ list-style: decimal;
+ margin-left: 2em;
+}
+.api-documentation-actions .api-documentation-action {
+ margin-top: 30px;
+}
+.api-documentation-actions .api-documentation-action>p, .api-documentation-actions .api-documentation-action>h3 {
+ margin-top: 5px;
+}
+.api-documentation-actions .api-documentation-action table {
+ width: 100%}
+.api-documentation-actions .api-documentation-action table tr {
+ border-top: 1px solid #e6e6e6;
+}
+.api-documentation-actions .api-documentation-action table tr td {
+ padding: 10px 0 10px 5px;
+ margin: 5px;
+ vertical-align: top;
+}
+.api-documentation-actions .api-documentation-action table tr td ul li {
+ list-style: square;
+ margin-left: 2em;
+}
+.api-documentation-actions .api-documentation-action table tr td ul.possible-values {
+ display: inline;
+}
+.api-documentation-actions .api-documentation-action table tr td ul.possible-values li {
+ display: inline;
+ margin: 0;
+}
+.api-documentation-actions .api-documentation-action table tr td ul.possible-values li:before {
+ content: ', '}
+.api-documentation-actions .api-documentation-action table tr td ul.possible-values li:first-child:before {
+ content: ''}
+.api-documentation-actions .api-documentation-action .example-response {
+ text-decoration: underline;
+}
+.api-documentation-actions .api-documentation-action .example-response-content {
+ margin: 10px 0;
+ padding: 5px;
+ background-color: #f3f3f3;
+ border: 1px solid #e6e6e6;
+}
+.api-documentation-actions .api-documentation-action .example-response-content code {
+ white-space: pre-wrap;
+}
+.coding-rules-page .navigator-results .spinner {
+ margin: 10px;
+}
+.coding-rules-page .navigator-results .line-right {
+ margin-top: -14px;
+ float: none;
+ text-align: right;
+}
+.coding-rules-page .navigator-results-list .line {
+ padding-top: 3px;
+ padding-bottom: 3px;
+}
+.coding-rules-page .navigator-results-list .line+.line {
+ padding-top: 0;
+}
+.coding-rules-page .navigator-results-list .line-small {
+ color: #777;
+}
+.navigator-filter-query {
+ min-width: 40em;
+ padding: 0 5px;
+}
+.navigator-filter-query input {
+ height: 80%;
+ width: 100%;
+ font-size: 13px;
+ vertical-align: middle;
+ vertical-align: -webkit-baseline-middle;
+}
+.coding-rules-detail-header, .coding-rules-detail-title {
+ position: relative;
+ margin-bottom: 10px;
+ line-height: 1.5;
+ font-weight: 700;
+}
+.coding-rules-detail-header {
+ margin-bottom: 0;
+ padding-right: 100px;
+ font-size: 18px;
+}
+.coding-rules-detail-title {
+ display: inline-block;
+ margin-top: 30px;
+ text-transform: uppercase;
+}
+.coding-rules-detail-permalink {
+ position: absolute;
+ top: 0;
+ right: 0;
+ font-size: 13px;
+ font-weight: 400;
+ text-decoration: none;
+ transition: all .2s ease;
+}
+.coding-rules-detail-permalink:hover {
+ color: #4b9fd5;
+}
+.coding-rules-detail-context {
+ margin-bottom: 10px;
+ padding: 5px;
+ border: 1px solid #d7b7ef;
+ background-color: #eee1f8;
+}
+.coding-rules-detail-context .coding-rules-detail-quality-profile {
+ margin-left: 0;
+}
+.coding-rules-detail-context .coding-rules-detail-quality-profile-name, .coding-rules-detail-context .coding-rules-detail-quality-profile-severity, .coding-rules-detail-context .coding-rules-detail-quality-profile-parameters, .coding-rules-detail-context .coding-rules-detail-quality-profile-actions {
+ vertical-align: top;
+}
+.coding-rules-detail-context .coding-rules-detail-quality-profile-name, .coding-rules-detail-context .coding-rules-detail-quality-profile-severity {
+ width: 1px;
+ padding-right: 10px;
+ white-space: nowrap;
+}
+.coding-rules-detail-context .coding-rules-detail-quality-profile-parameter {
+ display: table-cell;
+}
+.coding-rules-detail-quality-profile-parameter {
+ display: block;
+ height: 100%;
+ padding-top: 0;
+ padding-right: 10px;
+}
+.coding-rules-detail-quality-profile-parameter .key, .coding-rules-detail-quality-profile-parameter .value, .coding-rules-detail-quality-profile-parameter .sep {
+ display: inline;
+ vertical-align: top;
+}
+.coding-rules-detail-quality-profile-parameter .value {
+ display: inline-block;
+ max-width: 300px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-family: monospace;
+ vertical-align: baseline;
+}
+.coding-rules-detail-quality-profile-parameter+.coding-rules-detail-quality-profile-parameter {
+ margin-top: 0;
+}
+.coding-rules-detail-context-actions {
+ padding: 5px;
+ background-color: #eee1f8;
+ border: 1px solid #d7b7ef;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.coding-rules-detail-context-actions-quality-profile {
+ vertical-align: middle;
+ margin-right: 10px;
+ font-weight: 700;
+}
+.coding-rules-detail-context-actions-item {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 10px;
+}
+.coding-rules-detail-context-actions-item .limited {
+ display: inline-block;
+ vertical-align: middle;
+ max-width: 180px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.coding-rules-detail-context-actions-item .limited-big {
+ max-width: 480px;
+}
+.coding-rules-detail-properties {
+ margin: 10px 0;
+ font-size: 0;
+}
+.coding-rules-detail-property {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 20px;
+ font-size: 12px;
+ height: 22px;
+ line-height: 22px;
+}
+.coding-rules-detail-property .select2-search-field {
+ line-height: 1;
+}
+.coding-rules-subcharacteristic {
+ cursor: pointer;
+}
+.coding-rules-debt-popup h3 {
+ display: inline;
+}
+.coding-rules-detail-tag+.coding-rules-detail-tag {
+ margin-left: 10px;
+}
+.coding-rules-detail-tags-change {
+ cursor: pointer;
+}
+.coding-rules-detail-tags-change:hover span {
+ text-decoration: underline;
+}
+.coding-rules-detail-tag-edit {
+ line-height: 1;
+}
+.coding-rules-detail-description {
+ margin: 20px 0;
+}
+.coding-rules-detail-description-extra {
+ margin-top: -10px;
+}
+.coding-rules-detail-extend-description-form {
+ margin: 10px 0;
+}
+.coding-rules-detail-parameters {
+ margin: 10px 0 20px;
+}
+.coding-rules-detail-parameter {
+ margin: 10px 0;
+}
+.coding-rules-detail-parameter-name {
+ display: block;
+ margin-left: 20px;
+ font-weight: 700;
+ cursor: pointer;
+}
+.coding-rules-detail-parameter-description {
+ display: inline-block;
+ text-overflow: ellipsis;
+ vertical-align: top;
+ max-width: 75%;
+ margin-left: 20px;
+ padding: 10px;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.coding-rules-detail-parameter-description .subtitle {
+ margin-top: 10px;
+ font-size: 13px;
+}
+.coding-rules-detail-parameter-details {
+ display: inline-block;
+ font-size: 13px;
+ padding-left: 5px;
+}
+.coding-rules-detail-parameter-original {
+ margin-left: 10px;
+ font-size: 12px;
+}
+.coding-rules-detail-quality-profiles-header {
+ margin-top: 30px;
+}
+.coding-rules-detail-quality-profiles {
+ font-size: 0;
+}
+.coding-rules-detail-quality-profile {
+ margin-left: 20px;
+}
+.coding-rules-detail-quality-profile+.coding-rules-detail-quality-profile {
+ margin-top: 10px;
+ padding-top: 10px;
+ border-top: 1px solid #e6e6e6;
+}
+.coding-rules-detail-quality-profile-name {
+ vertical-align: top;
+ width: 15%;
+ font-weight: 700;
+ white-space: nowrap;
+ padding-right: 5px;
+}
+.coding-rules-detail-quality-profile-severity {
+ vertical-align: top;
+ width: 10%}
+.coding-rules-detail-quality-profile-parameters {
+ vertical-align: top;
+}
+.coding-rules-detail-quality-profile-parameter+.coding-rules-detail-quality-profile-parameter {
+ margin-top: 8px;
+}
+.coding-rules-detail-quality-profile-actions {
+ vertical-align: top;
+ width: 25%;
+ text-align: right;
+}
+.coding-rules-detail-quality-profile-inheritance {
+ margin-top: 4px;
+ font-size: 12px;
+ font-weight: 400;
+}
+.coding-rules-detail-quality-profile-inheritance i {
+ position: relative;
+ top: -1px;
+ font-size: 14px;
+}
+.coding-rules-detail-quality-profiles-activation {
+ margin-top: -3px;
+ margin-left: 10px;
+}
+.coding-rules-detail-quality-profiles-template-caption {
+ margin-bottom: 10px;
+}
+.coding-rules-bulk-change-dropdown {
+ position: absolute;
+ z-index: 10;
+ width: 200px;
+ border: 1px solid #e6e6e6;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ box-shadow: 10px 10px 20px rgba(0, 0, 0, .5);
+ background-color: #fff;
+}
+.coding-rules-bulk-change-dropdown-link {
+ display: block;
+ max-width: 190px;
+ height: 30px;
+ line-height: 30px;
+ padding: 0 10px;
+ font-size: 12px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ border-bottom: none;
+ transition: all .2s ease;
+}
+.coding-rules-bulk-change-dropdown-link:hover {
+ background-color: #f3f3f3;
+}
+.coding-rules-bulk-change-dropdown-link strong {
+ font-weight: 700;
+}
+input.coding-rules-name-key {
+ width: 30em;
+}
+[id=coding-rules-detail-custom-rules] {
+ padding-left: 20px;
+}
+textarea.coding-rules-markdown-description {
+ width: 100%;
+ margin-bottom: 4px;
+}
+.coding-rules-detail-custom-rule+.coding-rules-detail-custom-rule {
+ margin-top: 10px;
+ padding-top: 10px;
+ border-top: 1px solid #e6e6e6;
+}
+.coding-rules-detail-custom-rule td {
+ padding: 10px;
+}
+.coding-rules-detail-custom-rule-name {
+ font-weight: 700;
+}
+.coding-rules-subcharacteristic-more {
+ display: none;
+}
+.coding-rules-list-tags {
+ display: inline-block;
+ vertical-align: top;
+ max-width: 50%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.coding-rules-list-tags .icon-tags:before {
+ font-size: 12px;
+}
+.component-viewer-source .code pre {
+ padding: 0;
+ font-family: 'Source Code Pro', monospace;
+ font-size: 12px;
+ line-height: 16px;
+}
+.component-viewer-source .code .c {
+ font-style: normal;
+}
+.component-viewer-source .code .j {
+ font-style: normal;
+}
+.component-viewer-source .code .k {
+ color: #0071ba;
+ font-weight: 600;
+}
+.component-viewer-source .code .s {
+ color: #d4333f;
+ font-weight: 400;
+}
+.component-viewer-source .code .p {
+ font-weight: 400;
+}
+.component-viewer-source .sym {
+ color: #5e8c26;
+}
+.component-viewer {
+ width: 100%;
+ min-width: 600px;
+ border-left-width: 0;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.component-viewer:before, .component-viewer:after {
+ display: table;
+ content: "";
+ line-height: 0;
+}
+.component-viewer:after {
+ clear: both;
+}
+.component-viewer-workspace-enabled .component-viewer-workspace .component-viewer-workspace-list, .component-viewer-workspace-enabled .component-viewer-workspace .component-viewer-workspace-title {
+ display: block;
+}
+.component-viewer-title {
+ color: #444;
+ font-size: 13px;
+ font-weight: 700;
+}
+.component-viewer-title-separator {
+ padding: 0 4px;
+}
+.component-viewer-workspace {
+ position: relative;
+ float: left;
+ min-width: 30px;
+ margin-right: 10px;
+ border: 1px solid #e6e6e6;
+ background-color: #f3f3f3;
+}
+.component-viewer-workspace.overflow {
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.component-viewer-workspace-header {
+ position: relative;
+ height: 30px;
+ border-bottom: 1px solid #e6e6e6;
+}
+.component-viewer-workspace-title {
+ display: none;
+ padding: 0 30px 0 10px;
+ line-height: 30px;
+ text-transform: uppercase;
+}
+.component-viewer-workspace-list {
+ display: none;
+ width: 250px;
+ padding: 8px 0;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.component-viewer-workspace-item {
+ padding: 0 10px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.component-viewer-workspace-item.active>a {
+ font-weight: 700;
+}
+.component-viewer-workspace-item .subtitle {
+ line-height: 16px;
+}
+.component-viewer-workspace-item+.component-viewer-workspace-item {
+ margin-top: 10px;
+}
+.component-viewer-workspace-transition {
+ margin-top: 7px;
+ margin-left: 7px;
+ font-size: 12px;
+}
+.component-viewer-workspace-options {
+ margin-top: 5px;
+ margin-left: 7px;
+ padding-left: 10px;
+ border-left: 3px solid #cdcdcd;
+}
+.component-viewer-workspace-option {
+ line-height: 16px;
+ padding: 3px 0;
+}
+.component-viewer-workspace-option.active>a {
+ font-weight: 700;
+}
+.component-viewer-workspace-toggle {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 30px;
+ height: 30px;
+ transition: all .2s ease;
+}
+.component-viewer-workspace-toggle:hover {
+ background-color: #e6e6e6;
+}
+.component-viewer-source {
+ position: relative;
+ float: left;
+}
+.component-viewer-source.overflow {
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ overflow: auto;
+}
+.component-viewer-source .code {
+ width: 100%;
+ border: 1px solid #e6e6e6;
+}
+.component-viewer-source .code th {
+ height: 30px;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ background-color: #f3f3f3;
+}
+.component-viewer-source .code th.stat {
+ padding-top: 4px;
+ padding-bottom: 4px;
+ border-left: none;
+ border-right: none;
+ border-bottom: 1px solid #e6e6e6;
+}
+.component-viewer-source .code th.lid {
+ border-right: 1px solid #e6e6e6;
+}
+.component-viewer-source .code th.settings {
+ line-height: 22px;
+ text-align: left;
+}
+.component-viewer-source .code th.settings .icon-not-favorite, .component-viewer-source .code th.settings .icon-favorite {
+ float: right;
+ padding-top: 2px;
+}
+.component-viewer-source .code th.settings-toggle {
+ vertical-align: top;
+ border-right: 1px solid #e6e6e6;
+ text-align: center;
+ white-space: nowrap;
+}
+.component-viewer-source .code th.settings-toggle .icon-settings {
+ font-size: 14px;
+}
+.component-viewer-source .code .row:hover td.stat {
+ background-color: #e6e6e6;
+}
+.component-viewer-source .code .row:hover td.line {
+ background-color: #f3f3f3;
+}
+.component-viewer-source .code .row-highlighted td.stat, .component-viewer-source .code .row-highlighted:hover td.stat {
+ background-color: #fdf190;
+}
+.component-viewer-source .code .row-highlighted td.line, .component-viewer-source .code .row-highlighted:hover td.line, .component-viewer-source .code .row-highlighted .code-issues, .component-viewer-source .code .row-highlighted:hover .code-issues, .component-viewer-source .code .row-highlighted .code-issue, .component-viewer-source .code .row-highlighted:hover .code-issue {
+ background-color: #fff8c2;
+}
+.component-viewer-source .code td.line {
+ width: 100%;
+ padding: 1px 5px;
+}
+.component-viewer-source .code .stat {
+ vertical-align: top;
+ min-width: 12px;
+ padding: 1px 5px;
+ background-color: #f3f3f3;
+ color: #888;
+ font-size: 11px;
+ line-height: 16px;
+ text-align: right;
+ cursor: default;
+ white-space: nowrap;
+}
+.component-viewer-source .code .lid {
+ min-width: 18px;
+ padding-left: 10px;
+ padding-right: 10px;
+ cursor: pointer;
+}
+.component-viewer-source .code .coverage-tests {
+ cursor: pointer;
+}
+.component-viewer-source .code .duplications {
+ padding-top: 0;
+ padding-bottom: 0;
+ font-size: 0;
+}
+.component-viewer-source .code .duplications .duplication {
+ display: inline-block;
+ vertical-align: top;
+ width: 5px;
+ height: 19px;
+}
+.component-viewer-source .code .duplications .duplication+.duplication {
+ margin-left: 2px;
+}
+.component-viewer-source .code .duplications .duplication-exists {
+ background-color: #f3ca8e;
+ cursor: pointer;
+ transition: all .2s ease;
+}
+.component-viewer-source .code .duplications .duplication-hover {
+ background-color: #eeb460;
+}
+.component-viewer-source .code .measures {
+ padding: 4px 5px;
+ border-left: 1px solid #e6e6e6;
+ border-bottom: 1px solid #e6e6e6;
+ background-color: #f3f3f3;
+}
+.component-viewer-source .code .issue>pre {
+ display: inline-block;
+ background-image: url("data:image/png; base64, iVBORw0KGgoAAAANSUhEUgAAAAcAAAAGCAYAAAAPDoR2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1M0M2Rjk4M0M3QUYxMUUzODkzRUREMUM5OTNDMjY4QSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1M0M2Rjk4NEM3QUYxMUUzODkzRUREMUM5OTNDMjY4QSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjUzQzZGOTgxQzdBRjExRTM4OTNFREQxQzk5M0MyNjhBIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjUzQzZGOTgyQzdBRjExRTM4OTNFREQxQzk5M0MyNjhBIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+bcqJtQAAAEhJREFUeNpi+G+swwDGDAwgbAWlwZiJAQFCgfgwEIfDRaC67ID4NRDnQ2kQnwFZwgFqnANMAQOUYY9sF0wBiCGH5CBkrAgQYACuWi4sSGW8yAAAAABJRU5ErkJggg==");
+ background-repeat: repeat-x;
+ background-size: 4px;
+ background-position: bottom;
+}
+.component-viewer-source .code .scm {
+ line-height: 16px;
+ padding-top: 0;
+ padding-bottom: 0;
+ text-align: left;
+}
+.component-viewer-source .code .scm .scm-date {
+ display: inline-block;
+ vertical-align: middle;
+ padding: 2px 4px;
+ line-height: 1;
+ background-color: #e6e6e6;
+}
+.component-viewer-source .code .scm .scm-author {
+ display: inline-block;
+ vertical-align: middle;
+ max-width: 120px;
+ padding: 2px 0;
+ line-height: 1;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.component-viewer-source .code .stat.coverage-green {
+ background-color: #a9d07b!important;
+ color: #444;
+}
+.component-viewer-source .code .stat.coverage-orange {
+ background-color: #ffb84d!important;
+ color: #444;
+}
+.component-viewer-source .code .stat.coverage-red {
+ background-color: #e1727a!important;
+ color: #444;
+}
+.component-viewer-source .code .row-expand .stat, .component-viewer-source .code .row-expand .line {
+ border-left: none;
+ border-right: none;
+ background: url("../images/gray-stripes.png?c0affd395b7ae52801fcae4cbc50fd81") repeat;
+}
+.component-viewer-source .code .row-expand .line {
+ text-align: right;
+}
+.component-viewer-source .code .row-hidden {
+ display: none;
+}
+.component-viewer-source-settings {
+ display: none;
+}
+.component-viewer-source-settings.open {
+ display: inline-block;
+}
+.component-viewer-source-settings>li {
+ display: inline;
+ margin-right: 10px;
+}
+.component-viewer-header {
+ position: relative;
+ margin-bottom: 10px;
+}
+.component-viewer-header-bar {
+ border: 1px solid #e6e6e6;
+ background-color: #f3f3f3;
+}
+.component-viewer-header-bar:before, .component-viewer-header-bar:after {
+ display: table;
+ content: "";
+ line-height: 0;
+}
+.component-viewer-header-bar:after {
+ clear: both;
+}
+.component-viewer-header-bar+.component-viewer-header-bar {
+ border-top: 1px solid #e6e6e6;
+}
+.component-viewer-header-component {
+ float: left;
+ line-height: 24px;
+ padding: 6px 10px;
+}
+.component-viewer-header-component-project {
+ color: #777;
+ font-size: 12px;
+}
+.component-viewer-header-component-name {
+ font-weight: 600;
+}
+.component-viewer-header-favorite {
+ position: relative;
+ top: -2px;
+ margin-left: 4px;
+ border-bottom: none;
+}
+.component-viewer-header-measures {
+ float: right;
+}
+.component-viewer-header-measures-scope {
+ position: relative;
+ float: left;
+ height: 60px;
+}
+.component-viewer-header-measures-toggle-scope {
+ position: absolute;
+ top: 0;
+ display: block;
+ width: 100%;
+ height: 6px;
+ margin-bottom: -1px;
+ border-left: 1px solid #f3f3f3;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ background-color: #c7e1f2;
+ border-bottom: none;
+ -webkit-transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ transform-origin: 0 0;
+ transition: all .2s ease;
+}
+.component-viewer-header-measures-toggle-scope:after {
+ content: " ";
+ position: absolute;
+ top: 100%;
+ width: 100%;
+ height: 4px;
+ background-color: transparent;
+}
+.component-viewer-header-measures-toggle-scope:hover {
+ background-color: #89c0e3;
+ -webkit-transform: scale(1, 2);
+ -ms-transform: scale(1, 2);
+ transform: scale(1, 2);
+}
+.component-viewer-header-measures-toggle-scope.active {
+ background-color: #4b9fd5;
+}
+.component-viewer-header-measures-toggle-scope.inactive {
+ background-color: transparent;
+}
+.component-viewer-header-measures-expand {
+ display: block;
+ padding: 11px 20px;
+ white-space: nowrap;
+ border-bottom: none;
+}
+a.component-viewer-header-measures-expand {
+ transition: background .2s ease;
+}
+a.component-viewer-header-measures-expand:hover {
+ background-color: #e6e6e6;
+}
+a.component-viewer-header-measures-expand:active, a.component-viewer-header-measures-expand.active {
+ margin-bottom: -1px;
+ border-bottom: 1px solid #fff;
+ border-left-color: #e6e6e6;
+ background-color: #fff;
+}
+.component-viewer-header-measures-scope+.component-viewer-header-measures-scope {
+ border-left-color: #e6e6e6;
+}
+.component-viewer-header-measures-expand .icon-dropdown {
+ margin-left: 6px;
+ margin-right: -10px;
+ color: #444;
+}
+.component-viewer-header-measure {
+ display: inline-block;
+ vertical-align: middle;
+ font-size: 13px;
+}
+.component-viewer-header-measure .rating {
+ font-size: 18px;
+}
+.component-viewer-header-measure+.component-viewer-header-measure {
+ margin-left: 15px;
+}
+.component-viewer-header-measure-label {
+ display: block;
+ margin-top: 2px;
+ color: #777;
+ font-size: 12px;
+}
+.component-viewer-header-measure-value {
+ display: block;
+ color: #444;
+ font-size: 18px;
+ font-weight: 300;
+}
+.component-viewer-header-measure-value i {
+ position: relative;
+ top: -2px;
+}
+.component-viewer-header-measure-issues {
+ width: 45px;
+}
+.component-viewer-header-measure-issue {
+ min-width: 1px;
+ height: 6px;
+}
+.component-viewer-header-measure-issue.s-blocker {
+ background-color: #d4333f;
+}
+.component-viewer-header-measure-issue.s-critical {
+ background-color: #d4333f;
+}
+.component-viewer-header-measure-issue.s-major {
+ background-color: #d4333f;
+}
+.component-viewer-header-measure-issue.s-minor {
+ background-color: #85bb43;
+}
+.component-viewer-header-measure-issue.s-info {
+ background-color: #85bb43;
+}
+.component-viewer-header-measure-issue+.component-viewer-header-measure-issue {
+ margin-top: 1px;
+}
+.component-viewer-header-actions {
+ float: right;
+ display: block;
+ padding: 20px 10px;
+ font-size: 16px;
+ border-bottom: none;
+}
+.component-viewer-header-more-actions {
+ position: absolute;
+ z-index: 100;
+ right: 0;
+ top: 60px;
+ padding: 10px;
+ border: 1px solid #e6e6e6;
+ background-color: #fff;
+ line-height: 1.8;
+}
+.component-viewer-header-expanded-bar {
+ display: none;
+ position: relative;
+ margin-top: -1px;
+ border: 1px solid #e6e6e6;
+ border-top: none;
+ background-color: #fff;
+}
+.component-viewer-header-expanded-bar:before, .component-viewer-header-expanded-bar:after {
+ display: table;
+ content: "";
+ line-height: 0;
+}
+.component-viewer-header-expanded-bar:after {
+ clear: both;
+}
+.component-viewer-header-expanded-bar.active {
+ display: block;
+}
+.component-viewer-header-expanded-bar-section {
+ display: inline-block;
+ vertical-align: top;
+ width: 250px;
+}
+.component-viewer-header-expanded-bar-section.large {
+ width: 350px;
+}
+.component-viewer-header-expanded-bar-section-actions {
+ margin-left: 15px;
+}
+.component-viewer-header-expanded-bar-section-actions .component-viewer-header-expanded-bar-section-list>li {
+ padding: 4px 0;
+ line-height: 1.5;
+}
+.component-viewer-header-expanded-bar-section-title {
+ padding: 10px 10px 6px;
+ color: #777;
+ font-size: 12px;
+}
+.component-viewer-header-expanded-bar-section-list {
+ max-height: 120px;
+ overflow: auto;
+}
+.component-viewer-header-expanded-bar-section-list::-webkit-scrollbar {
+ width: 11px;
+ background-color: transparent;
+ background-clip: content-box;
+}
+.component-viewer-header-expanded-bar-section-list::-webkit-scrollbar-button {
+ background-color: transparent;
+}
+.component-viewer-header-expanded-bar-section-list::-webkit-scrollbar-corner {
+ background-color: transparent;
+}
+.component-viewer-header-expanded-bar-section-list::-webkit-scrollbar-thumb {
+ border: solid transparent;
+ border-width: 1px 1px 1px 2px;
+ background-color: #c5c5c5;
+ background-clip: content-box;
+}
+.component-viewer-header-expanded-bar-section-list::-webkit-scrollbar-track {
+ border: solid #fff;
+ border-width: 1px 1px 1px 2px;
+ background-color: #fff;
+ background-clip: content-box;
+}
+.component-viewer-header-expanded-bar-section-list::-webkit-scrollbar-track-piece {
+ border-left: 1px solid #ccc;
+ background-color: transparent;
+}
+.component-viewer-header-expanded-bar-section-list>li>.item {
+ position: relative;
+ display: block;
+ padding: 4px 60px 4px 10px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+.component-viewer-header-expanded-bar-section-list>li>.item>.number {
+ position: absolute;
+ right: 25px;
+ top: 50%;
+ margin-top: -8px;
+}
+.component-viewer-header-expanded-bar-section-list>li>.item>i {
+ position: absolute;
+ top: 50%;
+ right: 10px;
+ margin-top: -7px;
+}
+.component-viewer-header-expanded-bar-section-list>li>.item .duration {
+ display: inline-block;
+ min-width: 40px;
+}
+.component-viewer-header-expanded-bar-section-list>li>a.item {
+ color: #444;
+ border-bottom: none;
+ transition: all .2s ease;
+}
+.component-viewer-header-expanded-bar-section-list>li>a.item:hover {
+ background-color: #f3f3f3;
+}
+.component-viewer-header-expanded-bar-section-list>li>a.item:active, .component-viewer-header-expanded-bar-section-list>li>a.item.active {
+ background-color: #cae3f2;
+}
+.component-viewer-header-expanded-bar-bulk-change {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ padding: 4px 10px;
+ font-size: 12px;
+ transition: all .2s ease;
+}
+.component-viewer-header-expanded-bar-bulk-change:hover {
+ background-color: #f3f3f3;
+}
+.component-viewer-header-decoration {
+ margin-top: 10px;
+}
+.component-viewer-header-time-changes {
+ padding: 10px;
+}
+.component-viewer-header-sqale-rating {
+ float: left;
+ font-size: 20px;
+}
+.component-viewer-popup-test {
+ position: relative;
+ display: block;
+ height: 16px;
+ line-height: 16px;
+}
+.component-viewer-popup-test-name {
+ display: block;
+ border-left: 20px solid transparent;
+ border-right: 44px solid transparent;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.component-viewer-popup-test-status {
+ position: absolute;
+ left: 0;
+ top: 50%;
+ margin-top: -8px;
+}
+.component-viewer-popup-test-duration {
+ position: absolute;
+ top: 0;
+ right: 0;
+ color: #777;
+ font-size: 12px;
+}
+.component-viewer-popup-duplications {
+ padding: 4px 0;
+ white-space: normal;
+}
+.component-viewer-popup-label {
+ padding-right: 6px;
+ font-weight: 500;
+}
+@font-face {
+ font-family: 'Source Code Pro';
+ src: url("../fonts/sourcecodepro-regular.woff?00afed99b3447c000639744c33c850fb") format('woff');
+ font-weight: 400;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'Source Code Pro';
+ src: url("../fonts/sourcecodepro-semibold.woff?55455c9c3f3f6090aed1b37a1c19cbf9") format('woff');
+ font-weight: 600;
+ font-style: normal;
+}
+.dsm-legend {
+ margin: 10px 0;
+}
+.dsm-legend>li {
+ display: inline-block;
+}
+.dsm-legend>li+li {
+ margin-left: 20px;
+}
+.dsm-legend-square {
+ display: inline-block;
+ vertical-align: middle;
+ width: 14px;
+ height: 14px;
+}
+.dsm-legend-square.gray {
+ background-color: #efefef;
+}
+.dsm-legend-square.red {
+ background-color: #d4333f;
+}
+.dsm-legend-square.green {
+ background-color: #e2ffbe;
+}
+.dsm-legend-square.blue {
+ background-color: #4b9fd5;
+}
+.dsm-legend-square.yellow {
+ background-color: #fde9cc;
+}
+.dsm-legend-label {
+ display: inline-block;
+ vertical-align: middle;
+ font-size: 13px;
+}
+.dsm-body td {
+ border: 1px solid #e6e6e6;
+}
+.dsm-body-title {
+ position: relative;
+ vertical-align: middle;
+ padding: 2px 15px 2px 4px;
+ border-right: 2px solid #d2d2d2!important;
+ color: #444;
+ cursor: pointer;
+ border-bottom: none;
+ transition: background-color .2s ease;
+}
+.dsm-body-title:hover {
+ background-color: #f3f3f3;
+}
+.dsm-body-cell {
+ min-width: 23px;
+ padding: 2px 4px;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ text-align: center;
+ cursor: pointer;
+ transition: background-color .2s ease;
+}
+.dsm-body-cell-dependency {
+ background-color: #efefef;
+}
+.dsm-body-cell-cycle {
+ background-color: #d4333f!important;
+ color: #fff!important;
+}
+.dsm-body-highlighted {
+ background-color: #dff2fd;
+}
+.dsm-body-highlighted:hover {
+ background-color: #dff2fd;
+}
+.dsm-body-usage, .dsm-body-usage:hover {
+ background-color: #e2ffbe;
+}
+.dsm-body-dependency, .dsm-body-dependency:hover {
+ background-color: #fde9cc;
+}
+.dsm-info {
+ margin-top: 25px;
+}
+.dsm-info th {
+ padding: 2px 5px 7px;
+ font-weight: 500;
+}
+.dsm-info td {
+ padding: 2px 5px;
+}
+.dsm-info td.changed {
+ padding-top: 7px;
+}
+.libraries-header {
+ margin-bottom: 20px;
+ font-size: 0;
+}
+.libraries-header-filter, .libraries-header-test, .libraries-header-actions {
+ display: inline-block;
+ vertical-align: middle;
+ font-size: 13px;
+}
+.libraries-header-test, .libraries-header-actions {
+ margin-left: 30px;
+}
+.libraries-header-actions {
+ margin-right: -10px;
+}
+.libraries-header-actions a {
+ margin-right: 10px;
+}
+.libraries-tree>ul ul {
+ padding-left: 24px;
+}
+.libraries-tree>ul ul ul {
+ margin: 4px 0 4px 8px;
+ padding-left: 16px;
+ border-left: 1px dashed #ddd;
+}
+.libraries-tree>ul>li+li {
+ margin-top: 15px;
+}
+.libraries-tree>ul>li>.libraries-tree-name {
+ font-weight: 500;
+}
+.libraries-tree li {
+ padding: 3px 0;
+}
+.libraries-tree li:last-child {
+ padding-bottom: 0;
+}
+.libraries-tree .icon-dropdown {
+ display: inline-block;
+ width: 10px;
+ visibility: hidden;
+}
+.libraries-tree-subtree-hidden {
+ display: none;
+}
+.libraries-tree-with-subtree>.libraries-tree-name {
+ border-bottom: 1px solid transparent;
+ cursor: pointer;
+ transition: all .2s ease;
+}
+.libraries-tree-with-subtree>.libraries-tree-name:hover {
+ border-color: #ddd;
+}
+.libraries-tree-with-subtree>a>.icon-dropdown {
+ visibility: visible;
+}
+.libraries-tree-subtree-collapsed>ul {
+ display: none;
+}
+.libraries-tree-subtree-collapsed>a>.icon-dropdown:before {
+ content: "\f0da"}
+.libraries-tree-test {
+ display: none;
+}
+.libraries-tree-show-tests .libraries-tree-test {
+ display: list-item;
+}
+.libraries-tree-version {
+ margin: 0 3px;
+ padding: 0 4px;
+ background: #f3f3f3;
+}
+.quality-gates-navigator .navigator-side {
+ display: table-cell;
+ vertical-align: top;
+ width: 250px;
+ min-width: 0;
+}
+.quality-gates-navigator .navigator-header {
+ margin-left: 0;
+}
+.quality-gates-navigator .navigator-header .spinner {
+ margin-top: 9px;
+}
+.quality-gates-navigator .navigator-actions {
+ height: 40px;
+ width: 230px;
+ margin: 10px;
+ padding: 0 10px;
+}
+.quality-gates-navigator .navigator-actions .navigator-header-title {
+ color: #444;
+ font-size: 13px;
+ font-weight: 700;
+ text-transform: uppercase;
+}
+.quality-gates-navigator .navigator-results {
+ width: 230px;
+ min-width: 0;
+}
+.quality-gates-navigator .navigator-details {
+ margin-left: 0;
+}
+.quality-gates-nav .navigator-results-list>li {
+ border-color: transparent;
+}
+.quality-gates-nav .navigator-results-list>li:hover:not(.active):not(.empty) {
+ background-color: #f3f3f3;
+}
+.quality-gates-nav .navigator-results-list>li.active {
+ border-color: #4B9FD5;
+}
+.quality-gates-nav .navigator-results-list>li.empty {
+ cursor: default;
+}
+.quality-gates-nav .navigator-results-list>li .line {
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.quality-gates-nav .navigator-results-list>li .subtitle {
+ text-transform: lowercase;
+}
+.quality-gate-section+.quality-gate-section {
+ margin-top: 10px;
+ padding-top: 20px;
+}
+.quality-gate-section-empty+.quality-gate-section {
+ border-top: 1px solid #e6e6e6;
+}
+.quality-gate-section-name {
+ margin-bottom: 10px;
+ font-weight: 700;
+ text-transform: uppercase;
+}
+.quality-gate-introduction {
+ margin-bottom: 20px;
+}
+.quality-gate-new-condition {
+ margin-bottom: 10px;
+}
+.quality-gate-condition-actions {
+ position: relative;
+}
+.quality-gate-default-message {
+ padding: 6px 5px;
+ border: 1px solid #ddd;
+ background-color: #efefef;
+}
+.quality-gate-conditions-wrap {
+ border-left: 1px solid #ddd;
+ border-right: 1px solid #ddd;
+}
+.quality-gate-conditions .deprecated {
+ color: #777;
+ text-transform: lowercase;
+ font-variant: small-caps;
+}
+.quality-gate-conditions tbody {
+ border-left: none!important;
+ border-right: none!important;
+}
diff --git a/projects/languages/css/css-sonar-runner/validation.txt b/projects/languages/css/css-sonar-runner/validation.txt
new file mode 100644
index 00000000..1a250122
--- /dev/null
+++ b/projects/languages/css/css-sonar-runner/validation.txt
@@ -0,0 +1,11 @@
+start server
+ with plugin css 1.5
+sonar-runner
+verify org.sonarqube:css-simple-sq-scanner
+ measure lines is 7258
+ measure ncloc is 7254
+ measure files is 2
+verify org.sonarqube:css-simple-sq-scanner:src/sonar.css
+ measure lines is 7169
+ measure ncloc is 7165
+stop server
diff --git a/projects/languages/erlang/README.md b/projects/languages/erlang/README.md
new file mode 100644
index 00000000..b424549f
--- /dev/null
+++ b/projects/languages/erlang/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a simple Erlang project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Erlang Plugin](https://github.com/SonarCommunity/sonar-erlang) 1.2+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/erlang/sonar-project.properties b/projects/languages/erlang/sonar-project.properties
new file mode 100644
index 00000000..7bb015c5
--- /dev/null
+++ b/projects/languages/erlang/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:erlang-simple-sq-scanner
+sonar.projectName=Erlang :: Simple Project :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=erlang
+
+# Encoding of sources files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/erlang/src/hello.erl b/projects/languages/erlang/src/hello.erl
new file mode 100644
index 00000000..cabba3b9
--- /dev/null
+++ b/projects/languages/erlang/src/hello.erl
@@ -0,0 +1,4 @@
+-module(hello).
+-export([hello_world/0]).
+
+hello_world() -> io:fwrite("hello, world\n").
diff --git a/projects/languages/flex/flex-sonar-runner-coverage/README.md b/projects/languages/flex/flex-sonar-runner-coverage/README.md
new file mode 100644
index 00000000..2c58ac18
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner-coverage/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a Flex project with the SonarQube Scanner and retrieving code coverage data from a Cobertura report.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Flex Plugin](http://docs.sonarqube.org/display/PLUG/Flex+Plugin) 2.2.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/flex/flex-sonar-runner-coverage/report/coverage.xml b/projects/languages/flex/flex-sonar-runner-coverage/report/coverage.xml
new file mode 100644
index 00000000..ddee7657
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner-coverage/report/coverage.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+ src
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/flex/flex-sonar-runner-coverage/sonar-project.properties b/projects/languages/flex/flex-sonar-runner-coverage/sonar-project.properties
new file mode 100644
index 00000000..608514f9
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner-coverage/sonar-project.properties
@@ -0,0 +1,16 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:flex-coverage-sq-scanner
+sonar.projectName=Flex :: Coverage :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=flex
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
+
+# Retrieve code coverage data from the Cobertura report
+sonar.flex.cobertura.reportPath=report/coverage.xml
diff --git a/projects/languages/flex/flex-sonar-runner-coverage/src/Circle.as b/projects/languages/flex/flex-sonar-runner-coverage/src/Circle.as
new file mode 100644
index 00000000..b371db1a
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner-coverage/src/Circle.as
@@ -0,0 +1,10 @@
+package {
+
+ public class Circle {
+ public var diameter:int = 0;
+
+ function Circle (d:int) {
+ this.diameter = d;
+ }
+ }
+}
diff --git a/projects/languages/flex/flex-sonar-runner-coverage/src/UncoveredCircle.as b/projects/languages/flex/flex-sonar-runner-coverage/src/UncoveredCircle.as
new file mode 100644
index 00000000..e0a66503
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner-coverage/src/UncoveredCircle.as
@@ -0,0 +1,10 @@
+package {
+
+ public class UncoveredCircle {
+ public var diameter:int = 0;
+
+ function UncoveredCircle (d:int) {
+ this.diameter = d;
+ }
+ }
+}
diff --git a/projects/languages/flex/flex-sonar-runner-coverage/validation.txt b/projects/languages/flex/flex-sonar-runner-coverage/validation.txt
new file mode 100644
index 00000000..9e64d6a9
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner-coverage/validation.txt
@@ -0,0 +1,18 @@
+start server
+ with plugin flex 2.2.1
+sonar-runner
+verify org.sonarqube:flex-coverage-sq-scanner
+ measure lines is 22
+ measure ncloc is 16
+ measure files is 2
+ measure classes is 2
+ measure coverage is 50
+verify org.sonarqube:flex-coverage-sq-scanner:src/Circle.as
+ measure lines is 11
+ measure ncloc is 8
+ measure coverage is 100
+verify org.sonarqube:flex-coverage-sq-scanner:src/UncoveredCircle.as
+ measure lines is 11
+ measure ncloc is 8
+ measure coverage is 0
+stop server
diff --git a/projects/languages/flex/flex-sonar-runner/README.md b/projects/languages/flex/flex-sonar-runner/README.md
new file mode 100644
index 00000000..ac49377f
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a Flex project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Flex Plugin](http://docs.sonarqube.org/display/PLUG/Flex+Plugin) 2.2.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/flex/flex-sonar-runner/sonar-project.properties b/projects/languages/flex/flex-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..722104e5
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:flex-simple-sq-scanner
+sonar.projectName=Flex :: Simple Project :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=flex
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/flex/flex-sonar-runner/src/Greeter.as b/projects/languages/flex/flex-sonar-runner/src/Greeter.as
new file mode 100644
index 00000000..2471a186
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner/src/Greeter.as
@@ -0,0 +1,13 @@
+package
+{
+ public class Greeter
+ {
+ public function sayHello():String
+ {
+ var greeting:String;
+ greeting = "Hello World!";
+ if (1 == 1) {}
+ return greeting;
+ }
+ }
+}
diff --git a/projects/languages/flex/flex-sonar-runner/validation.txt b/projects/languages/flex/flex-sonar-runner/validation.txt
new file mode 100644
index 00000000..28e249b7
--- /dev/null
+++ b/projects/languages/flex/flex-sonar-runner/validation.txt
@@ -0,0 +1,12 @@
+start server
+ with plugin flex 2.2.1
+sonar-runner
+verify org.sonarqube:flex-simple-sq-scanner
+ measure lines is 14
+ measure ncloc is 13
+ measure files is 1
+ measure classes is 1
+verify org.sonarqube:flex-simple-sq-scanner:src/Greeter.as
+ measure lines is 14
+ measure ncloc is 13
+stop server
diff --git a/projects/languages/generic-coverage/sonar-runner/README.md b/projects/languages/generic-coverage/sonar-runner/README.md
new file mode 100644
index 00000000..f576c7b2
--- /dev/null
+++ b/projects/languages/generic-coverage/sonar-runner/README.md
@@ -0,0 +1,14 @@
+This example demonstrates how to use the generic coverage plugin with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Generic Coverage Plugin](http://docs.sonarqube.org/display/PLUG/Generic+Test+Coverage) 1.2+
+* [SonarQube Javascript Plugin](http://docs.sonarqube.org/display/PLUG/JavaScript+Plugin) 2.12
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/generic-coverage/sonar-runner/report/coverage.xml b/projects/languages/generic-coverage/sonar-runner/report/coverage.xml
new file mode 100644
index 00000000..ac460327
--- /dev/null
+++ b/projects/languages/generic-coverage/sonar-runner/report/coverage.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/generic-coverage/sonar-runner/report/itcoverage.xml b/projects/languages/generic-coverage/sonar-runner/report/itcoverage.xml
new file mode 100644
index 00000000..ac460327
--- /dev/null
+++ b/projects/languages/generic-coverage/sonar-runner/report/itcoverage.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/generic-coverage/sonar-runner/report/unittest.xml b/projects/languages/generic-coverage/sonar-runner/report/unittest.xml
new file mode 100644
index 00000000..6e4bc9cb
--- /dev/null
+++ b/projects/languages/generic-coverage/sonar-runner/report/unittest.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ message
+
+
+
+
+
+ long long stacktrace
+
+
+
+
diff --git a/projects/languages/generic-coverage/sonar-runner/sonar-project.properties b/projects/languages/generic-coverage/sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..bf3d1516
--- /dev/null
+++ b/projects/languages/generic-coverage/sonar-runner/sonar-project.properties
@@ -0,0 +1,17 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:example-generic-coverage-sonar-scanner
+sonar.projectName=Example of Generic Test Coverage Reports Import :: SonarQube Scanner
+sonar.projectDescription=Example of Import of UT Execution Results Report and UT/IT Coverage Report Import
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src/main/java,src/main/js
+sonar.tests=src/test/java,src/test/js
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
+
+sonar.genericcoverage.reportPaths=report/coverage.xml
+sonar.genericcoverage.itReportPaths=report/itcoverage.xml
+sonar.genericcoverage.unitTestReportPaths=report/unittest.xml
+
diff --git a/projects/languages/generic-coverage/sonar-runner/src/main/java/FooBar.java b/projects/languages/generic-coverage/sonar-runner/src/main/java/FooBar.java
new file mode 100644
index 00000000..e5b8cd77
--- /dev/null
+++ b/projects/languages/generic-coverage/sonar-runner/src/main/java/FooBar.java
@@ -0,0 +1,10 @@
+public class FooBar {
+
+ public int process(int a) {
+ if (a > 1 && a < 10) {
+ return a;
+ }
+ return 0;
+ }
+
+}
diff --git a/projects/languages/generic-coverage/sonar-runner/src/main/js/foo.js b/projects/languages/generic-coverage/sonar-runner/src/main/js/foo.js
new file mode 100644
index 00000000..6ddcc7ac
--- /dev/null
+++ b/projects/languages/generic-coverage/sonar-runner/src/main/js/foo.js
@@ -0,0 +1,6 @@
+function process() {
+ if (i > 3) {
+ return i;
+ }
+ return 0;
+}
diff --git a/projects/languages/generic-coverage/sonar-runner/src/test/java/FooBarTest.java b/projects/languages/generic-coverage/sonar-runner/src/test/java/FooBarTest.java
new file mode 100644
index 00000000..9c49f63f
--- /dev/null
+++ b/projects/languages/generic-coverage/sonar-runner/src/test/java/FooBarTest.java
@@ -0,0 +1,10 @@
+public class FooBar {
+
+ public int test(int a) {
+ if (a > 1 && a < 10) {
+ return a;
+ }
+ return 0;
+ }
+
+}
diff --git a/projects/languages/generic-coverage/sonar-runner/src/test/js/test_foo.js b/projects/languages/generic-coverage/sonar-runner/src/test/js/test_foo.js
new file mode 100644
index 00000000..6ddcc7ac
--- /dev/null
+++ b/projects/languages/generic-coverage/sonar-runner/src/test/js/test_foo.js
@@ -0,0 +1,6 @@
+function process() {
+ if (i > 3) {
+ return i;
+ }
+ return 0;
+}
diff --git a/projects/languages/groovy/groovy-maven/README.md b/projects/languages/groovy/groovy-maven/README.md
new file mode 100644
index 00000000..d270c817
--- /dev/null
+++ b/projects/languages/groovy/groovy-maven/README.md
@@ -0,0 +1,17 @@
+This example demonstrates how to analyze a Groovy project with Maven.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Groovy Plugin](http://docs.sonarqube.org/display/PLUG/Groovy+Plugin) 1.3.1+
+* Maven 3.0+
+
+Usage
+=====
+* Compile the project:
+
+ mvn clean install
+
+* Analyze it with SonarQube using Maven:
+
+ mvn sonar:sonar
diff --git a/projects/languages/groovy/groovy-maven/pom.xml b/projects/languages/groovy/groovy-maven/pom.xml
new file mode 100644
index 00000000..639dca67
--- /dev/null
+++ b/projects/languages/groovy/groovy-maven/pom.xml
@@ -0,0 +1,54 @@
+
+
+ 4.0.0
+
+ org.sonarqube
+ example-groovy-maven
+ 1.0-SNAPSHOT
+
+ Simple Groovy Project Analyzed with Maven
+
+
+ UTF-8
+ grvy
+
+
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.4.7
+
+
+ junit
+ junit
+ 3.8.2
+ test
+
+
+
+
+ src/main/groovy
+
+
+ org.codehaus.gmaven
+ gmaven-plugin
+ 1.4
+
+ 1.8
+
+
+
+
+ generateStubs
+ compile
+ generateTestStubs
+ testCompile
+
+
+
+
+
+
+
+
diff --git a/projects/languages/groovy/groovy-maven/src/main/groovy/example/Greeting.groovy b/projects/languages/groovy/groovy-maven/src/main/groovy/example/Greeting.groovy
new file mode 100644
index 00000000..ef635498
--- /dev/null
+++ b/projects/languages/groovy/groovy-maven/src/main/groovy/example/Greeting.groovy
@@ -0,0 +1,7 @@
+package example
+
+class Greeting {
+ def say() {
+ println 'Hello World'
+ }
+}
diff --git a/projects/languages/groovy/groovy-maven/src/main/groovy/innerclass/InnerClassExample.groovy b/projects/languages/groovy/groovy-maven/src/main/groovy/innerclass/InnerClassExample.groovy
new file mode 100644
index 00000000..caf298d2
--- /dev/null
+++ b/projects/languages/groovy/groovy-maven/src/main/groovy/innerclass/InnerClassExample.groovy
@@ -0,0 +1,14 @@
+package innerclass
+
+class InnerClassExample
+{
+ def show() {
+ println 'Hello World'
+ new ExampleInnerClass().show()
+ }
+
+ class ExampleInnerClass {
+ def show() { println "Hello Inner"}
+ }
+
+}
diff --git a/projects/languages/groovy/groovy-maven/src/test/groovy/example/GreetingTest.groovy b/projects/languages/groovy/groovy-maven/src/test/groovy/example/GreetingTest.groovy
new file mode 100644
index 00000000..a66eb686
--- /dev/null
+++ b/projects/languages/groovy/groovy-maven/src/test/groovy/example/GreetingTest.groovy
@@ -0,0 +1,7 @@
+package example
+
+class GreetingTest extends GroovyTestCase {
+ void testSay() {
+ new Greeting().say()
+ }
+}
diff --git a/projects/languages/groovy/groovy-sonar-runner-cobertura/README.md b/projects/languages/groovy/groovy-sonar-runner-cobertura/README.md
new file mode 100644
index 00000000..fb538049
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-cobertura/README.md
@@ -0,0 +1,14 @@
+This example demonstrates how to analyze a Groovy project with the SonarQube Scanner.
+It reuses existing Cobertura report.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Groovy Plugin](http://docs.sonarqube.org/display/PLUG/Groovy+Plugin) 1.3.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/groovy/groovy-sonar-runner-cobertura/reports/cobertura.xml b/projects/languages/groovy/groovy-sonar-runner-cobertura/reports/cobertura.xml
new file mode 100644
index 00000000..4c1a3d29
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-cobertura/reports/cobertura.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+ C:/git/sonar-examples/projects/languages/groovy/groovy-maven/target/generated-sources/groovy-stubs/main
+ --source
+ C:/git/sonar-examples/projects/languages/groovy/groovy-maven/src/main/groovy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/groovy/groovy-sonar-runner-cobertura/sonar-project.properties b/projects/languages/groovy/groovy-sonar-runner-cobertura/sonar-project.properties
new file mode 100644
index 00000000..644b9527
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-cobertura/sonar-project.properties
@@ -0,0 +1,12 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:groovy-cobertura-sq-scanner
+sonar.projectName=Groovy :: Cobertura :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.sources=src
+sonar.language=grvy
+sonar.sourceEncoding=UTF-8
+
+# Path to the Cobertura XML report
+sonar.groovy.cobertura.reportPath=reports/cobertura.xml
+
diff --git a/projects/languages/groovy/groovy-sonar-runner-cobertura/src/example/Greeting.groovy b/projects/languages/groovy/groovy-sonar-runner-cobertura/src/example/Greeting.groovy
new file mode 100644
index 00000000..ef635498
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-cobertura/src/example/Greeting.groovy
@@ -0,0 +1,7 @@
+package example
+
+class Greeting {
+ def say() {
+ println 'Hello World'
+ }
+}
diff --git a/projects/languages/groovy/groovy-sonar-runner-cobertura/src/innerclass/InnerClassExample.groovy b/projects/languages/groovy/groovy-sonar-runner-cobertura/src/innerclass/InnerClassExample.groovy
new file mode 100644
index 00000000..caf298d2
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-cobertura/src/innerclass/InnerClassExample.groovy
@@ -0,0 +1,14 @@
+package innerclass
+
+class InnerClassExample
+{
+ def show() {
+ println 'Hello World'
+ new ExampleInnerClass().show()
+ }
+
+ class ExampleInnerClass {
+ def show() { println "Hello Inner"}
+ }
+
+}
diff --git a/projects/languages/groovy/groovy-sonar-runner-cobertura/val.deactivated b/projects/languages/groovy/groovy-sonar-runner-cobertura/val.deactivated
new file mode 100644
index 00000000..a5f10734
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-cobertura/val.deactivated
@@ -0,0 +1,14 @@
+start server
+ with plugin groovy 1.3.1
+sonar-runner
+verify org.sonarqube:groovy-cobertura-sq-scanner
+ measure lines is 23
+ measure ncloc is 17
+ measure files is 2
+ measure classes is 3
+ measure coverage is 25.0
+verify org.sonarqube:groovy-cobertura-sq-scanner:src/example/Greeting.groovy
+ measure lines is 8
+ measure ncloc is 6
+ measure coverage is 100.0
+stop server
diff --git a/projects/languages/groovy/groovy-sonar-runner-jacoco/README.md b/projects/languages/groovy/groovy-sonar-runner-jacoco/README.md
new file mode 100644
index 00000000..0172d2bd
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-jacoco/README.md
@@ -0,0 +1,18 @@
+This example demonstrates how to import JaCoCo reports with a maven project
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Groovy Plugin](http://docs.sonarqube.org/display/PLUG/Groovy+Plugin) 1.3.1+
+* Maven 3.0+
+
+Usage
+=====
+* Compile the project:
+
+ mvn clean install
+
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/groovy/groovy-sonar-runner-jacoco/pom.xml b/projects/languages/groovy/groovy-sonar-runner-jacoco/pom.xml
new file mode 100644
index 00000000..cfcfb998
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-jacoco/pom.xml
@@ -0,0 +1,146 @@
+
+
+ 4.0.0
+
+ org.sonarqube
+ groovy-sonar-runner-jacoco
+ 1.0-SNAPSHOT
+
+
+ UTF-8
+ UTF-8
+ false
+ false
+ 0.8.7
+
+
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.4.7
+
+
+ junit
+ junit
+ 4.10
+ test
+
+
+ org.jacoco
+ org.jacoco.core
+ ${jacoco.version}
+
+
+
+
+ src/main/groovy
+
+
+ org.codehaus.gmaven
+ gmaven-plugin
+ 1.5
+
+ 2.0
+
+
+
+
+ generateTestStubs
+ compile
+ generateTestStubs
+ testCompile
+
+
+
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.4.7
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.15
+
+ ${surefireArgLine}
+ ${skip.unit.tests}
+
+ **/IT*.groovy
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 2.15
+
+
+ integration-tests
+
+ integration-test
+ verify
+
+
+ ${failsafeArgLine}
+ ${skip.integration.tests}
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+ default-prepare-agent
+
+ prepare-agent
+
+
+ ${project.build.directory}/coverage-reports/jacoco-ut.exec
+ surefireArgLine
+
+
+
+ post-unit-test
+ test
+
+ report
+
+
+ ${project.build.directory}/coverage-reports/jacoco-ut.exec
+ ${project.reporting.outputDirectory}/jacoco-ut
+
+
+
+ pre-integration-test
+ pre-integration-test
+
+ prepare-agent
+
+
+ ${project.build.directory}/coverage-reports/jacoco-it.exec
+ failsafeArgLine
+
+
+
+ post-integration-test
+ post-integration-test
+
+ report
+
+
+ ${project.build.directory}/coverage-reports/jacoco-it.exec
+ ${project.reporting.outputDirectory}/jacoco-it
+
+
+
+
+
+
+
diff --git a/projects/languages/groovy/groovy-sonar-runner-jacoco/sonar-project.properties b/projects/languages/groovy/groovy-sonar-runner-jacoco/sonar-project.properties
new file mode 100644
index 00000000..13fee169
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-jacoco/sonar-project.properties
@@ -0,0 +1,25 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:groovy-jacoco-sq-scanner
+sonar.projectName=Groovy :: JaCoCo :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src/main/groovy
+# Comma-separated paths to directories with tests (required if you want to load UT Exec Reports)
+sonar.tests=src/test/groovy
+
+# Language
+sonar.language=grvy
+
+# Comma-separated paths to directories with binaries (required)
+sonar.binaries=target/classes
+
+# JaCoCo exec files
+sonar.groovy.jacoco.reportPath=target/coverage-reports/jacoco-ut.exec
+sonar.groovy.jacoco.itReportPath=target/coverage-reports/jacoco-it.exec
+
+# Unit Tests Execution Reports
+sonar.junit.reportsPath=target/surefire-reports
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/projects/languages/groovy/groovy-sonar-runner-jacoco/src/main/groovy/example/Hello.groovy b/projects/languages/groovy/groovy-sonar-runner-jacoco/src/main/groovy/example/Hello.groovy
new file mode 100644
index 00000000..c3ae4f70
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-jacoco/src/main/groovy/example/Hello.groovy
@@ -0,0 +1,50 @@
+package example;
+
+class Hello {
+
+ def name
+ def innerClass
+
+ Hello(name) {
+ this.name = name
+ this.innerClass = new InnerClass()
+ }
+
+ String salute() {
+ if (name != null) {
+ return "Hello $name!"
+ }
+ return "Hello!"
+ }
+
+ def sayHelloToUnitTests() {
+ println "Hello Unit Tests"
+ }
+
+ def sayHelloToIntegrationTests() {
+ println "Hello Integration Tests"
+ }
+
+ def branches(boolean test) {
+ if (test) {
+ println "branch 1"
+ } else {
+ println "branch 2"
+ println "branch 2 bis"
+ }
+ }
+
+ def notcovered() {
+ println "Not covered"
+ }
+
+ def bar() {
+ innerClass.foo()
+ }
+
+ class InnerClass {
+ void foo() {
+ println "foo"
+ }
+ }
+}
diff --git a/projects/languages/groovy/groovy-sonar-runner-jacoco/src/test/groovy/example/HelloIT.groovy b/projects/languages/groovy/groovy-sonar-runner-jacoco/src/test/groovy/example/HelloIT.groovy
new file mode 100644
index 00000000..a4010d71
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-jacoco/src/test/groovy/example/HelloIT.groovy
@@ -0,0 +1,13 @@
+package example;
+
+import org.junit.Test;
+
+class HelloIT {
+
+ @Test
+ void test_sayHelloToIntegrationTests() {
+ def hello = new Hello()
+ hello.sayHelloToIntegrationTests()
+ assert hello != null
+ }
+}
diff --git a/projects/languages/groovy/groovy-sonar-runner-jacoco/src/test/groovy/example/HelloTest.groovy b/projects/languages/groovy/groovy-sonar-runner-jacoco/src/test/groovy/example/HelloTest.groovy
new file mode 100644
index 00000000..f0c274dc
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner-jacoco/src/test/groovy/example/HelloTest.groovy
@@ -0,0 +1,37 @@
+package example;
+
+import org.junit.Test;
+
+class HelloTest {
+
+ @Test
+ void test_salute_full_coverage() {
+ def hello = new Hello()
+ assert hello != null
+ assert hello.name == null
+ assert hello.salute().equals("Hello!")
+
+ hello = new Hello("Nico")
+ assert hello != null
+ assert hello.name != null
+ assert hello.salute() == "Hello Nico!"
+ }
+
+ @Test
+ void test_sayHelloToUnitTests() {
+ def hello = new Hello()
+ hello.sayHelloToUnitTests()
+ }
+
+ @Test
+ void test_branches_partial_coverage() {
+ def hello = new Hello()
+ hello.branches(false);
+ }
+
+ @Test
+ void test_inner_class() {
+ def hello = new Hello()
+ hello.bar()
+ }
+}
diff --git a/projects/languages/groovy/groovy-sonar-runner/README.md b/projects/languages/groovy/groovy-sonar-runner/README.md
new file mode 100644
index 00000000..50b9120c
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a Groovy project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Groovy Plugin](http://docs.sonarqube.org/display/PLUG/Groovy+Plugin) 1.3.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
\ No newline at end of file
diff --git a/projects/languages/groovy/groovy-sonar-runner/sonar-project.properties b/projects/languages/groovy/groovy-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..48ec5c51
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner/sonar-project.properties
@@ -0,0 +1,14 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:groovy-simple-sq-scanner
+sonar.projectName=Groovy :: Simple Project :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=grvy
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
+
diff --git a/projects/languages/groovy/groovy-sonar-runner/src/example/Greeting.groovy b/projects/languages/groovy/groovy-sonar-runner/src/example/Greeting.groovy
new file mode 100644
index 00000000..ef635498
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner/src/example/Greeting.groovy
@@ -0,0 +1,7 @@
+package example
+
+class Greeting {
+ def say() {
+ println 'Hello World'
+ }
+}
diff --git a/projects/languages/groovy/groovy-sonar-runner/src/innerclass/InnerClassExample.groovy b/projects/languages/groovy/groovy-sonar-runner/src/innerclass/InnerClassExample.groovy
new file mode 100644
index 00000000..caf298d2
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner/src/innerclass/InnerClassExample.groovy
@@ -0,0 +1,14 @@
+package innerclass
+
+class InnerClassExample
+{
+ def show() {
+ println 'Hello World'
+ new ExampleInnerClass().show()
+ }
+
+ class ExampleInnerClass {
+ def show() { println "Hello Inner"}
+ }
+
+}
diff --git a/projects/languages/groovy/groovy-sonar-runner/validation.txt b/projects/languages/groovy/groovy-sonar-runner/validation.txt
new file mode 100644
index 00000000..bfa425be
--- /dev/null
+++ b/projects/languages/groovy/groovy-sonar-runner/validation.txt
@@ -0,0 +1,12 @@
+start server
+ with plugin groovy 1.3.1
+sonar-runner
+verify org.sonarqube:groovy-simple-sq-scanner
+ measure lines is 23
+ measure ncloc is 17
+ measure files is 2
+ measure classes is 3
+verify org.sonarqube:groovy-simple-sq-scanner:src/example/Greeting.groovy
+ measure lines is 8
+ measure ncloc is 6
+stop server
diff --git a/projects/languages/java/ant/java-ant-simple/README.md b/projects/languages/java/ant/java-ant-simple/README.md
new file mode 100644
index 00000000..8f14c608
--- /dev/null
+++ b/projects/languages/java/ant/java-ant-simple/README.md
@@ -0,0 +1,15 @@
+This example demonstrates how to analyze a simple Java project with Ant.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner for Ant](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Ant) 2.4.1+
+* [Ant](http://ant.apache.org/) 1.7.1 or higher
+
+Usage
+=====
+* Set the path to the SonarQube Ant Task in the build.xml file
+* Set the sonar.jdbc.* properties in the build.xml file
+* Run the following command:
+
+ ant all
diff --git a/projects/languages/java/ant/java-ant-simple/build.xml b/projects/languages/java/ant/java-ant-simple/build.xml
new file mode 100644
index 00000000..2b6e3a77
--- /dev/null
+++ b/projects/languages/java/ant/java-ant-simple/build.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/java/ant/java-ant-simple/src/One.java b/projects/languages/java/ant/java-ant-simple/src/One.java
new file mode 100644
index 00000000..1ff2941e
--- /dev/null
+++ b/projects/languages/java/ant/java-ant-simple/src/One.java
@@ -0,0 +1,11 @@
+public class One {
+ String message = "foo";
+
+ public String foo() {
+ return message;
+ }
+
+ public void uncoveredMethod() {
+ System.out.println(foo());
+ }
+}
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/README.md b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/README.md
new file mode 100644
index 00000000..e2ab2808
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/README.md
@@ -0,0 +1,17 @@
+This example demonstrates how to collect code coverage by integration tests, tests are located in a separate Java Maven module.
+SonarQube aggregates code coverage by unit tests and integration tests to compute an overall code coverage (this feature requires SonarQube 4.5+).
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* Maven 2.2.1 or higher
+
+Usage
+=====
+* Build the project and execute all the tests:
+
+ mvn clean install
+
+* Analyze the project with SonarQube using Maven:
+
+ mvn sonar:sonar
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app-it/pom.xml b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app-it/pom.xml
new file mode 100644
index 00000000..22e1fdcf
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app-it/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+
+ org.sonarqube
+ parent
+ 1.0-SNAPSHOT
+
+
+ app-it
+
+ Java :: JaCoco Multi Modules :: App IT
+
+
+
+ ${project.groupId}
+ app
+ ${project.version}
+
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+
+ ${project.basedir}/../target/jacoco-it.exec
+
+
+
+
+
+
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app-it/src/test/java/example/HelloWorldIntegrationTest.java b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app-it/src/test/java/example/HelloWorldIntegrationTest.java
new file mode 100644
index 00000000..0183c6d7
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app-it/src/test/java/example/HelloWorldIntegrationTest.java
@@ -0,0 +1,12 @@
+package example;
+
+import org.junit.Test;
+
+public class HelloWorldIntegrationTest {
+
+ @Test
+ public void test() {
+ new HelloWorld().coveredByIntegrationTest();
+ }
+
+}
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app/pom.xml b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app/pom.xml
new file mode 100644
index 00000000..d3846cf9
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app/pom.xml
@@ -0,0 +1,15 @@
+
+
+ 4.0.0
+
+
+ org.sonarqube
+ parent
+ 1.0-SNAPSHOT
+
+
+ app
+
+ Java :: JaCoco Multi Modules :: App
+
+
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app/src/main/java/example/HelloWorld.java b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app/src/main/java/example/HelloWorld.java
new file mode 100644
index 00000000..48cb48e6
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app/src/main/java/example/HelloWorld.java
@@ -0,0 +1,20 @@
+package example;
+
+public class HelloWorld {
+
+ public void coveredByUnitTest() {
+ System.out.println("coveredByUnitTest1");
+ System.out.println("coveredByUnitTest2");
+ }
+
+ public void coveredByIntegrationTest() {
+ System.out.println("coveredByIntegrationTest1");
+ System.out.println("coveredByIntegrationTest2");
+ System.out.println("coveredByIntegrationTest3");
+ }
+
+ public void notCovered() {
+ System.out.println("notCovered");
+ }
+
+}
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app/src/test/java/example/HelloWorldUnitTest.java b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app/src/test/java/example/HelloWorldUnitTest.java
new file mode 100644
index 00000000..44231b7f
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/app/src/test/java/example/HelloWorldUnitTest.java
@@ -0,0 +1,12 @@
+package example;
+
+import org.junit.Test;
+
+public class HelloWorldUnitTest {
+
+ @Test
+ public void test() {
+ new HelloWorld().coveredByUnitTest();
+ }
+
+}
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/pom.xml b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/pom.xml
new file mode 100644
index 00000000..d4a3d305
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-multimodule-maven-jacoco/pom.xml
@@ -0,0 +1,101 @@
+
+
+ 4.0.0
+
+ org.sonarqube
+ parent
+ pom
+ 1.0-SNAPSHOT
+
+ Java :: JaCoco Multi Modules :: Parent
+
+
+ app
+ app-it
+
+
+
+ UTF-8
+ UTF-8
+
+
+
+ ${project.basedir}/../target/jacoco-it.exec
+ java
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.5
+ 1.5
+
+
+
+
+
+
+
+ sonar-coverage
+
+ true
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.7.2.201409121644
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+ true
+
+
+
+ agent-for-ut
+
+ prepare-agent
+
+
+
+ agent-for-it
+
+ prepare-agent-integration
+
+
+
+ jacoco-site
+ verify
+
+ report
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/README.md b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/README.md
new file mode 100644
index 00000000..d0f045d1
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/README.md
@@ -0,0 +1,14 @@
+This example demonstrates how to collect code coverage by unit tests and integration tests.
+SonarQube aggregates these code coverage data to compute an overall code coverage.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Java Plugin](http://docs.sonarqube.org/display/PLUG/Java+Plugin) 3.13+
+
+Usage
+=====
+* Analyze the project with SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/classes/example/HelloWorld.class b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/classes/example/HelloWorld.class
new file mode 100644
index 00000000..dd0da84b
Binary files /dev/null and b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/classes/example/HelloWorld.class differ
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/jacoco/jacoco-it.exec b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/jacoco/jacoco-it.exec
new file mode 100644
index 00000000..0d39ceee
Binary files /dev/null and b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/jacoco/jacoco-it.exec differ
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/jacoco/jacoco-ut.exec b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/jacoco/jacoco-ut.exec
new file mode 100644
index 00000000..fc44ddbc
Binary files /dev/null and b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/jacoco/jacoco-ut.exec differ
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/junit/TEST-example.HelloWorldUnitTest.xml b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/junit/TEST-example.HelloWorldUnitTest.xml
new file mode 100644
index 00000000..e913fc42
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/junit/TEST-example.HelloWorldUnitTest.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/junit/example.HelloWorldUnitTest.txt b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/junit/example.HelloWorldUnitTest.txt
new file mode 100644
index 00000000..d44947ee
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/reports/junit/example.HelloWorldUnitTest.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: example.HelloWorldUnitTest
+-------------------------------------------------------------------------------
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.065 sec
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/sonar-project.properties b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/sonar-project.properties
new file mode 100644
index 00000000..65b5031a
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/sonar-project.properties
@@ -0,0 +1,21 @@
+sonar.projectKey=org.sonarqube:java-ut-it-jacoco-sq-scanner
+sonar.projectName=Java :: UT + IT Jacoco :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.sources=src/main/java
+sonar.tests=src/test/java
+sonar.java.binaries=classes
+
+sonar.language=java
+
+#Tells SonarQube where the unit tests execution reports are
+sonar.junit.reportsPath=reports/junit
+
+#Tells SonarQube where the unit tests code coverage report is
+sonar.jacoco.reportPath=reports/jacoco/jacoco-ut.exec
+
+#Tells SonarQube where the integration tests code coverage report is
+sonar.jacoco.itReportPath=reports/jacoco/jacoco-it.exec
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/src/main/java/example/HelloWorld.java b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/src/main/java/example/HelloWorld.java
new file mode 100644
index 00000000..48cb48e6
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/src/main/java/example/HelloWorld.java
@@ -0,0 +1,20 @@
+package example;
+
+public class HelloWorld {
+
+ public void coveredByUnitTest() {
+ System.out.println("coveredByUnitTest1");
+ System.out.println("coveredByUnitTest2");
+ }
+
+ public void coveredByIntegrationTest() {
+ System.out.println("coveredByIntegrationTest1");
+ System.out.println("coveredByIntegrationTest2");
+ System.out.println("coveredByIntegrationTest3");
+ }
+
+ public void notCovered() {
+ System.out.println("notCovered");
+ }
+
+}
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/src/test/java/example/HelloWorldUnitTest.java b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/src/test/java/example/HelloWorldUnitTest.java
new file mode 100644
index 00000000..44231b7f
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/src/test/java/example/HelloWorldUnitTest.java
@@ -0,0 +1,12 @@
+package example;
+
+import org.junit.Test;
+
+public class HelloWorldUnitTest {
+
+ @Test
+ public void test() {
+ new HelloWorld().coveredByUnitTest();
+ }
+
+}
diff --git a/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/validation.txt b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/validation.txt
new file mode 100644
index 00000000..60e7a9fe
--- /dev/null
+++ b/projects/languages/java/code-coverage/combined ut-it/combined-ut-it-sonar-runner-jacoco/validation.txt
@@ -0,0 +1,21 @@
+start server
+ with plugin java 3.10
+sonar-runner
+verify org.sonarqube:java-ut-it-jacoco-sq-scanner
+ measure lines is 21
+ measure ncloc is 15
+ measure files is 1
+ measure classes is 1
+ measure tests is 1
+ measure test_success_density is 100.0
+ measure coverage is 40.0
+ measure it_coverage is 50.0
+ measure overall_coverage is 80.0
+verify org.sonarqube:java-ut-it-jacoco-sq-scanner:src/main/java/example/HelloWorld.java
+ measure lines is 21
+ measure ncloc is 15
+ measure lines_to_cover is 10
+ measure uncovered_lines is 6
+ measure it_lines_to_cover is 10
+ measure it_uncovered_lines is 5
+stop server
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-maven/README.md b/projects/languages/java/code-coverage/it/it-jacoco-maven/README.md
new file mode 100644
index 00000000..76e782a6
--- /dev/null
+++ b/projects/languages/java/code-coverage/it/it-jacoco-maven/README.md
@@ -0,0 +1,16 @@
+This example demonstrates how to add information on integration tests coverage for a Java project using JaCoCo and Maven.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* Maven 3.0+
+
+Usage
+=====
+* Build the project and run tests:
+
+ mvn clean install
+
+* Analyze the project with SonarQube using Maven:
+
+ mvn sonar:sonar
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-maven/pom.xml b/projects/languages/java/code-coverage/it/it-jacoco-maven/pom.xml
new file mode 100644
index 00000000..103bbd28
--- /dev/null
+++ b/projects/languages/java/code-coverage/it/it-jacoco-maven/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ org.sonarqube
+ example-it-jacoco-maven
+ 1.0-SNAPSHOT
+ Java :: IT Coverage with JaCoCo :: Maven
+
+
+ UTF-8
+ java
+
+ ${project.basedir}/reports/jacoco.exec
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.5
+ 1.5
+
+
+
+
+
+
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-maven/reports/jacoco.exec b/projects/languages/java/code-coverage/it/it-jacoco-maven/reports/jacoco.exec
new file mode 100644
index 00000000..6cb8333a
Binary files /dev/null and b/projects/languages/java/code-coverage/it/it-jacoco-maven/reports/jacoco.exec differ
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-maven/src/main/java/example/One.java b/projects/languages/java/code-coverage/it/it-jacoco-maven/src/main/java/example/One.java
new file mode 100644
index 00000000..52baaaf4
--- /dev/null
+++ b/projects/languages/java/code-coverage/it/it-jacoco-maven/src/main/java/example/One.java
@@ -0,0 +1,13 @@
+package example;
+
+public class One {
+ String message = "foo";
+
+ public String foo() {
+ return message;
+ }
+
+ public void uncoveredMethod() {
+ System.out.println(foo());
+ }
+}
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/README.md b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/README.md
new file mode 100644
index 00000000..c28d7521
--- /dev/null
+++ b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to add information on integration tests coverage for a Java project using JaCoCo and SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+
+Usage
+=====
+* Analyze it with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
+
\ No newline at end of file
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/classes/One.class b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/classes/One.class
new file mode 100644
index 00000000..af32a24d
Binary files /dev/null and b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/classes/One.class differ
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/reports/jacoco.exec b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/reports/jacoco.exec
new file mode 100644
index 00000000..cbe4a740
Binary files /dev/null and b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/reports/jacoco.exec differ
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/sonar-project.properties b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..e40b52e8
--- /dev/null
+++ b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/sonar-project.properties
@@ -0,0 +1,10 @@
+sonar.projectKey=org.sonarqube:example-it-jacoco-sonar-scanner
+sonar.projectName=Java :: IT Coverage with JaCoCo :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.sources=src
+sonar.binaries=classes
+sonar.language=java
+sonar.sourceEncoding=UTF-8
+
+sonar.jacoco.itReportPath=reports/jacoco.exec
\ No newline at end of file
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/src/One.java b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/src/One.java
new file mode 100644
index 00000000..1ff2941e
--- /dev/null
+++ b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/src/One.java
@@ -0,0 +1,11 @@
+public class One {
+ String message = "foo";
+
+ public String foo() {
+ return message;
+ }
+
+ public void uncoveredMethod() {
+ System.out.println(foo());
+ }
+}
diff --git a/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/validation.txt b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/validation.txt
new file mode 100644
index 00000000..3e59d13f
--- /dev/null
+++ b/projects/languages/java/code-coverage/it/it-jacoco-sonar-runner/validation.txt
@@ -0,0 +1,15 @@
+start server
+ with plugin java 3.10
+sonar-runner
+verify org.sonarqube:example-it-jacoco-sonar-scanner
+ measure lines is 12
+ measure ncloc is 9
+ measure files is 1
+ measure classes is 1
+ measure it_coverage is 60.0
+verify org.sonarqube:example-it-jacoco-sonar-scanner:src/One.java
+ measure lines is 12
+ measure ncloc is 9
+ measure it_lines_to_cover is 5
+ measure it_uncovered_lines is 2
+stop server
diff --git a/projects/languages/java/code-coverage/ut/ut-maven-cobertura/README.md b/projects/languages/java/code-coverage/ut/ut-maven-cobertura/README.md
new file mode 100644
index 00000000..78f5690b
--- /dev/null
+++ b/projects/languages/java/code-coverage/ut/ut-maven-cobertura/README.md
@@ -0,0 +1,19 @@
+This example demonstrates how to import JUnit and Cobertura reports.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 5.6+
+* [SonarQube Java Plugin](http://docs.sonarqube.org/display/PLUG/Java+Plugin) 3.14+
+* [SonarQube Cobertura Plugin](https://github.com/SonarQubeCommunity/sonar-cobertura) 1.6.3+
+* Maven 3.0+
+
+Usage
+=====
+* Build the project, run the unit tests and generate the Cobertura report in XML format:
+
+ mvn clean compile
+ mvn cobertura:cobertura -Dcobertura.report.format=xml
+
+* Analyze the project with SonarQube using Maven:
+
+ mvn sonar:sonar
diff --git a/projects/languages/java/code-coverage/ut/ut-maven-cobertura/pom.xml b/projects/languages/java/code-coverage/ut/ut-maven-cobertura/pom.xml
new file mode 100644
index 00000000..4d87a602
--- /dev/null
+++ b/projects/languages/java/code-coverage/ut/ut-maven-cobertura/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+ org.sonarqube
+ example-ut-maven-cobertura
+ 1.0-SNAPSHOT
+
+ Java :: UT Coverage with Cobertura :: Maven
+
+
+ UTF-8
+ target/surefire-reports
+ target/site/cobertura/coverage.xml
+
+
+
+
+ junit
+ junit
+ 4.8.1
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.7
+ 1.7
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ cobertura-maven-plugin
+ 2.7
+
+
+ html
+ xml
+
+
+
+
+
+
+
diff --git a/projects/languages/java/code-coverage/ut/ut-maven-cobertura/src/main/java/example/One.java b/projects/languages/java/code-coverage/ut/ut-maven-cobertura/src/main/java/example/One.java
new file mode 100644
index 00000000..52baaaf4
--- /dev/null
+++ b/projects/languages/java/code-coverage/ut/ut-maven-cobertura/src/main/java/example/One.java
@@ -0,0 +1,13 @@
+package example;
+
+public class One {
+ String message = "foo";
+
+ public String foo() {
+ return message;
+ }
+
+ public void uncoveredMethod() {
+ System.out.println(foo());
+ }
+}
diff --git a/projects/languages/java/code-coverage/ut/ut-maven-cobertura/src/test/java/example/OneTest.java b/projects/languages/java/code-coverage/ut/ut-maven-cobertura/src/test/java/example/OneTest.java
new file mode 100644
index 00000000..6e1a4fe9
--- /dev/null
+++ b/projects/languages/java/code-coverage/ut/ut-maven-cobertura/src/test/java/example/OneTest.java
@@ -0,0 +1,13 @@
+package example;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class OneTest {
+ @Test
+ public void testFoo() throws Exception {
+ One one = new One();
+ assertEquals("foo", one.foo());
+ }
+
+}
diff --git a/projects/languages/java/code-coverage/ut/ut-maven-jacoco/README.md b/projects/languages/java/code-coverage/ut/ut-maven-jacoco/README.md
new file mode 100644
index 00000000..31ce3f59
--- /dev/null
+++ b/projects/languages/java/code-coverage/ut/ut-maven-jacoco/README.md
@@ -0,0 +1,22 @@
+This example demonstrates how to import JUnit and JaCoCo reports.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Java Plugin](http://docs.sonarqube.org/display/PLUG/Java+Plugin) 3.13+
+* Maven 3.0+
+
+
+Usage
+=====
+* Prepare jacoco agent to allow coverage report generation, build the project, and execute the unit tests:
+
+ mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install
+
+* To get coverage per tests information, you will need to activate the profile when running the instrumented tests:
+
+ mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install -Pcoverage-per-test
+
+* Analyze the project with SonarQube using Maven:
+
+ mvn sonar:sonar
diff --git a/projects/languages/java/code-coverage/ut/ut-maven-jacoco/pom.xml b/projects/languages/java/code-coverage/ut/ut-maven-jacoco/pom.xml
new file mode 100644
index 00000000..21104a68
--- /dev/null
+++ b/projects/languages/java/code-coverage/ut/ut-maven-jacoco/pom.xml
@@ -0,0 +1,76 @@
+
+
+ 4.0.0
+
+ org.sonarqube
+ example-ut-maven-jacoco
+ 1.0-SNAPSHOT
+
+ Java :: UT Coverage with JaCoCo :: Maven
+
+
+ UTF-8
+
+
+
+
+ junit
+ junit
+
+ 4.11
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+ 1.5
+ 1.5
+
+
+
+
+
+
+
+
+
+ coverage-per-test
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ 2.13
+
+
+
+ listener
+ org.sonar.java.jacoco.JUnitListener
+
+
+
+
+
+
+
+
+
+ org.sonarsource.java
+ sonar-jacoco-listeners
+ 3.8
+ test
+
+
+
+
+
+
+
diff --git a/projects/languages/java/code-coverage/ut/ut-maven-jacoco/src/main/java/example/One.java b/projects/languages/java/code-coverage/ut/ut-maven-jacoco/src/main/java/example/One.java
new file mode 100644
index 00000000..52933b08
--- /dev/null
+++ b/projects/languages/java/code-coverage/ut/ut-maven-jacoco/src/main/java/example/One.java
@@ -0,0 +1,18 @@
+package example;
+
+public class One {
+ String message = "foo";
+ String message2 = "toto";
+
+ public String foo() {
+ return message;
+ }
+
+ public String toto() {
+ return message2;
+ }
+
+ public void uncoveredMethod() {
+ System.out.println(foo());
+ }
+}
diff --git a/projects/languages/java/code-coverage/ut/ut-maven-jacoco/src/test/java/example/OneTest.java b/projects/languages/java/code-coverage/ut/ut-maven-jacoco/src/test/java/example/OneTest.java
new file mode 100644
index 00000000..113e3e57
--- /dev/null
+++ b/projects/languages/java/code-coverage/ut/ut-maven-jacoco/src/test/java/example/OneTest.java
@@ -0,0 +1,19 @@
+package example;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class OneTest {
+ @Test
+ public void testFoo() throws Exception {
+ One one = new One();
+ assertEquals("foo", one.foo());
+ }
+
+ @Test
+ public void testBoth() throws Exception {
+ One one = new One();
+ assertEquals("toto", one.toto());
+ assertEquals("foo", one.foo());
+ }
+}
diff --git a/projects/languages/java/gradle/README.md b/projects/languages/java/gradle/README.md
new file mode 100644
index 00000000..747b02e1
--- /dev/null
+++ b/projects/languages/java/gradle/README.md
@@ -0,0 +1 @@
+For multi-module project samples, see /projects/multi-module/gradle
\ No newline at end of file
diff --git a/projects/languages/java/gradle/java-gradle-simple/README.md b/projects/languages/java/gradle/java-gradle-simple/README.md
new file mode 100644
index 00000000..9c700970
--- /dev/null
+++ b/projects/languages/java/gradle/java-gradle-simple/README.md
@@ -0,0 +1,12 @@
+This example demonstrates how to analyze a simple Java project with Gradle.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [Gradle](http://www.gradle.org/) 2.1 or higher
+
+Usage
+=====
+* Analyze the project with SonarQube using Gradle:
+
+ gradle sonarqube [-Dsonar.host.url=... -Dsonar.jdbc.url=... -Dsonar.jdbc.username=... -Dsonar.jdbc.password=...]
diff --git a/projects/languages/java/gradle/java-gradle-simple/build.gradle b/projects/languages/java/gradle/java-gradle-simple/build.gradle
new file mode 100644
index 00000000..442f96e6
--- /dev/null
+++ b/projects/languages/java/gradle/java-gradle-simple/build.gradle
@@ -0,0 +1,41 @@
+// Uses DSL plugins resolution introduced in Gradle 2.1
+plugins {
+ id "java"
+ id "jacoco"
+ id "org.sonarqube" version "1.2"
+}
+
+sonarqube {
+ properties {
+ property "sonar.projectName", "Java :: Simple Project :: SonarQube Scanner for Gradle"
+ property "sonar.projectKey", "org.sonarqube:java-gradle-simple"
+ property "sonar.jacoco.reportPath", "${project.buildDir}/jacoco/test.exec"
+ }
+}
+
+allprojects {
+ ext.baseVersion = "0.1"
+ ext.snapshotVersion = true
+
+ group = "org.sonarqube"
+ version = "$baseVersion" + (snapshotVersion ? "-SNAPSHOT" : "")
+}
+
+test {
+ ignoreFailures = true
+}
+
+dependencies {
+ testCompile 'junit:junit:4.12'
+}
+
+repositories {
+ repositories {
+ maven {
+ url "http://repo1.maven.org/maven2/"
+ }
+ maven {
+ url "https://plugins.gradle.org/m2/"
+ }
+ }
+}
diff --git a/projects/gradle/src/main/java/example/Greeting.java b/projects/languages/java/gradle/java-gradle-simple/src/main/java/example/Greeting.java
similarity index 100%
rename from projects/gradle/src/main/java/example/Greeting.java
rename to projects/languages/java/gradle/java-gradle-simple/src/main/java/example/Greeting.java
diff --git a/projects/languages/java/gradle/java-gradle-simple/src/test/java/example/FailingTest.java b/projects/languages/java/gradle/java-gradle-simple/src/test/java/example/FailingTest.java
new file mode 100644
index 00000000..963a4f1a
--- /dev/null
+++ b/projects/languages/java/gradle/java-gradle-simple/src/test/java/example/FailingTest.java
@@ -0,0 +1,16 @@
+package example;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.fail;
+
+public class FailingTest {
+
+ @Test
+ public void testAuthenticator() throws Exception {
+ fail("FAIL!");
+ }
+}
diff --git a/projects/gradle/src/test/java/example/GreetingTest.java b/projects/languages/java/gradle/java-gradle-simple/src/test/java/example/GreetingTest.java
similarity index 100%
rename from projects/gradle/src/test/java/example/GreetingTest.java
rename to projects/languages/java/gradle/java-gradle-simple/src/test/java/example/GreetingTest.java
diff --git a/projects/languages/java/maven/java-maven-simple/README.md b/projects/languages/java/maven/java-maven-simple/README.md
new file mode 100644
index 00000000..d594a271
--- /dev/null
+++ b/projects/languages/java/maven/java-maven-simple/README.md
@@ -0,0 +1,17 @@
+This example demonstrates how to analyze a simple Java Maven project.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Java Plugin](http://docs.sonarqube.org/display/PLUG/Java+Plugin) 3.13.1+
+* Maven 2.2.1 or higher
+
+Usage
+=====
+* Build the project:
+
+ mvn clean install
+
+* Analyze it with SonarQube using Maven:
+
+ mvn sonar:sonar
diff --git a/projects/languages/java/maven/java-maven-simple/pom.xml b/projects/languages/java/maven/java-maven-simple/pom.xml
new file mode 100644
index 00000000..b46caa8a
--- /dev/null
+++ b/projects/languages/java/maven/java-maven-simple/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+ org.sonarqube
+ example-java-maven
+ 1.0-SNAPSHOT
+
+ Java :: Simple Project :: SonarQube Scanner for Maven
+
+
+ UTF-8
+ java
+
+
+
diff --git a/projects/languages/java/maven/java-maven-simple/src/main/java/example/One.java b/projects/languages/java/maven/java-maven-simple/src/main/java/example/One.java
new file mode 100644
index 00000000..52baaaf4
--- /dev/null
+++ b/projects/languages/java/maven/java-maven-simple/src/main/java/example/One.java
@@ -0,0 +1,13 @@
+package example;
+
+public class One {
+ String message = "foo";
+
+ public String foo() {
+ return message;
+ }
+
+ public void uncoveredMethod() {
+ System.out.println(foo());
+ }
+}
diff --git a/projects/languages/java/sonar-runner/java-sonar-runner-simple/README.md b/projects/languages/java/sonar-runner/java-sonar-runner-simple/README.md
new file mode 100644
index 00000000..5a041f2e
--- /dev/null
+++ b/projects/languages/java/sonar-runner/java-sonar-runner-simple/README.md
@@ -0,0 +1,12 @@
+This example demonstrates how to analyze a simple Java project with the Sonar Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/java/sonar-runner/java-sonar-runner-simple/sonar-project.properties b/projects/languages/java/sonar-runner/java-sonar-runner-simple/sonar-project.properties
new file mode 100644
index 00000000..9ee18f53
--- /dev/null
+++ b/projects/languages/java/sonar-runner/java-sonar-runner-simple/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:java-simple-sq-scanner
+sonar.projectName=Java :: Simple Project Not Compiled :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=java
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/projects/languages/java/sonar-runner/java-sonar-runner-simple/src/ComplexMethod.java b/projects/languages/java/sonar-runner/java-sonar-runner-simple/src/ComplexMethod.java
new file mode 100644
index 00000000..c942bb96
--- /dev/null
+++ b/projects/languages/java/sonar-runner/java-sonar-runner-simple/src/ComplexMethod.java
@@ -0,0 +1,28 @@
+public class ComplexMethod {
+
+ public String intToEnglishValue(int i) {
+ if (i == 1) {
+ return "One";
+ }
+ if (i == 2) {
+ return "Two";
+ }
+ if (i == 3) {
+ return "Three";
+ }
+ if (i == 4) {
+ return "Four";
+ }
+ if (i == 5) {
+ return "Five";
+ }
+ if (i == 6) {
+ return "Six";
+ }
+ if (i > 6) {
+ throw new NotImplementedException();
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/projects/languages/java/sonar-runner/java-sonar-runner-simple/src/HelloWorld.java b/projects/languages/java/sonar-runner/java-sonar-runner-simple/src/HelloWorld.java
new file mode 100644
index 00000000..2d03d228
--- /dev/null
+++ b/projects/languages/java/sonar-runner/java-sonar-runner-simple/src/HelloWorld.java
@@ -0,0 +1,6 @@
+public class HelloWorld {
+
+ public static void main(String[] args) {
+ System.out.println("Hello World !");
+ }
+}
diff --git a/projects/languages/java/sonar-runner/java-sonar-runner-simple/validation.txt b/projects/languages/java/sonar-runner/java-sonar-runner-simple/validation.txt
new file mode 100644
index 00000000..6e216b77
--- /dev/null
+++ b/projects/languages/java/sonar-runner/java-sonar-runner-simple/validation.txt
@@ -0,0 +1,15 @@
+start server
+ with plugin java 3.12
+sonar-runner
+verify org.sonarqube:java-simple-sq-scanner
+ measure lines is 35
+ measure ncloc is 31
+ measure files is 2
+ measure classes is 2
+verify org.sonarqube:java-simple-sq-scanner:src/HelloWorld.java
+ measure lines is 7
+ measure ncloc is 5
+verify org.sonarqube:java-simple-sq-scanner:src/ComplexMethod.java
+ measure lines is 28
+ measure ncloc is 26
+stop server
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/README.md b/projects/languages/javascript/javascript-sonar-runner-lcov/README.md
new file mode 100644
index 00000000..bea45e94
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a JavaScript project with the SonarQube Scanner reusing an LCOV report.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [Sonar JavaScript Plugin](http://docs.sonarqube.org/display/PLUG/JavaScript+Plugin) 2.12+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/report/lcov.dat b/projects/languages/javascript/javascript-sonar-runner-lcov/report/lcov.dat
new file mode 100644
index 00000000..30b016dd
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/report/lcov.dat
@@ -0,0 +1,71 @@
+SF:sources/Person.js
+DA:2,1
+DA:3,2
+DA:4,2
+DA:5,2
+DA:8,1
+DA:11,2
+end_of_record
+SF:sources/com/company/Car.js
+DA:1,1
+DA:2,3
+DA:3,3
+DA:4,3
+DA:5,3
+DA:6,3
+DA:9,1
+DA:12,1
+DA:16,1
+DA:17,0
+DA:18,1
+DA:19,1
+DA:21,0
+DA:26,0
+DA:27,0
+DA:31,0
+DA:32,0
+DA:36,1
+DA:37,0
+DA:38,0
+DA:39,0
+DA:41,1
+DA:42,1
+DA:47,0
+end_of_record
+SF:sources/com/company/Truck.js
+DA:1,1
+DA:2,0
+DA:3,0
+DA:4,0
+DA:5,0
+DA:6,0
+DA:9,1
+DA:12,0
+DA:16,0
+DA:17,0
+DA:18,0
+DA:19,0
+DA:21,0
+end_of_record
+SF:sources/com/company/Vehicle.js
+DA:9,1
+DA:10,0
+DA:11,0
+DA:12,0
+DA:13,0
+DA:14,0
+DA:22,1
+DA:25,0
+DA:29,0
+DA:30,0
+DA:31,0
+DA:32,0
+DA:34,0
+DA:39,0
+DA:40,0
+DA:41,0
+DA:42,0
+DA:44,0
+DA:45,0
+DA:50,0
+end_of_record
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/sonar-project.properties b/projects/languages/javascript/javascript-sonar-runner-lcov/sonar-project.properties
new file mode 100644
index 00000000..84d1c2e2
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/sonar-project.properties
@@ -0,0 +1,13 @@
+sonar.projectKey=org.sonarqube:javascript-lcov-sq-scanner
+sonar.projectName=JavaScript :: Coverage LCOV :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.language=js
+sonar.sources=sources
+sonar.sourceEncoding=UTF-8
+
+# Optional
+sonar.tests=tests
+
+# To import the LCOV report
+sonar.javascript.lcov.reportPath=report/lcov.dat
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/sources/Person.js b/projects/languages/javascript/javascript-sonar-runner-lcov/sources/Person.js
new file mode 100644
index 00000000..f536a4f4
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/sources/Person.js
@@ -0,0 +1,14 @@
+
+var Person = function(first, last, middle) {
+ this.first = first;
+ this.middle = middle;
+ this.last = last;
+};
+
+Person.prototype = {
+
+ whoAreYou : function() {
+ return this.first + (this.middle ? ' ' + this.middle: '') + ' ' + this.last;
+ }
+
+};
\ No newline at end of file
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/sources/com/company/Car.js b/projects/languages/javascript/javascript-sonar-runner-lcov/sources/com/company/Car.js
new file mode 100644
index 00000000..40a9da78
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/sources/com/company/Car.js
@@ -0,0 +1,50 @@
+var Car = function(brand, model, year) {
+ this.brand = brand;
+ this.model = model;
+ this.year = year;
+ this.engineState = 'stopped';
+ this.messageToDriver = '';
+};
+
+Car.prototype = {
+
+ getFullName : function() {
+ return this.brand + ' ' + this.model + ' ' + 'Y: ' + this.year;
+ },
+
+ calculatePrice : function() {
+ if (this.year < 1990) {
+ return '$1500';
+ } else if (this.year > 2011) {
+ return '$30000';
+ } else {
+ return '$1500 - 30000';
+ }
+ },
+
+ startEngine : function() {
+ this.engineState = 'started';
+ return 'engine started';
+ },
+
+ stopEngine : function() {
+ this.engineState = 'stopped';
+ return 'engine stopped';
+ },
+
+ stopEngineWithCheck : function() {
+ if (this.engineState === 'started') {
+ this.engineState = 'stopped';
+ this.messageToDriver = 'all good. c u later';
+ return 'engine stopped';
+ } else {
+ this.messageToDriver = 'engine not started. what do you want me to do?';
+ return 'engine was not running';
+ }
+ },
+
+ tuneCar : function() {
+ this.year = '2011';
+ }
+
+};
\ No newline at end of file
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/sources/com/company/Truck.js b/projects/languages/javascript/javascript-sonar-runner-lcov/sources/com/company/Truck.js
new file mode 100644
index 00000000..98df0732
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/sources/com/company/Truck.js
@@ -0,0 +1,24 @@
+var Truck = function(brand, model, year) {
+ this.brand = brand;
+ this.model = model;
+ this.year = year;
+ this.engineState = 'stopped';
+ this.messageToDriver = '';
+};
+
+Truck.prototype = {
+
+ getFullName : function() {
+ return this.brand + ' ' + this.model + ' ' + 'Y: ' + this.year;
+ },
+
+ calculatePrice : function() {
+ if (this.year < 1990) {
+ return '$15000';
+ } else if (this.year > 2011) {
+ return '$300000';
+ } else {
+ return '$15000 - 300000';
+ }
+ }
+};
\ No newline at end of file
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/sources/com/company/Vehicle.js b/projects/languages/javascript/javascript-sonar-runner-lcov/sources/com/company/Vehicle.js
new file mode 100644
index 00000000..e004a007
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/sources/com/company/Vehicle.js
@@ -0,0 +1,53 @@
+/**
+ * This is copy/paste file from Car.js with couple methods removed
+ *
+ * Removed methods:
+ * - startEngine ()
+ * - stopEngine ()
+ *
+ */
+var Vehicle = function(brand, model, year) {
+ this.brand = brand;
+ this.model = model;
+ this.year = year;
+ this.engineState = 'stopped';
+ this.messageToDriver = '';
+};
+
+
+// single line comments line 1
+// single line comments line 2
+// single line comments line 3
+// single line comments line 4
+Vehicle.prototype = {
+
+ getFullName : function() {
+ return this.brand + ' ' + this.model + ' ' + 'Y: ' + this.year;
+ },
+
+ calculatePrice : function() {
+ if (this.year < 1990) {
+ return '$1500';
+ } else if (this.year > 2011) {
+ return '$30000';
+ } else {
+ return '$1500 - 30000';
+ }
+ },
+
+ stopEngineWithCheck : function() {
+ if (this.engineState === 'started') {
+ this.engineState = 'stopped';
+ this.messageToDriver = 'all good. c u later';
+ return 'engine stopped';
+ } else {
+ this.messageToDriver = 'engine not started. what do you want me to do?';
+ return 'engine was not running';
+ }
+ },
+
+ tuneCar : function() {
+ this.year = '2011';
+ }
+
+};
\ No newline at end of file
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/tests/PersonTest.js b/projects/languages/javascript/javascript-sonar-runner-lcov/tests/PersonTest.js
new file mode 100644
index 00000000..36b8fb05
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/tests/PersonTest.js
@@ -0,0 +1,13 @@
+TestCase('PersonTest', {
+
+ testWhoAreYou : function() {
+ var p = new Person('John', 'Doe', 'P.');
+ assertEquals('Should have responded with full name', 'John P. Doe', p.whoAreYou());
+ },
+
+ testWhoAreYouWithNoMiddleName : function() {
+ var p = new Person('John', 'Doe');
+ assertEquals('Should have used only first and last name', 'John Doe', p.whoAreYou());
+ }
+
+});
\ No newline at end of file
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/tests/com/company/CarTest.js b/projects/languages/javascript/javascript-sonar-runner-lcov/tests/com/company/CarTest.js
new file mode 100644
index 00000000..b63b17d1
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/tests/com/company/CarTest.js
@@ -0,0 +1,18 @@
+TestCase('com.company.CarTest', {
+
+ testfullName : function() {
+ var car = new Car('VW', 'Beatle', 1971);
+ assertEquals('VW Beatle Y: 1971', car.getFullName());
+ },
+
+ testStopEngineWithCheck : function() {
+ var car = new Car('VW', 'Beatle', 1971);
+ assertEquals('engine was not running', car.stopEngineWithCheck());
+ },
+
+ testCalculatePrice : function() {
+ var car = new Car('Volvo', 'XC70', 2012);
+ assertEquals('$30000', car.calculatePrice());
+ }
+
+});
\ No newline at end of file
diff --git a/projects/languages/javascript/javascript-sonar-runner-lcov/validation.txt b/projects/languages/javascript/javascript-sonar-runner-lcov/validation.txt
new file mode 100644
index 00000000..05da87c3
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner-lcov/validation.txt
@@ -0,0 +1,13 @@
+start server
+ with plugin javascript 2.11
+sonar-runner
+verify org.sonarqube:javascript-lcov-sq-scanner
+ measure lines is 141
+ measure ncloc is 107
+ measure files is 4
+ measure coverage is 38.1
+verify org.sonarqube:javascript-lcov-sq-scanner:sources/com/company/Car.js
+ measure lines is 50
+ measure ncloc is 42
+ measure coverage is 58.3
+stop server
diff --git a/projects/languages/javascript/javascript-sonar-runner/README.md b/projects/languages/javascript/javascript-sonar-runner/README.md
new file mode 100644
index 00000000..a6f2ae85
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a simple JavaScript project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [Sonar JavaScript Plugin](http://docs.sonarqube.org/display/PLUG/JavaScript+Plugin) 2.12+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/javascript/javascript-sonar-runner/sonar-project.properties b/projects/languages/javascript/javascript-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..21f98643
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:javascript-simple-sq-scanner
+sonar.projectName=JavaScript :: Simple Project :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=js
+
+# Encoding of sources files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/javascript/javascript-sonar-runner/src/Person.js b/projects/languages/javascript/javascript-sonar-runner/src/Person.js
new file mode 100644
index 00000000..7bde72c7
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner/src/Person.js
@@ -0,0 +1,31 @@
+var Person = function(first, last, middle) {
+ this.first = first;
+ this.middle = middle;
+ this.last = last;
+};
+
+Person.prototype = {
+
+ whoAreYou : function() {
+ return this.first + (this.middle ? ' ' + this.middle: '') + ' ' + this.last;
+ }
+
+};
+
+var a = NaN;
+
+if (a === NaN) { // Noncompliant; always false
+ console.log("a is not a number"); // this is dead code
+}
+if (a !== NaN) { // Noncompliant; always true
+ console.log("a is not NaN"); // this statement is not necessarily true
+}
+
+
+for (var i = 0; i < strings.length; i--) {
+ console.log("dead code")
+}
+
+if (str == null && str.length == 0) {
+ console.log("String is empty");
+}
diff --git a/projects/languages/javascript/javascript-sonar-runner/validation.txt b/projects/languages/javascript/javascript-sonar-runner/validation.txt
new file mode 100644
index 00000000..76189fa9
--- /dev/null
+++ b/projects/languages/javascript/javascript-sonar-runner/validation.txt
@@ -0,0 +1,11 @@
+start server
+ with plugin javascript 2.11
+sonar-runner
+verify org.sonarqube:javascript-simple-sq-scanner
+ measure lines is 32
+ measure ncloc is 23
+ measure files is 1
+verify org.sonarqube:javascript-simple-sq-scanner:src/Person.js
+ measure lines is 32
+ measure ncloc is 23
+stop server
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/README.md b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/README.md
new file mode 100644
index 00000000..1fb80bb5
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/README.md
@@ -0,0 +1,16 @@
+This example demonstrates how to analyze Gradle project with mixed Groovy (Spock) and Java (JUnit) test suite.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Groovy Plugin](http://docs.sonarqube.org/display/PLUG/Groovy+Plugin) 1.3+
+
+Usage
+=====
+* Compile the project:
+
+ ./gradlew check
+
+* Analyze it with SonarQube using Gradle:
+
+ ./gradlew sonarqube
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/build.gradle b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/build.gradle
new file mode 100644
index 00000000..c421ecf2
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/build.gradle
@@ -0,0 +1,30 @@
+buildscript {
+ repositories {
+ jcenter()
+ maven { url "https://plugins.gradle.org/m2/" }
+ }
+ dependencies {
+ classpath "org.sonarqube.gradle:gradle-sonarqube-plugin:1.0"
+ }
+}
+
+apply plugin: 'groovy'
+apply plugin: 'jacoco'
+apply plugin: 'org.sonarqube'
+
+repositories {
+ jcenter()
+}
+
+dependencies {
+ compile 'org.codehaus.groovy:groovy-all:2.4.7'
+
+ testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
+ testCompile 'junit:junit:4.12'
+}
+
+sonarqube {
+ properties {
+ property "sonar.groovy.jacoco.reportPath", "$buildDir/jacoco/test.exec" //TODO: Could be set by default when Groovy plugin is detected
+ }
+}
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradle/wrapper/gradle-wrapper.jar b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..b5166dad
Binary files /dev/null and b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradle/wrapper/gradle-wrapper.properties b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..3d69fde4
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jun 26 10:21:09 CEST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradlew b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradlew
new file mode 100755
index 00000000..91a7e269
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradlew.bat b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradlew.bat
new file mode 100644
index 00000000..8a0b282a
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/settings.gradle b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/settings.gradle
new file mode 100644
index 00000000..69a6ae5d
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'groovy-java-gradle-mixed-tests'
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/main/groovy/sonar/examples/Library.groovy b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/main/groovy/sonar/examples/Library.groovy
new file mode 100644
index 00000000..ac7eab1a
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/main/groovy/sonar/examples/Library.groovy
@@ -0,0 +1,11 @@
+package sonar.examples
+
+class Library {
+ boolean someLibraryMethodJUnit() {
+ true
+ }
+
+ boolean someLibraryMethodSpock() {
+ true
+ }
+}
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/main/groovy/sonar/examples/LibraryJava.java b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/main/groovy/sonar/examples/LibraryJava.java
new file mode 100644
index 00000000..6de12f91
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/main/groovy/sonar/examples/LibraryJava.java
@@ -0,0 +1,11 @@
+package sonar.examples;
+
+class LibraryJava {
+ boolean someLibraryMethodJUnit() {
+ return true;
+ }
+
+ boolean someLibraryMethodSpock() {
+ return true;
+ }
+}
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibraryJavaSpec.groovy b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibraryJavaSpec.groovy
new file mode 100644
index 00000000..f707a857
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibraryJavaSpec.groovy
@@ -0,0 +1,11 @@
+package sonar.examples
+
+import spock.lang.Specification
+
+class LibraryJavaSpec extends Specification {
+
+ def "should be Spock test"() {
+ expect:
+ new LibraryJava().someLibraryMethodSpock()
+ }
+}
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibraryJavaTest.java b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibraryJavaTest.java
new file mode 100644
index 00000000..b30022c4
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibraryJavaTest.java
@@ -0,0 +1,13 @@
+package sonar.examples;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class LibraryJavaTest {
+
+ @Test
+ public void shouldBeJUnitTest() {
+ assertTrue(new LibraryJava().someLibraryMethodJUnit());
+ }
+}
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibrarySpec.groovy b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibrarySpec.groovy
new file mode 100644
index 00000000..e596d7f0
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibrarySpec.groovy
@@ -0,0 +1,11 @@
+package sonar.examples
+
+import spock.lang.Specification
+
+class LibrarySpec extends Specification {
+
+ def "should be Spock test"() {
+ expect:
+ new Library().someLibraryMethodSpock()
+ }
+}
diff --git a/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibraryTest.java b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibraryTest.java
new file mode 100644
index 00000000..dc1f9308
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-groovy-tests-gradle/src/test/groovy/sonar/examples/LibraryTest.java
@@ -0,0 +1,13 @@
+package sonar.examples;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class LibraryTest {
+
+ @Test
+ public void shouldBeJUnitTest() {
+ assertTrue(new Library().someLibraryMethodJUnit());
+ }
+}
diff --git a/projects/languages/multi-language/multi-language-java-javascript-ant/README.md b/projects/languages/multi-language/multi-language-java-javascript-ant/README.md
new file mode 100644
index 00000000..4d5cb5ec
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-ant/README.md
@@ -0,0 +1,17 @@
+This example demonstrates how to analyze a multi-language project (Java / JavaScript) with the SonarQube Ant Task.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner for Ant](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Ant) 2.4.1+
+* [SonarQube Java Plugin](http://docs.sonarqube.org/display/PLUG/Java+Plugin) 3.13.1+
+* [SonarQube JavaScript Plugin](http://docs.sonarqube.org/display/PLUG/JavaScript+Plugin) 2.12+
+* [Ant](http://ant.apache.org/) 1.7.1+
+
+Usage
+=====
+* Set the path to the SonarQube Ant Task in the build.xml file
+* Set the sonar.jdbc.* properties in the build.xml file
+* Run the following command:
+
+ ant all
diff --git a/projects/languages/multi-language/multi-language-java-javascript-ant/build.xml b/projects/languages/multi-language/multi-language-java-javascript-ant/build.xml
new file mode 100644
index 00000000..f5ed71e8
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-ant/build.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/multi-language/multi-language-java-javascript-ant/src/Helloworld.java b/projects/languages/multi-language/multi-language-java-javascript-ant/src/Helloworld.java
new file mode 100644
index 00000000..4d4870a6
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-ant/src/Helloworld.java
@@ -0,0 +1,8 @@
+public class Helloworld {
+
+ public void helloWorld() {
+ System.out.println("HelloWorld");
+ System.exit(33);
+ }
+
+}
diff --git a/projects/languages/multi-language/multi-language-java-javascript-ant/src/Person.js b/projects/languages/multi-language/multi-language-java-javascript-ant/src/Person.js
new file mode 100644
index 00000000..6bae2cad
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-ant/src/Person.js
@@ -0,0 +1,12 @@
+
+var Person = function(first, last, middle) {
+ this.first = first;
+ this.middle = middle;
+ this.last = last;
+};
+Person.prototype = {
+
+ whoAreYou : function() {
+ return this.first + (this.middle ? ' ' + this.middle: '') + ' ' + this.last;
+ }
+};
diff --git a/projects/languages/multi-language/multi-language-java-javascript-maven/README.md b/projects/languages/multi-language/multi-language-java-javascript-maven/README.md
new file mode 100644
index 00000000..678465ed
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-maven/README.md
@@ -0,0 +1,18 @@
+This example demonstrates how to analyze a multi-language project (Java / JavaScript) with Maven.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Java Plugin](http://docs.sonarqube.org/display/PLUG/Java+Plugin) 3.13.1+
+* [SonarQube JavaScript Plugin](http://docs.sonarqube.org/display/PLUG/JavaScript+Plugin) 2.12+
+* Maven 3.0+
+
+Usage
+=====
+* Build the project:
+
+ mvn clean install
+
+* Analyze the project with SonarQube using Maven:
+
+ mvn sonar:sonar
diff --git a/projects/languages/multi-language/multi-language-java-javascript-maven/pom.xml b/projects/languages/multi-language/multi-language-java-javascript-maven/pom.xml
new file mode 100644
index 00000000..d403ea27
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-maven/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+ org.sonarqube
+ multi-language-project-java-javascript-maven
+ 1.0-SNAPSHOT
+
+ Java and JavaScript :: SonarQube Scanner for Maven
+
+
+ UTF-8
+ src
+
+
+
diff --git a/projects/languages/multi-language/multi-language-java-javascript-maven/src/main/java/Helloworld.java b/projects/languages/multi-language/multi-language-java-javascript-maven/src/main/java/Helloworld.java
new file mode 100644
index 00000000..4d4870a6
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-maven/src/main/java/Helloworld.java
@@ -0,0 +1,8 @@
+public class Helloworld {
+
+ public void helloWorld() {
+ System.out.println("HelloWorld");
+ System.exit(33);
+ }
+
+}
diff --git a/projects/languages/multi-language/multi-language-java-javascript-maven/src/webapp/static/js/Person.js b/projects/languages/multi-language/multi-language-java-javascript-maven/src/webapp/static/js/Person.js
new file mode 100644
index 00000000..6bae2cad
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-maven/src/webapp/static/js/Person.js
@@ -0,0 +1,12 @@
+
+var Person = function(first, last, middle) {
+ this.first = first;
+ this.middle = middle;
+ this.last = last;
+};
+Person.prototype = {
+
+ whoAreYou : function() {
+ return this.first + (this.middle ? ' ' + this.middle: '') + ' ' + this.last;
+ }
+};
diff --git a/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/README.md b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/README.md
new file mode 100644
index 00000000..5881996c
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/README.md
@@ -0,0 +1,14 @@
+This example demonstrates how to analyze a multi-language project (Java / JavaScript) with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Java Plugin](http://docs.sonarqube.org/display/PLUG/Java+Plugin) 3.13.1+
+* [SonarQube JavaScript Plugin](http://docs.sonarqube.org/display/PLUG/JavaScript+Plugin) 2.12+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/classes/Helloworld.class b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/classes/Helloworld.class
new file mode 100644
index 00000000..d8f679ad
Binary files /dev/null and b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/classes/Helloworld.class differ
diff --git a/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/sonar-project.properties b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..6f9e12df
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/sonar-project.properties
@@ -0,0 +1,8 @@
+sonar.projectKey=org.sonarqube:multi-language-project-java-javascript-sq-scanner
+sonar.projectName=Java and JavaScript :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.sourceEncoding=UTF-8
+
+sonar.sources=src
+sonar.binaries=classes
diff --git a/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/src/Helloworld.java b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/src/Helloworld.java
new file mode 100644
index 00000000..4d4870a6
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/src/Helloworld.java
@@ -0,0 +1,8 @@
+public class Helloworld {
+
+ public void helloWorld() {
+ System.out.println("HelloWorld");
+ System.exit(33);
+ }
+
+}
diff --git a/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/src/Person.js b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/src/Person.js
new file mode 100644
index 00000000..6bae2cad
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/src/Person.js
@@ -0,0 +1,12 @@
+
+var Person = function(first, last, middle) {
+ this.first = first;
+ this.middle = middle;
+ this.last = last;
+};
+Person.prototype = {
+
+ whoAreYou : function() {
+ return this.first + (this.middle ? ' ' + this.middle: '') + ' ' + this.last;
+ }
+};
diff --git a/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/validation.txt b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/validation.txt
new file mode 100644
index 00000000..72739c11
--- /dev/null
+++ b/projects/languages/multi-language/multi-language-java-javascript-sonar-runner/validation.txt
@@ -0,0 +1,16 @@
+start server
+ with plugin java 3.7.1
+ with plugin javascript 2.8
+sonar-runner
+verify org.sonarqube:multi-language-project-java-javascript-sq-scanner
+ measure lines is 22
+ measure ncloc is 16
+ measure files is 2
+ measure classes is 1
+verify org.sonarqube:multi-language-project-java-javascript-sq-scanner:src/Helloworld.java
+ measure lines is 9
+ measure ncloc is 6
+verify org.sonarqube:multi-language-project-java-javascript-sq-scanner:src/Person.js
+ measure lines is 13
+ measure ncloc is 10
+stop server
diff --git a/projects/languages/objc/objc-sonar-runner/README.md b/projects/languages/objc/objc-sonar-runner/README.md
new file mode 100644
index 00000000..f6f7dcdc
--- /dev/null
+++ b/projects/languages/objc/objc-sonar-runner/README.md
@@ -0,0 +1,15 @@
+This example demonstrates how to analyze an Objective-C project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarSource Objective-C Plugin](http://www.sonarsource.com/products/plugins/languages/objective-c/) 3.11+
+* [SonarSource Build Wrapper](http://www.sonarsource.com/products/plugins/languages/objective-c/) 3.11+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ /path/to/build-wrapper-macosx-x86 --out-dir out xcodebuild clean build
+ sonar-scanner
diff --git a/projects/languages/objc/objc-sonar-runner/helloworld.xcodeproj/project.pbxproj b/projects/languages/objc/objc-sonar-runner/helloworld.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..c132e238
--- /dev/null
+++ b/projects/languages/objc/objc-sonar-runner/helloworld.xcodeproj/project.pbxproj
@@ -0,0 +1,251 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 041441E4198A725F00234FDF /* Other.m in Sources */ = {isa = PBXBuildFile; fileRef = 041441E3198A725F00234FDF /* Other.m */; };
+ 049685BC198A4DDB0048323D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 049685BB198A4DDB0048323D /* Foundation.framework */; };
+ 049685BF198A4DDB0048323D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 049685BE198A4DDB0048323D /* main.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 049685B6198A4DDB0048323D /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = /usr/share/man/man1/;
+ dstSubfolderSpec = 0;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 041441E2198A725F00234FDF /* Other.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Other.h; sourceTree = ""; };
+ 041441E3198A725F00234FDF /* Other.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Other.m; sourceTree = ""; };
+ 049685B8198A4DDB0048323D /* helloworld */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = helloworld; sourceTree = BUILT_PRODUCTS_DIR; };
+ 049685BB198A4DDB0048323D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 049685BE198A4DDB0048323D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 049685B5198A4DDB0048323D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 049685BC198A4DDB0048323D /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 049685AF198A4DDB0048323D = {
+ isa = PBXGroup;
+ children = (
+ 049685BD198A4DDB0048323D /* helloworld */,
+ 049685BA198A4DDB0048323D /* Frameworks */,
+ 049685B9198A4DDB0048323D /* Products */,
+ );
+ sourceTree = "";
+ };
+ 049685B9198A4DDB0048323D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 049685B8198A4DDB0048323D /* helloworld */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 049685BA198A4DDB0048323D /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 049685BB198A4DDB0048323D /* Foundation.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ 049685BD198A4DDB0048323D /* helloworld */ = {
+ isa = PBXGroup;
+ children = (
+ 049685BE198A4DDB0048323D /* main.m */,
+ 041441E2198A725F00234FDF /* Other.h */,
+ 041441E3198A725F00234FDF /* Other.m */,
+ );
+ path = helloworld;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 049685B7198A4DDB0048323D /* helloworld */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 049685C6198A4DDB0048323D /* Build configuration list for PBXNativeTarget "helloworld" */;
+ buildPhases = (
+ 049685B4198A4DDB0048323D /* Sources */,
+ 049685B5198A4DDB0048323D /* Frameworks */,
+ 049685B6198A4DDB0048323D /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = helloworld;
+ productName = helloworld;
+ productReference = 049685B8198A4DDB0048323D /* helloworld */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 049685B0198A4DDB0048323D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0510;
+ ORGANIZATIONNAME = helloworld;
+ };
+ buildConfigurationList = 049685B3198A4DDB0048323D /* Build configuration list for PBXProject "helloworld" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 049685AF198A4DDB0048323D;
+ productRefGroup = 049685B9198A4DDB0048323D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 049685B7198A4DDB0048323D /* helloworld */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 049685B4198A4DDB0048323D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 041441E4198A725F00234FDF /* Other.m in Sources */,
+ 049685BF198A4DDB0048323D /* main.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 049685C4198A4DDB0048323D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.9;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 049685C5198A4DDB0048323D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.9;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ 049685C7198A4DDB0048323D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = NO;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 049685C8198A4DDB0048323D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = NO;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 049685B3198A4DDB0048323D /* Build configuration list for PBXProject "helloworld" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 049685C4198A4DDB0048323D /* Debug */,
+ 049685C5198A4DDB0048323D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 049685C6198A4DDB0048323D /* Build configuration list for PBXNativeTarget "helloworld" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 049685C7198A4DDB0048323D /* Debug */,
+ 049685C8198A4DDB0048323D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 049685B0198A4DDB0048323D /* Project object */;
+}
diff --git a/projects/languages/objc/objc-sonar-runner/helloworld.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/projects/languages/objc/objc-sonar-runner/helloworld.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..60c2c64f
--- /dev/null
+++ b/projects/languages/objc/objc-sonar-runner/helloworld.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/projects/languages/objc/objc-sonar-runner/helloworld/Other.h b/projects/languages/objc/objc-sonar-runner/helloworld/Other.h
new file mode 100644
index 00000000..0b25b669
--- /dev/null
+++ b/projects/languages/objc/objc-sonar-runner/helloworld/Other.h
@@ -0,0 +1,10 @@
+//
+// Other.h
+// helloworld
+//
+
+#import
+
+@interface Other : NSObject
+- (void)sayHello;
+@end
diff --git a/projects/languages/objc/objc-sonar-runner/helloworld/Other.m b/projects/languages/objc/objc-sonar-runner/helloworld/Other.m
new file mode 100644
index 00000000..e1f2c22a
--- /dev/null
+++ b/projects/languages/objc/objc-sonar-runner/helloworld/Other.m
@@ -0,0 +1,14 @@
+//
+// Other.m
+// helloworld
+//
+
+#import
+
+#import "Other.h"
+
+@implementation Other
+- (void)sayHello {
+ NSLog(@"Hello, world!");
+}
+@end
diff --git a/projects/languages/objc/objc-sonar-runner/helloworld/main.m b/projects/languages/objc/objc-sonar-runner/helloworld/main.m
new file mode 100644
index 00000000..341eae63
--- /dev/null
+++ b/projects/languages/objc/objc-sonar-runner/helloworld/main.m
@@ -0,0 +1,23 @@
+//
+// main.m
+// helloworld
+//
+
+#import "Other.h"
+
+int main(int argc, const char * argv[]) {
+
+ @autoreleasepool {
+ int c = 0;
+ if (argc == 1) {
+ c = 1;
+ } else if (argc == 1) {
+ c = 2;
+ } else {
+ }
+ Other *object = [[Other alloc] init];
+ [object sayHello];
+ }
+ return 0;
+}
+
diff --git a/projects/languages/objc/objc-sonar-runner/sonar-project.properties b/projects/languages/objc/objc-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..81ff5fca
--- /dev/null
+++ b/projects/languages/objc/objc-sonar-runner/sonar-project.properties
@@ -0,0 +1,18 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:objc-sq-scanner
+
+sonar.projectName=Objective-C :: Simple :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=helloworld
+
+sonar.c.file.suffixes=
+sonar.objc.file.suffixes=.h,.m
+
+# The build-wrapper output dir
+sonar.cfamily.build-wrapper-output=out
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
+
diff --git a/projects/languages/php/php-sonar-runner-unit-tests/README.md b/projects/languages/php/php-sonar-runner-unit-tests/README.md
new file mode 100644
index 00000000..272c82e5
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner-unit-tests/README.md
@@ -0,0 +1,15 @@
+This example demonstrates how to analyze a PHP project with the SonarQube Scanner.
+It reuses existing unit test execution and code coverage reports from PHPUnit.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube PHP Plugin](http://docs.sonarqube.org/display/PLUG/PHP+Plugin) 2.8+
+
+Usage
+=====
+* In "reports/phpunit.coverage.xml", change the path "src/Math.php" to the full path of this file on your machine.
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/php/php-sonar-runner-unit-tests/reports/phpunit.coverage.xml b/projects/languages/php/php-sonar-runner-unit-tests/reports/phpunit.coverage.xml
new file mode 100644
index 00000000..184a0dd8
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner-unit-tests/reports/phpunit.coverage.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/php/php-sonar-runner-unit-tests/reports/phpunit.xml b/projects/languages/php/php-sonar-runner-unit-tests/reports/phpunit.xml
new file mode 100644
index 00000000..1942bdf4
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner-unit-tests/reports/phpunit.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ PhpUnderControl_Example_MathTest::testSubFail
+ Failed asserting that 1 matches expected 0.
+
+
+
+
+
+
+ PhpUnderControl_Example_MathTest::testDataProviderOneWillFail with data set #2 (7, 1)
+ Failed asserting that 6 matches expected 1.
+
+
+
+
+
+
+ PhpUnderControl_Example_MathTest::testDataProviderAllWillFail with data set #0 (17, 42)
+ Failed asserting that -25 matches expected 1.
+
+
+
+
+ PhpUnderControl_Example_MathTest::testDataProviderAllWillFail with data set #1 (13, 23)
+ Failed asserting that -10 matches expected 1.
+
+
+
+ PhpUnderControl_Example_MathTest::testDataProviderAllWillFail with data set #2 (42, 17)
+ Failed asserting that 25 matches expected 1.
+
+
+
+ PhpUnderControl_Example_MathTest::testDataProviderAllWillFail with data set #3 (23, 13)
+ Failed asserting that 10 matches expected 1.
+
+
+
+
+ PhpUnderControl_Example_MathTest::testFail
+ Failed because...
+
+
+
+
+
diff --git a/projects/languages/php/php-sonar-runner-unit-tests/sonar-project.properties b/projects/languages/php/php-sonar-runner-unit-tests/sonar-project.properties
new file mode 100644
index 00000000..7f915194
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner-unit-tests/sonar-project.properties
@@ -0,0 +1,14 @@
+sonar.projectKey=org.sonarqube:php-ut-sq-scanner
+sonar.projectName=PHP :: PHPUnit :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.sources=src
+sonar.tests=tests
+
+sonar.language=php
+
+sonar.sourceEncoding=UTF-8
+
+# Reusing PHPUnit reports
+sonar.php.coverage.reportPath=reports/phpunit.coverage.xml
+sonar.php.tests.reportPath=reports/phpunit.xml
diff --git a/projects/languages/php/php-sonar-runner-unit-tests/src/Foo/Math5.php b/projects/languages/php/php-sonar-runner-unit-tests/src/Foo/Math5.php
new file mode 100644
index 00000000..b06ce5b4
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner-unit-tests/src/Foo/Math5.php
@@ -0,0 +1,210 @@
+.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Manuel Pichler nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package Example
+ * @author Manuel Pichler
+ * @copyright 2007-2009 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id: Math.php 4429 2009-01-04 15:39:45Z mapi $
+ * @link http://www.phpundercontrol.org/
+ */
+
+/**
+ * Simple math class.
+ *
+ * @package Example
+ * @author Manuel Pichler
+ * @copyright 2007-2009 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: 0.5.0
+ * @link http://www.phpundercontrol.org/
+ */
+class PhpUnderControl_Example2_Math
+{
+ /**
+ * Adds the two given values.
+ *
+ * @param integer $v1 Value one.
+ * @param integer $v2 Value two.
+ *
+ * @return integer.
+ */
+ public function add($v1 , $v2)
+ {
+ return ($v1 + $v2);
+ }
+
+ /**
+ * Subtract param two from param one
+ *
+ * @param integer $v1 Value one.
+ * @param integer $v2 Value two.
+ *
+ * @return integer.
+ */
+ public function sub($v1, $v2)
+ {
+ return ($v1 - $v2);
+ }
+
+ /**
+ * Not tested method that should be visible with low coverage.
+ */
+ public function div($v1, $v2)
+ {
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end($d);
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end($d);
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ return $v8;
+ }
+
+ /**
+ * Simple copy for cpd detection.
+ */
+ public function complex($v1, $v2)
+ {
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end( $d );
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end($d);
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ return $v8;
+ }
+}
diff --git a/projects/languages/php/php-sonar-runner-unit-tests/src/Math.php b/projects/languages/php/php-sonar-runner-unit-tests/src/Math.php
new file mode 100644
index 00000000..5c1ab480
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner-unit-tests/src/Math.php
@@ -0,0 +1,214 @@
+.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Manuel Pichler nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package Example
+ * @author Manuel Pichler
+ * @copyright 2007-2009 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id: Math.php 4429 2009-01-04 15:39:45Z mapi $
+ * @link http://www.phpundercontrol.org/
+ */
+function add($v1 , $v2)
+ {
+ return ($v1 + $v2);
+ }
+
+/**
+ * Simple math class.
+ *
+ * @package Example
+ * @author Manuel Pichler
+ * @copyright 2007-2009 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: 0.5.0
+ * @link http://www.phpundercontrol.org/
+ */
+class PhpUnderControl_Example_Math
+{
+ /**
+ * Adds the two given values.
+ *
+ * @param integer $v1 Value one.
+ * @param integer $v2 Value two.
+ *
+ * @return integer.
+ */
+ public function add($v1 , $v2)
+ {
+ return ($v1 + $v2);
+ }
+
+ /**
+ * Subtract param two from param one
+ *
+ * @param integer $v1 Value one.
+ * @param integer $v2 Value two.
+ *
+ * @return integer.
+ */
+ public function sub($v1, $v2)
+ {
+ return ($v1 - $v2);
+ }
+
+ /**
+ * Not tested method that should be visible with low coverage.
+ */
+ public function div($v1, $v2)
+ {
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end($d);
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end($d);
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ return $v8;
+ }
+
+ /**
+ * Simple copy for cpd detection.
+ */
+ public function complex($v1, $v2)
+ {
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end( $d );
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end($d);
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ return $v8;
+ }
+}
diff --git a/projects/languages/php/php-sonar-runner-unit-tests/tests/SomeTest.php b/projects/languages/php/php-sonar-runner-unit-tests/tests/SomeTest.php
new file mode 100644
index 00000000..a5ead9c3
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner-unit-tests/tests/SomeTest.php
@@ -0,0 +1,169 @@
+.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Manuel Pichler nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+require_once dirname(__FILE__) . '/../src/Math.php';
+
+/**
+ * Simple math test class.
+ *
+ * @package Example
+ * @author Manuel Pichler
+ * @copyright 2007-2009 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: 0.5.0
+ * @link http://www.phpundercontrol.org/
+ */
+class PhpUnderControl_Example_MathTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * The used math object.
+ *
+ * @var PhpUnderControl_Example_Math $math
+ */
+ protected $math = null;
+
+ /**
+ * Creates a new {@link PhpUnderControl_Example_Math} object.
+ */
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->math = new PhpUnderControl_Example_Math();
+ }
+
+ /**
+ * Successful test.
+ */
+ public function testAddSuccess()
+ {
+ sleep(2);
+ $this->assertEquals(4, $this->math->add(1, 3));
+ }
+
+ /**
+ * Successful test.
+ */
+ public function testSubSuccess()
+ {
+ $this->assertEquals( -2, $this->math->sub( 1, 3 ) );
+ }
+
+ /**
+ * Failing test.
+ */
+ public function testSubFail()
+ {
+ sleep(2);
+ $this->assertEquals( 0, $this->math->sub( 2, 1 ) );
+ }
+
+ /**
+ * Test case with data provider.
+ *
+ * @dataProvider dataProviderOne
+ */
+ public function testDataProviderOneWillFail( $x, $y )
+ {
+ sleep(1);
+ $this->assertEquals( 1, $this->math->sub( $x, $y ) );
+ }
+
+ /**
+ * Test case with data provider.
+ *
+ * @dataProvider dataProviderTwo
+ */
+ public function testDataProviderAllWillFail( $x, $y )
+ {
+ $this->assertEquals( 1, $this->math->sub( $x, $y ) );
+ }
+
+ /**
+ * Failing test.
+ */
+ public function testFail()
+ {
+ $this->fail('Failed because...');
+ }
+
+ /**
+ * Skipping test.
+ */
+ public function testMarkSkip()
+ {
+ $this->markTestSkipped('Skipped because...');
+ }
+
+ /**
+ * Skipping test.
+ */
+ public function testMarkIncomplete()
+ {
+ $this->markTestIncomplete('Incomplete because...');
+ }
+
+ /**
+ * Example data provider.
+ *
+ * @return array(array)
+ */
+ public static function dataProviderOne()
+ {
+ return array(
+ array( 2, 1 ),
+ array( 3, 2 ),
+ array( 7, 1 ),
+ array( 9, 8 ),
+ );
+ }
+
+ /**
+ * Example data provider.
+ *
+ * @return array(array)
+ */
+ public static function dataProviderTwo()
+ {
+ return array(
+ array( 17, 42 ),
+ array( 13, 23 ),
+ array( 42, 17 ),
+ array( 23, 13 ),
+ );
+ }
+}
diff --git a/projects/languages/php/php-sonar-runner/README.md b/projects/languages/php/php-sonar-runner/README.md
new file mode 100644
index 00000000..70c9b27d
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a PHP project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube PHP Plugin](http://docs.sonarqube.org/display/PLUG/PHP+Plugin) 2.8+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/php/php-sonar-runner/sonar-project.properties b/projects/languages/php/php-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..b39c3467
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:php-simple-sq-scanner
+sonar.projectName=PHP :: Simple Project :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=php
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/php/php-sonar-runner/src/Math.php b/projects/languages/php/php-sonar-runner/src/Math.php
new file mode 100644
index 00000000..5c1ab480
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner/src/Math.php
@@ -0,0 +1,214 @@
+.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Manuel Pichler nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package Example
+ * @author Manuel Pichler
+ * @copyright 2007-2009 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id: Math.php 4429 2009-01-04 15:39:45Z mapi $
+ * @link http://www.phpundercontrol.org/
+ */
+function add($v1 , $v2)
+ {
+ return ($v1 + $v2);
+ }
+
+/**
+ * Simple math class.
+ *
+ * @package Example
+ * @author Manuel Pichler
+ * @copyright 2007-2009 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: 0.5.0
+ * @link http://www.phpundercontrol.org/
+ */
+class PhpUnderControl_Example_Math
+{
+ /**
+ * Adds the two given values.
+ *
+ * @param integer $v1 Value one.
+ * @param integer $v2 Value two.
+ *
+ * @return integer.
+ */
+ public function add($v1 , $v2)
+ {
+ return ($v1 + $v2);
+ }
+
+ /**
+ * Subtract param two from param one
+ *
+ * @param integer $v1 Value one.
+ * @param integer $v2 Value two.
+ *
+ * @return integer.
+ */
+ public function sub($v1, $v2)
+ {
+ return ($v1 - $v2);
+ }
+
+ /**
+ * Not tested method that should be visible with low coverage.
+ */
+ public function div($v1, $v2)
+ {
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end($d);
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end($d);
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ return $v8;
+ }
+
+ /**
+ * Simple copy for cpd detection.
+ */
+ public function complex($v1, $v2)
+ {
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end( $d );
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ $v3 = $v1 / ($v2 + $v1);
+ if ($v3 > 14)
+ {
+ $v4 = 0;
+ for ($i = 0; $i < $v3; $i++)
+ {
+ $v4 += ($v2 * $i);
+ }
+ }
+ $v5 = ($v4 < $v3 ? ($v3 - $v4) : ($v4 - $v3));
+
+ $v6 = ($v1 * $v2 * $v3 * $v4 * $v5);
+
+ $d = array($v1, $v2, $v3, $v4, $v5, $v6);
+
+ $v7 = 1;
+ for ($i = 0; $i < $v6; $i++)
+ {
+ shuffle( $d );
+ $v7 = $v7 + $i * end($d);
+ }
+
+ $v8 = $v7;
+ foreach ( $d as $x )
+ {
+ $v8 *= $x;
+ }
+
+ return $v8;
+ }
+}
diff --git a/projects/languages/php/php-sonar-runner/validation.txt b/projects/languages/php/php-sonar-runner/validation.txt
new file mode 100644
index 00000000..c583e11e
--- /dev/null
+++ b/projects/languages/php/php-sonar-runner/validation.txt
@@ -0,0 +1,11 @@
+start server
+ with plugin php 2.8
+sonar-runner
+verify org.sonarqube:php-simple-sq-scanner
+ measure lines is 215
+ measure ncloc is 115
+ measure files is 1
+verify org.sonarqube:php-simple-sq-scanner:src/Math.php
+ measure lines is 215
+ measure ncloc is 115
+stop server
diff --git a/projects/languages/pli/README.md b/projects/languages/pli/README.md
new file mode 100644
index 00000000..457ea0be
--- /dev/null
+++ b/projects/languages/pli/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a PL/I project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarSource PL/I Plugin](http://www.sonarsource.com/products/plugins/languages/pli/) 1.3.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/pli/sonar-project.properties b/projects/languages/pli/sonar-project.properties
new file mode 100644
index 00000000..089dfc6d
--- /dev/null
+++ b/projects/languages/pli/sonar-project.properties
@@ -0,0 +1,17 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:pli-simple-sq-scanner
+sonar.projectName=PL/I :: Simple :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=pli
+
+# Properties specific to PL/I
+sonar.pli.marginLeft=2
+sonar.pli.marginRight=0
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/projects/languages/pli/src/center.pli b/projects/languages/pli/src/center.pli
new file mode 100644
index 00000000..d6d79e5b
--- /dev/null
+++ b/projects/languages/pli/src/center.pli
@@ -0,0 +1,212 @@
+ /* Copyright (c) 1995 by R. A. Vowels, from "Introduction to PL/I, Algorithms, and */
+ /* Structured Programming". Permission is given to reproduce and to use these procedures */
+ /* as part of a program, and to include them as part of a larger work to be sold for profit. */
+ /* However, the user is not permitted to sell the procedures separately. Provided always */
+ /* that these procedures and this copyright notice are reproduced in full. */
+
+ DECLARE CENTERLEFT GENERIC
+ (CENTER_LEFT_2 WHEN (*, *),
+ CENTER_LEFT_3 WHEN (*, *, *) );
+ DECLARE CENTER GENERIC
+ (CENTER_LEFT_2 WHEN (*, *),
+ CENTER_LEFT_3 WHEN (*, *, *) );
+ DECLARE CENTERRIGHT GENERIC
+ (CENTER_RIGHT_2 WHEN (*, *),
+ CENTER_RIGHT_3 WHEN (*, *, *) );
+ DECLARE CENTRELEFT GENERIC
+ (CENTER_LEFT_2 WHEN (*, *),
+ CENTER_LEFT_3 WHEN (*, *, *) );
+ DECLARE CENTRERIGHT GENERIC
+ (CENTER_RIGHT_2 WHEN (*, *),
+ CENTER_RIGHT_3 WHEN (*, *, *) );
+ /* This procedure returns a string of length LEN, with STRING in the dead center, or one */
+ /* position to the left of dead center if it cannot be dead center. */
+ CENTER_LEFT_2:
+ PROCEDURE (STRING, LEN) RETURNS (CHARACTER(1000) VARYING);
+ /* INCOMING: STRING = the string to be centered; */
+ /* LEN = the length of the produced string in which STRING is to be */
+ /* centered. */
+ DECLARE STRING CHARACTER (*) VARYING;
+ DECLARE LEN FIXED BINARY;
+
+ DECLARE WORK CHARACTER (LEN);
+ DECLARE (K, L) FIXED BINARY;
+
+ L = LENGTH (STRING);
+ IF L >= LEN THEN RETURN (STRING);
+
+ K = (LEN - L + 2)/2;
+
+ WORK = '';
+ SUBSTR (WORK, K, L) = STRING;
+ RETURN (WORK);
+ END CENTER_LEFT_2;
+
+ /* This procedure returns a string of length LEN, with STRING in the dead center, or one */
+ /* position to the left of dead center if it cannot be dead center. A specified fill */
+ /* character FILL extends STRING right and left. */
+ CENTER_LEFT_3:
+ PROCEDURE (STRING, LEN, FILL) RETURNS (CHARACTER(1000) VARYING);
+ /* INCOMING: STRING = the string to be centered; */
+ /* LEN = the length of the produced string in which STRING is to be */
+ /* centered. */
+ /* FILL = a fill character used to extend STRING at both ends. */
+ DECLARE STRING CHARACTER (*) VARYING;
+ DECLARE LEN FIXED BINARY;
+ DECLARE FILL CHARACTER (1);
+
+ DECLARE WORK CHARACTER (LEN);
+ DECLARE (K, L) FIXED BINARY;
+
+ L = LENGTH (STRING);
+ IF L >= LEN THEN RETURN (STRING);
+
+ K = (LEN - L + 2)/2;
+
+ WORK = REPEAT (FILL, LEN-1);
+ SUBSTR (WORK, K, L) = STRING;
+ RETURN (WORK);
+ END CENTER_LEFT_3;
+
+ /* This procedure returns a string of length LEN, with STRING in the dead center, or one */
+ /* position to the right of dead center if it cannot be dead center. */
+ CENTER_RIGHT_2:
+ PROCEDURE (STRING, LEN) RETURNS (CHARACTER(1000) VARYING);
+ /* INCOMING: STRING = the string to be centered; */
+ /* LEN = the length of the produced string in which STRING is to be */
+ /* centered. */
+ DECLARE STRING CHARACTER (*) VARYING;
+ DECLARE LEN FIXED BINARY;
+
+ DECLARE WORK CHARACTER (LEN);
+ DECLARE (K, L) FIXED BINARY;
+
+ L = LENGTH (STRING);
+ IF L >= LEN THEN RETURN (STRING);
+
+ K = (LEN - L + 3)/2;
+
+ WORK = '';
+ SUBSTR (WORK, K, L) = STRING;
+ RETURN (WORK);
+ END CENTER_RIGHT_2;
+
+ /* This procedure returns a string of length LEN, with STRING in the dead center, or one */
+ /* position to the right of dead center if it cannot be dead center. A specified fill */
+ /* character FILL extends STRING right and left. */
+ CENTER_RIGHT_3:
+ PROCEDURE (STRING, LEN, FILL) RETURNS (CHARACTER(1000) VARYING);
+ /* INCOMING: STRING = the string to be centered; */
+ /* LEN = the length of the produced string in which STRING is to be */
+ /* centered. */
+ /* FILL = a fill character used to extend STRING at both ends. */
+ DECLARE STRING CHARACTER (*) VARYING;
+ DECLARE LEN FIXED BINARY;
+ DECLARE FILL CHARACTER (1);
+
+ DECLARE WORK CHARACTER (LEN);
+ DECLARE (K, L) FIXED BINARY;
+
+ L = LENGTH (STRING);
+ IF L >= LEN THEN RETURN (STRING);
+
+ K = (LEN - L + 3)/2;
+
+ WORK = REPEAT (FILL, LEN-1);
+ SUBSTR (WORK, K, L) = STRING;
+ RETURN (WORK);
+ END CENTER_RIGHT_3;
+
+ DECLARE LEFT GENERIC
+ (LEFT_blank WHEN (*,*),
+ LEFT_other WHEN (*,*,*) );
+
+ /* This procedure returns STRING in a string of length LEN, with blank characters padded on */
+ /* the right. */
+ LEFT_blank:
+ PROCEDURE (STRING, LEN) RETURNS (CHARACTER(1000) VARYING);
+ /* INCOMING: STRING = the string to be positioned left; */
+ /* LEN = the length of the produced string in which STRING is to be */
+ /* placed. */
+ DECLARE STRING CHARACTER (*) VARYING;
+ DECLARE LEN FIXED BINARY;
+
+ DECLARE WORK CHARACTER (LEN);
+ DECLARE L FIXED BINARY;
+
+ L = LENGTH (STRING);
+ IF L >= LEN THEN RETURN (STRING);
+
+ WORK = '';
+ SUBSTR (WORK, 1, L) = STRING;
+ RETURN (WORK);
+ END LEFT_blank;
+
+ /* This procedure returns STRING in a string of length LEN, padded with the character */
+ /* FILL on the right. */
+ LEFT_other:
+ PROCEDURE (STRING, LEN, FILL) RETURNS (CHARACTER(1000) VARYING);
+ /* INCOMING: STRING = the string to be positioned left; */
+ /* LEN = the length of the produced string in which STRING is to be */
+ /* positioned left; */
+ /* FILL = the character to be used to fill out the finished string. */
+ DECLARE STRING CHARACTER (*) VARYING;
+ DECLARE LEN FIXED BINARY;
+ DECLARE FILL CHARACTER (1);
+
+ DECLARE WORK CHARACTER (LEN);
+ DECLARE L FIXED BINARY;
+
+ L = LENGTH (STRING);
+ IF L >= LEN THEN RETURN (STRING);
+
+ WORK = STRING || REPEAT (FILL, LEN-L-1);
+ RETURN (WORK);
+ END LEFT_other;
+
+ DECLARE RIGHT GENERIC
+ (RIGHT_blank WHEN (*,*),
+ RIGHT_other WHEN (*,*,*) );
+
+ /* This procedure returns STRING right-adjusted in a string of length N, padded with blanks */
+ /* on the left. */
+ RIGHT_blank:
+ PROCEDURE (STRING, LEN) RETURNS (CHARACTER(1000) VARYING);
+ /* INCOMING: STRING = the string to be positioned right; */
+ /* LEN = the length of the produced string in which STRING is to be */
+ /* positioned right. */
+ DECLARE STRING CHARACTER (*) VARYING;
+ DECLARE LEN FIXED BINARY;
+
+ DECLARE WORK CHARACTER (LEN);
+ DECLARE L FIXED BINARY;
+
+ L = LENGTH (STRING);
+ IF L >= LEN THEN RETURN (STRING);
+
+ WORK = '';
+ SUBSTR (WORK, LEN-L+1, L) = STRING;
+ RETURN (WORK);
+ END RIGHT_blank;
+
+ /* This procedure returns STRING right-adjusted in a string of length N, padded with the */
+ /* character FILL on the left. */
+ RIGHT_other:
+ PROCEDURE (STRING, LEN, FILL) RETURNS (CHARACTER(1000) VARYING);
+ /* INCOMING: STRING = the string to be positioned right; */
+ /* LEN = the length of the produced string in which STRING is to be */
+ /* positioned right; */
+ /* FILL = the character to be used to fill out the finished string. */
+ DECLARE STRING CHARACTER (*) VARYING;
+ DECLARE LEN FIXED BINARY;
+ DECLARE FILL CHARACTER (1);
+
+ DECLARE WORK CHARACTER (LEN);
+ DECLARE L FIXED BINARY;
+
+ L = LENGTH (STRING);
+ IF L >= LEN THEN RETURN (STRING);
+
+ WORK = REPEAT (FILL, LEN-L-1) || STRING;
+ RETURN (WORK);
+ END RIGHT_other;
diff --git a/projects/languages/pli/src/chess.pli b/projects/languages/pli/src/chess.pli
new file mode 100644
index 00000000..f1e9c1aa
--- /dev/null
+++ b/projects/languages/pli/src/chess.pli
@@ -0,0 +1,760 @@
+ /* This is a chess program written in PL/I. */
+ /* The original was written in Fortran 90 by Dean Menezes. */
+ /* This translation by R. A. Vowels, 30 May 2008. */
+ /* Moves are input in this form: */
+ /* E2-E4 (start square, hyphen, end square). */
+
+ /* Sources: */
+
+ /* http://ai-depot.com/articles/minimax-explained/ */
+ /* http://www.aihorizon.com/essays/chessai/index.htm */
+ /* http://www.ascotti.org/programming/chess/Shannon%20-%20Programming
+ %20a%20computer%20for%20playing%20chess.pdf */
+
+ (SUBRG, SIZE, FOFL, STRINGRANGE, STRINGSIZE):
+ CHESS: PROCEDURE OPTIONS (MAIN, REORDER);
+ /* Global variables: */
+ /* level = current recursion level for calculation */
+ /* maxlevel = maximum recursion level */
+ /* score = current score (evaluation) */
+ /* besta, bestb, bestx, besty = holds best moves for each recursion level */
+ /* wcksflag, wcqsflag = flags to detemine castling abilities */
+ /* board = the 8x8 array to hold chessboard */
+ DECLARE ( MAXLEVEL VALUE ( 5) ) FIXED BINARY;
+ DECLARE ( LEVEL, SCORE, BESTA(0:7) ) FIXED BINARY (31);
+ DECLARE ( BESTB(1:MAXLEVEL), BESTX(1:MAXLEVEL), BESTY(1:MAXLEVEL) ) FIXED
+ BINARY (31);
+ DECLARE ( WCKSFLAG, WCQSFLAG ) BIT(1) ALIGNED;
+ DECLARE ( A, B, X, Y, RES ) FIXED BINARY (31);
+
+
+ /* initialize board to starting position */
+ DECLARE BOARD(0:7, 0:7) FIXED BINARY (31) STATIC INITIAL (
+ -500, -270, -300, -900, -7500, -300, -270, -500,
+ -100, -100, -100, -100, -100, -100, -100, -100,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 100, 100, 100, 100, 100, 100, 100, 100,
+ 500, 270, 300, 900, 5000, 300, 270, 500 );
+
+ LEVEL=0; A=-1; RES=0;
+ WCKSFLAG = '0'B ; WCQSFLAG = '0'B;
+ /* main loop: get white move from user, calculate black move */
+ DO FOREVER;
+ SCORE=0;
+ CALL IO(A, B, X, Y, RES);
+ RES=EVALUATE(-1, 10000);
+ A=BESTA(1); B=BESTB(1); X=BESTX(1); Y=BESTY(1);
+ END;
+
+ /* figure out if white is in check */
+ INCHECK: PROCEDURE () RETURNS( FIXED BINARY (31)) OPTIONS (REORDER);
+ DECLARE (XX(0:26), YY(0:26), CC(0:26)) FIXED BINARY (31);
+ DECLARE (I, A, B, X, Y, NDX) FIXED BINARY (31);
+
+ DO B = 0 TO 7;
+ DO A = 0 TO 7;
+ IF BOARD(B, A)>=0 THEN
+ ITERATE;
+ CALL MOVELIST(A, B, XX, YY, CC, NDX);
+ /* iterate through move list and see if */
+ /* piece can get to king */
+ DO I = 0 TO NDX BY 1;
+ X = XX(I);
+ Y = YY(I);
+ IF BOARD(Y, X) = 5000 THEN
+ RETURN (1);
+ END;
+ END;
+ END;
+ RETURN (0);
+ END INCHECK;
+
+ EVALUATE: PROCEDURE (ID, PRUNE) RETURNS ( FIXED BINARY (31) ) RECURSIVE;
+ DECLARE ( ID, PRUNE ) FIXED BINARY (31);
+ /* local variables. */
+ DECLARE ( XX(0:26), YY(0:26), CC(0:26) ) FIXED BINARY (31);
+ DECLARE ( A, B, X, Y, C, OLDSCORE, BESTSCORE, MOVER, TARG, NDX,
+ I ) FIXED BINARY (31);
+
+ LEVEL=LEVEL+1;
+ BESTSCORE=10000*ID;
+ DO B=7 TO 0 BY -1;
+ DO A=7 TO 0 BY -1;
+ /* generate the moves for all the pieces */
+ /* and iterate through them */
+ IF SIGN(BOARD(B,A))^=ID THEN
+ ITERATE;
+ CALL MOVELIST (A, B, XX, YY, CC, NDX);
+ DO I=0 TO NDX BY 1;
+ X=XX(I); Y=YY(I); C=CC(I);
+ OLDSCORE=SCORE; MOVER=BOARD(B,A); TARG=BOARD(Y,X);
+ /* make the move and evaluate the new position */
+ /* recursively. Targ holds the relative value of the piece */
+ /* allowing use to calculate material gain/loss */
+ CALL MAKEMOVE (A, B, X, Y, C);
+ IF LEVELBESTSCORE) | (ID>0 & SCORE=PRUNE) | (ID>0 & BESTSCORE<=PRUNE) THEN
+ DO;
+ BOARD(B,A)=MOVER; BOARD(Y,X)=TARG; SCORE=OLDSCORE;
+ LEVEL=LEVEL-1;
+ RETURN (BESTSCORE);
+ END;
+ END;
+ BOARD(B,A)=MOVER; BOARD(Y,X)=TARG; SCORE=OLDSCORE;
+ END;
+ END;
+ END;
+ LEVEL=LEVEL-1;
+ RETURN (BESTSCORE);
+ END EVALUATE;
+
+ /* make a move given the start square and end square */
+ /* currently always promotes to queen */
+ /* Moves from position (A, B) to position (X,Y). */
+
+ MAKEMOVE: PROCEDURE (A, B, X, Y, C) OPTIONS (REORDER);
+ DECLARE (A, B, X, Y, C) FIXED BINARY (31);
+ DECLARE (XX(0:26), YY(0:26)) FIXED BINARY (31);
+
+ BOARD(Y, X)=BOARD(B, A); BOARD(B, A)=0;
+ IF Y = 0 & BOARD(Y, X) = 100 THEN
+ BOARD(Y, X)= C;
+ IF Y = 7 & BOARD(Y, X) = -100 THEN
+ BOARD(Y, X)= C;
+ RETURN;
+ END MAKEMOVE;
+
+ /* select appropriate subprogram to populate xx and yy arrays */
+ /* with piece moves */
+ /* xx = x coordinates */
+ /* yy = y coordinates */
+ /* cc = pawn promotion if applicable */
+ /* ndx = index into xx, yy, cc arrays showing the number of */
+ /* elements that the arrays have been populated with */
+ MOVELIST: PROCEDURE (A, B, XX, YY, CC, NDX) OPTIONS (REORDER);
+ DECLARE (A, B) FIXED BINARY (31);
+ DECLARE (XX(0:26), YY(0:26), CC(0:26)) FIXED BINARY (31);
+ DECLARE (NDX) FIXED BINARY (31);
+ DECLARE (PIECE) FIXED BINARY (31);
+
+ PIECE=ABS(BOARD(B, A)); NDX=-1;
+ SELECT (PIECE);
+ WHEN (100) CALL PAWN(A, B, XX, YY, CC, NDX);
+ WHEN (270) CALL KNIGHT(A, B, XX, YY, NDX);
+ WHEN (300) CALL BISHOP(A, B, XX, YY, NDX);
+ WHEN (500) CALL ROOK(A, B, XX, YY, NDX);
+ WHEN (900) CALL QUEEN(A, B, XX, YY, NDX);
+ OTHERWISE CALL KING(A, B, XX, YY, NDX);
+ END;
+ RETURN;
+ END MOVELIST;
+
+ /* queen is a combination of rook and bishop */
+ QUEEN: PROCEDURE (A, B, XX, YY, NDX) OPTIONS (REORDER);
+ DECLARE (A, B) FIXED BINARY (31);
+ DECLARE (XX(0:26), YY(0:26)) FIXED BINARY (31);
+ DECLARE NDX FIXED BINARY (31);
+
+ CALL ROOK(A, B, XX, YY, NDX);
+ CALL BISHOP(A, B, XX, YY, NDX);
+ RETURN;
+ END QUEEN;
+
+
+ KING: PROCEDURE (A, B, XX, YY, NDX) OPTIONS (REORDER);
+ DECLARE (A, B) FIXED BINARY (31);
+ DECLARE (XX(0:26), YY(0:26)) FIXED BINARY (31);
+ DECLARE NDX FIXED BINARY (31);
+ DECLARE (ID, DX, DY) FIXED BINARY (31);
+
+ ID=SIGN(BOARD(B, A));
+ /* negative = left or up */
+ /* positive = right or down */
+ /* zero = no change */
+ DO DY=-1 TO 1;
+ IF B+DY<0 | B+DY>7 THEN
+ ITERATE;
+ DO DX=-1 TO 1;
+ IF A+DX<0 | A+DX>7 THEN
+ ITERATE;
+ IF ID^=SIGN(BOARD(B+DY,A+DX)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=A+DX; YY(NDX)=B+DY;
+ END;
+ END;
+ END;
+ RETURN;
+ END KING;
+
+
+ PAWN: PROCEDURE (A, B, XX, YY, CC, NDX) OPTIONS (REORDER);
+ DECLARE (A, B) FIXED BINARY (31);
+ DECLARE (XX(0:26), YY(0:26), CC(0:26)) FIXED BINARY (31);
+ DECLARE NDX FIXED BINARY (31);
+ DECLARE (I, ID) FIXED BINARY (31);
+
+ ID = SIGN(BOARD(B, A));
+ IF ((A - 1) >= 0) & ((A - 1) <= 7) & ((B - ID) >= 0) & ((B -
+ ID) <= 7) THEN
+ DO;
+ IF SIGN(BOARD((B - ID), (A - 1))) = -ID THEN
+ DO;
+ IF ((ID<0) & (B = 6)) | ((ID>0) & (B = 1)) THEN
+ DO;
+ CC(NDX+1) = 270*ID;
+ CC(NDX+2) = 300*ID;
+ CC(NDX+3) = 500*ID;
+ CC(NDX+4) = 900*ID;
+ DO I=1 TO 4;
+ NDX = NDX + 1;
+ XX(NDX) = A - 1;
+ YY(NDX) = B - ID;
+ END;
+ END;
+ ELSE
+ DO;
+ NDX = NDX + 1;
+ XX(NDX) = A - 1;
+ YY(NDX) = B - ID;
+ END;
+ END;
+ END;
+ IF ((A + 1) >= 0) & ((A + 1) <= 7) & ((B - ID) >= 0) & ((B
+ - ID) <= 7) THEN
+ DO;
+ IF SIGN(BOARD((B - ID), (A + 1))) = -ID THEN
+ DO;
+ IF ((ID<0) & (B = 6)) | ((ID>0) & (B = 1)) THEN
+ DO;
+ CC(NDX+1) = 270*ID;
+ CC(NDX+2) = 300*ID;
+ CC(NDX+3) = 500*ID;
+ CC(NDX+4) = 900*ID;
+ DO I=1 TO 4;
+ NDX = NDX + 1;
+ XX(NDX) = A + 1;
+ YY(NDX) = B - ID;
+ END;
+ END;
+ ELSE
+ DO;
+ NDX = NDX + 1;
+ XX(NDX) = A + 1;
+ YY(NDX) = B - ID;
+ END;
+ END;
+ END;
+ IF (A >= 0) & (A <= 7) & ((B - ID) >= 0) & ((B - ID) <= 7) THEN
+ DO;
+ IF BOARD((B - ID), A) = 0 THEN
+ DO;
+ IF ((ID<0) & (B = 6)) | ((ID>0) & (B = 1)) THEN
+ DO;
+ CC(NDX+1) = 270*ID;
+ CC(NDX+2) = 300*ID;
+ CC(NDX+3) = 500*ID;
+ CC(NDX+4) = 900*ID;
+ DO I=1 TO 4;
+ NDX = NDX + 1;
+ XX(NDX) = A;
+ YY(NDX) = B - ID;
+ END;
+ END;
+ ELSE
+ DO;
+ NDX = NDX + 1;
+ XX(NDX) = A;
+ YY(NDX) = B - ID;
+ END;
+ IF ((ID < 0) & (B = 1)) | ((ID > 0) & (B = 6)) THEN
+ DO;
+ IF BOARD((B - ID - ID), A) = 0 THEN
+ DO;
+ NDX = NDX + 1;
+ XX(NDX) = A;
+ YY(NDX) = B - ID - ID;
+ END;
+ END;
+ END;
+ END;
+ END PAWN;
+
+
+ BISHOP: PROCEDURE (A, B, XX, YY, NDX) OPTIONS (REORDER);
+ DECLARE (A, B) FIXED BINARY (31);
+ DECLARE (XX(0:26), YY(0:26)) FIXED BINARY (31);
+ DECLARE NDX FIXED BINARY (31);
+ DECLARE (ID, DXY, X, Y) FIXED BINARY;
+
+ ID=SIGN(BOARD(B, A));
+ /* four diagonal directions */
+ DO DXY=1 TO 7;
+ X=A-DXY; IF (X<0) THEN LEAVE;
+ Y=B+DXY; IF (Y>7) THEN LEAVE;
+ IF ID^=SIGN(BOARD(Y, X)) THEN /* cannot capture piece of same color */
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ IF BOARD(Y, X)^=0 THEN
+ LEAVE /* cannot jump over pieces */;
+ END;
+ DO DXY=1 TO 7;
+ X=A+DXY; IF (X>7) THEN LEAVE;
+ Y=B+DXY; IF (Y>7) THEN LEAVE;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ IF BOARD(Y, X)^=0 THEN
+ LEAVE;
+ END;
+ DO DXY=1 TO 7;
+ X=A-DXY; IF (X<0) THEN LEAVE;
+ Y=B-DXY; IF (Y<0) THEN LEAVE;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ IF BOARD(Y, X)^=0 THEN
+ LEAVE;
+ END;
+ DO DXY=1 TO 7;
+ X=A+DXY; IF (X>7) THEN LEAVE;
+ Y=B-DXY; IF (Y<0) THEN LEAVE;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ IF BOARD(Y, X)^=0 THEN
+ LEAVE;
+ END;
+ END BISHOP;
+
+ ROOK: PROCEDURE (A, B, XX, YY, NDX) OPTIONS (REORDER);
+ DECLARE (A, B) FIXED BINARY (31);
+ DECLARE (XX(0:26), YY(0:26)) FIXED BINARY (31);
+ DECLARE NDX FIXED BINARY (31);
+ DECLARE (ID, X, Y) FIXED BINARY (31);
+
+ ID=SIGN(BOARD(B, A));
+ /* four different orthagonal directions */
+ DO X = A-1 TO 0 BY -1;
+ IF ID^=SIGN(BOARD(B, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=B;
+ END;
+ IF BOARD(B, X)^=0 THEN
+ LEAVE;
+ END;
+ DO X = A+1 TO 7 BY 1;
+ IF ID^=SIGN(BOARD(B, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=B;
+ END;
+ IF BOARD(B, X)^=0 THEN
+ LEAVE;
+ END;
+ DO Y = B-1 TO 0 BY -1;
+ IF ID^=SIGN(BOARD(Y, A)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=A; YY(NDX)=Y;
+ END;
+ IF BOARD(Y, A)^=0 THEN
+ LEAVE;
+ END;
+ DO Y = B+1 TO 7 BY 1;
+ IF ID^=SIGN(BOARD(Y, A)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=A; YY(NDX)=Y;
+ END;
+ IF BOARD(Y, A)^=0 THEN
+ LEAVE;
+ END;
+ RETURN;
+ END ROOK;
+
+
+ KNIGHT: PROCEDURE (A, B, XX, YY, NDX) OPTIONS (REORDER);
+ DECLARE (A, B) FIXED BINARY (31);
+ DECLARE (XX(0:26), YY(0:26)) FIXED BINARY (31);
+ DECLARE NDX FIXED BINARY (31);
+ DECLARE (ID, X, Y) FIXED BINARY (31);
+
+ ID=SIGN(BOARD(B, A));
+ /* 2 vertical, 1 horizontal */
+ /* or 2 horizontal, 1 vertical */
+ X=A-1; Y=B-2;
+ IF X>=0 & Y>=0 THEN
+ DO;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ END;
+ X=A-2; Y=B-1;
+ IF X>=0 & Y>=0 THEN
+ DO;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ END;
+ X=A+1; Y=B-2;
+ IF X<=7 & Y>=0 THEN
+ DO;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ END;
+ X=A+2; Y=B-1;
+ IF X<=7 & Y>=0 THEN
+ DO;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ END;
+ X=A-1; Y=B+2;
+ IF X>=0 & Y<=7 THEN
+ DO;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ END;
+ X=A-2; Y=B+1;
+ IF X>=0 & Y<=7 THEN
+ DO;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ END;
+ X=A+1; Y=B+2;
+ IF X<=7 & Y<=7 THEN
+ DO;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ END;
+ X=A+2; Y=B+1;
+ IF X<=7 & Y<=7 THEN
+ DO;
+ IF ID^=SIGN(BOARD(Y, X)) THEN
+ DO;
+ NDX=NDX+1; XX(NDX)=X; YY(NDX)=Y;
+ END;
+ END;
+ RETURN;
+ END KNIGHT;
+
+ /* display chessboard */
+ SHOW: PROCEDURE OPTIONS (REORDER);
+ DECLARE (A, B) FIXED BINARY (31);
+
+ DO B=0 TO 7;
+ PUT SKIP EDIT ( ' +---+---+---+---+---+---+---+---+' )(COL(20), A);
+ PUT SKIP EDIT ( 8-B, ' |' )(COL(20), F(1), A);
+ DO A=0 TO 7;
+ SELECT (BOARD(B, A));
+ WHEN (-7500) PUT EDIT ( ' *k|' )(A);
+ WHEN (-900) PUT EDIT ( ' *q|' )(A);
+ WHEN (-500) PUT EDIT ( ' *r|' )(A);
+ WHEN (-300) PUT EDIT ( ' *b|' )(A);
+ WHEN (-270) PUT EDIT ( ' *n|' )(A);
+ WHEN (-100) PUT EDIT ( ' *p|' )(A);
+ WHEN (0) PUT EDIT ( ' |' )(A);
+ WHEN (100) PUT EDIT ( ' P |' )(A);
+ WHEN (270) PUT EDIT ( ' N |' )(A);
+ WHEN (300) PUT EDIT ( ' B |' )(A);
+ WHEN (500) PUT EDIT ( ' R |' )(A);
+ WHEN (900) PUT EDIT ( ' Q |' )(A);
+ WHEN (5000) PUT EDIT ( ' K |' )(A);
+ END;
+ END;
+ END;
+ PUT SKIP EDIT ( ' +---+---+---+---+---+---+---+---+' )(COL(20), A);
+ PUT SKIP EDIT ( ' A B C D E F G H' )(COL(20), A);
+ RETURN;
+ END SHOW;
+
+ /* io -- input/output: */
+ /* display black move and get white move */
+ IO: PROCEDURE (A, B, X, Y, RES) OPTIONS (REORDER);
+ DECLARE (A, B, X, Y, RES) FIXED BINARY (31);
+ DECLARE ( INPUT ) CHARACTER (10);
+ DECLARE (XX(0:26), YY(0:26), CC(0:26)) FIXED BINARY (31);
+ DECLARE (I, K, NDX, PIECE, TARG, MOVER, C) FIXED BINARY (31);
+ DECLARE NULL FIXED BINARY; /* This variable is assigned but never used. */
+ DECLARE LETTER (0:7) CHAR (1) STATIC INITIAL
+ ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H');
+
+ DECLARE SL FIXED BINARY;
+
+ /* >>>>>>>>> CAUTION - WATCH FOR UNINITIALIZED XX, YY <<<<<<<<<<< */
+ DECLARE ( WCKSOLD, WCQSOLD ) BIT(1) ALIGNED;
+
+ ON ERROR SNAP BEGIN;
+ PUT SKIP LIST ('at line ' || TRIM(SL) );
+ END;
+
+ SL = SOURCELINE();
+
+ IF A>=0 THEN
+ DO;
+ IF RES<-2500 THEN
+ DO;
+ PUT SKIP LIST ( 'I RESIGN');
+ CALL SHOW;
+ PUT SKIP;
+ STOP;
+ END;
+ PIECE=BOARD(Y, X);
+ CALL MAKEMOVE(A, B, X, Y, C);
+ PUT SKIP EDIT ( 'MY MOVE: ' )(A);
+ PUT EDIT ( LETTER(A), 8-B, '-', LETTER(X), 8-Y)
+ (A, F(1), A, A, F(1));
+
+ SELECT (PIECE);
+ WHEN (100) PUT SKIP LIST ( 'I TOOK YOUR PAWN');
+ WHEN (270) PUT SKIP LIST ( 'I TOOK YOUR KNIGHT');
+ WHEN (300) PUT SKIP LIST ( 'I TOOK YOUR BISHOP');
+ WHEN (500) PUT SKIP LIST ( 'I TOOK YOUR ROOK');
+ WHEN (900) PUT SKIP LIST ( 'I TOOK YOUR QUEEN');
+ WHEN (5000) PUT SKIP LIST ( 'I TOOK YOUR KING');
+ OTHERWISE ;
+ END;
+ END;
+ DO_FOREVER1:
+ DO FOREVER;
+ CALL SHOW;
+ PUT SKIP EDIT ( 'YOUR MOVE: ' )(A);
+ RETRY_MOVE:
+ GET EDIT (INPUT) (L);
+ CALL UPCASE(INPUT);
+ IF (INPUT = 'QUIT') | (INPUT = 'BYE') | (INPUT = 'EXIT') THEN
+ STOP;
+ /* castling */
+ IF (INPUT = 'O-O') | (INPUT = '0-0') THEN
+ DO;
+ IF INCHECK() ^= 0 THEN
+ ITERATE DO_FOREVER1; /* cannot castle out of check */
+ IF WCKSFLAG THEN
+ ITERATE DO_FOREVER1;
+ IF BOARD(7, 7) ^= 500 THEN
+ ITERATE DO_FOREVER1;
+ IF (BOARD (7,6) ^= 0) | (BOARD(7,5) ^=0) THEN
+ ITERATE DO_FOREVER1;
+ BOARD(7, 4) = 0;
+ BOARD(7, 5) = 5000;
+ IF INCHECK() ^= 0 THEN /* cannot castle through check */
+ DO;
+ BOARD(7, 4) = 5000;
+ BOARD(7, 5) = 0;
+ ITERATE DO_FOREVER1;
+ END;
+ ELSE
+ DO;
+ BOARD(7, 4) = 5000;
+ BOARD(7, 5) = 0;
+ END;
+ BOARD(7, 6) = 5000;
+ BOARD(7, 4) = 0;
+ BOARD(7, 5) = 500;
+ BOARD(7, 7) = 0;
+ IF INCHECK() ^= 0 THEN /* cannot castle into check */
+ DO;
+ BOARD(7, 6) = 0;
+ BOARD(7, 4) = 5000;
+ BOARD(7, 5) = 0;
+ BOARD(7, 7) = 500;
+ ITERATE DO_FOREVER1;
+ END;
+ ELSE
+ DO;
+ WCKSFLAG = '1'B;
+ WCQSFLAG = '1'B;
+ RETURN;
+ END;
+ END;
+ IF (INPUT = 'O-O-O') | (INPUT = '0-0-0') THEN
+ DO;
+ IF INCHECK() ^= 0 THEN
+ ITERATE DO_FOREVER1; /* cannot castle out of check */
+ IF WCQSFLAG THEN
+ ITERATE DO_FOREVER1;
+ IF BOARD(7,0) ^= 500 THEN
+ ITERATE DO_FOREVER1;
+ IF (BOARD(7,1) ^= 0) | (BOARD(7,2) ^= 0) | (BOARD(7,3) ^= 0) THEN
+ ITERATE DO_FOREVER1;
+ BOARD(7, 4) = 0;
+ BOARD(7, 3) = 5000;
+ IF INCHECK() ^= 0 THEN /* cannot castle through check */
+ DO;
+ BOARD(7, 4) = 5000;
+ BOARD(7, 3) = 0;
+ ITERATE DO_FOREVER1;
+ END;
+ ELSE
+ DO;
+ BOARD(7, 4) = 5000;
+ BOARD(7, 3) = 0;
+ END;
+ BOARD(7, 2) = 5000;
+ BOARD(7, 4) = 0;
+ BOARD(7, 3) = 500;
+ BOARD(7, 0) = 0;
+ IF INCHECK() ^= 0 THEN /* cannot castle into check */
+ DO;
+ BOARD(7, 2) = 0;
+ BOARD(7, 4) = 5000;
+ BOARD(7, 3) = 0;
+ BOARD(7, 0) = 500;
+ ITERATE DO_FOREVER1;
+ END;
+ ELSE
+ DO;
+ WCKSFLAG = '1'B;
+ WCQSFLAG = '1'B;
+ RETURN;
+ END;
+ END;
+
+ /* Check that only the proper letters A-H etc are used. */
+ /* (this does not check that the letters are in their correct columns.) */
+ I = VERIFY (TRIM(INPUT), 'ABCDEFGHO0-12345678');
+ IF I > 0 THEN
+ DO;
+ PUT SKIP LIST ('That move was invalid. Please try again:');
+ GO TO RETRY_MOVE;
+ END;
+
+ SL = SOURCELINE();
+
+ /* (A,B) are co-ordinates of the from position. */
+ /* (X,Y) are co-ordinates of the destination position. */
+
+ /* Translate algebraic notation to co-ordinates. */
+
+ B = 8 - INDEX ('12345678', SUBSTR(INPUT, 2, 1) );
+ A = INDEX ('ABCDEFGH', SUBSTR(INPUT, 1, 1) ) - 1;
+ X = INDEX ('ABCDEFGH', SUBSTR(INPUT, 4, 1) ) - 1;
+ Y = 8 - INDEX ('12345678', SUBSTR(INPUT, 5, 1) );
+
+ PUT SKIP DATA (A, B);
+ PUT SKIP DATA (X, Y);
+ STOP;
+ IF B>7 | B<0 | A>7 | A<0 | X>7 | X<0 | Y>7 | Y<0 THEN
+ DO;
+ PUT SKIP LIST ('Illegal move. Please try again');
+ ITERATE DO_FOREVER1;
+ END;
+ IF BOARD(B,A)<=0 THEN
+ ITERATE DO_FOREVER1;
+ /* en passant capture */
+ IF (Y = 2) & (B = 3) & ((X = A-1) | (X = A+1)) THEN
+ DO;
+ IF (BOARD(B,A) = 100) & (BOARD(Y,X) = 0) & (BOARD(Y+1,X) =-100) THEN
+ DO;
+ IF (BESTB(1) = 1) & (BESTA(1) = X) THEN
+ DO;
+ MOVER = BOARD(B,A);
+ TARG = BOARD(Y,X);
+ CALL MAKEMOVE(A,B,X,Y,C);
+ BOARD(Y+1,X)=0;
+ IF (INCHECK()) = 0 THEN
+ RETURN;
+ BOARD(B,A) = MOVER;
+ BOARD(Y, X) = TARG;
+ BOARD(Y+1,X) = -100;
+ ITERATE DO_FOREVER1;
+ END;
+ END;
+ END;
+ /* check if selected white move is on list of moves */
+ CALL MOVELIST(A, B, XX, YY, CC, NDX);
+ DOK_LOOP:
+ DO K = 0 TO NDX BY 1;
+ IF (X = XX(K)) & (Y = YY(K)) THEN
+ DO;
+ MOVER = BOARD(B, A);
+ TARG = BOARD(Y, X);
+ IF Y = 0 THEN
+ FOREVER_LOOP:
+ DO FOREVER;
+ PUT SKIP EDIT ( 'PROMOTION PIECE: ' )(A);
+ GET EDIT (INPUT) (L);
+ CALL UPCASE(INPUT);
+ SELECT (INPUT);
+ WHEN ('N', 'KT', 'KNIGHT', 'HORSE') C = 270;
+ WHEN ('B', 'BISHOP') C = 300;
+ WHEN ('R', 'ROOK') C = 500;
+ WHEN ('Q', 'QUEEN') C = 900;
+ OTHERWISE ITERATE;
+ END;
+ LEAVE FOREVER_LOOP;
+ END;
+ CALL MAKEMOVE(A, B, X, Y, C);
+ IF MOVER = 5000 THEN
+ DO;
+ WCQSOLD = WCQSFLAG;
+ WCKSOLD = WCKSFLAG;
+ WCKSFLAG = '1'B;
+ WCQSFLAG = '1'B;
+ END;
+ IF (A = 0) & (B = 7) & (MOVER = 500) THEN
+ DO;
+ WCQSOLD = WCQSFLAG;
+ WCQSFLAG = '1'B;
+ END;
+ IF (A = 7) & (B = 7) & (MOVER = 500) THEN
+ DO;
+ WCKSOLD = WCKSFLAG;
+ WCKSFLAG = '1'B;
+ END;
+ IF INCHECK() = 0 THEN
+ RETURN;
+ BOARD(B, A) = MOVER;
+ BOARD(Y, X) = TARG;
+ IF MOVER = 5000 THEN
+ DO;
+ WCQSFLAG = WCQSOLD;
+ WCKSFLAG = WCKSOLD;
+ END;
+ IF (A = 0) & (B = 7) & (MOVER = 500) THEN
+ WCQSFLAG = WCQSOLD;
+ IF (A = 7) & (B = 7) & (MOVER = 500) THEN
+ WCKSFLAG = WCKSOLD;
+ LEAVE DOK_LOOP;
+ END;
+ END;
+ END;
+ END IO;
+
+ /* convert string to uppercase */
+ UPCASE: PROCEDURE (STRING) OPTIONS (REORDER);
+ DECLARE ( STRING ) CHARACTER (*);
+
+ STRING = TRANSLATE (STRING, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 'abcdefghijklmnopqrstuvwxyz' );
+
+ END UPCASE;
+
+ END CHESS;
diff --git a/projects/languages/pli/src/maxlen.pli b/projects/languages/pli/src/maxlen.pli
new file mode 100644
index 00000000..c7498b09
--- /dev/null
+++ b/projects/languages/pli/src/maxlen.pli
@@ -0,0 +1,67 @@
+ /* Copyright (c) 1995 by R. A. Vowels, from "Introduction to PL/I, Algorithms, and */
+ /* Structured Programming". Permission is given to reproduce and to use these procedures */
+ /* as part of a program, and to include them as part of a larger work to be sold for profit. */
+ /* However, the user is not permitted to sell the procedures separately. Provided always */
+ /* that these procedures and this copyright notice are reproduced in full. */
+
+ DECLARE MAXLENGTH GENERIC
+ (MAXLEN_graphic WHEN (GRAPHIC),
+ MAXLEN_bit WHEN (BIT),
+ MAXLEN_char WHEN (*) );
+
+ /* This procedure is provided for those who must have the */
+ /* built-in function MAXLENGTH. Do not call it often, as */
+ /* run-time is relatively high. */
+ /* This procedure returns the maximum length that a VARYING character string may take. */
+ MAXLEN_char:
+ PROCEDURE (STRING) RETURNS (FIXED BINARY);
+ DECLARE STRING CHARACTER (*) VARYING;
+
+ DECLARE LENGTH BUILTIN;
+ DECLARE TEMP CHARACTER (32767) VARYING;
+ DECLARE STR CHARACTER (32767) STATIC INITIAL ( ' ' );
+ DECLARE K FIXED BINARY;
+
+ TEMP = STRING; /* Preserve a copy of the string. */
+ (NOSTRINGSIZE):
+ STRING = STR; /* Assign something very long to it. */
+ K = LENGTH (STRING); /* Find out how long the variable is. */
+ STRING = TEMP; /* Restore the string. */
+ RETURN (K); /* The declared length of the string. */
+ END MAXLEN_char;
+
+ /* This procedure returns the maximum length that a VARYING graphic string may take. */
+ MAXLEN_graphic:
+ PROCEDURE (STRING) RETURNS (FIXED BINARY);
+ DECLARE STRING GRAPHIC (*) VARYING;
+
+ DECLARE LENGTH BUILTIN;
+ DECLARE TEMP GRAPHIC (16383) VARYING;
+ DECLARE STR GRAPHIC (16383) STATIC INITIAL ( ' ' );
+ DECLARE K FIXED BINARY;
+
+ TEMP = STRING; /* Preserve a copy of the string. */
+ (NOSTRINGSIZE):
+ STRING = STR; /* Assign something very long to it. */
+ K = LENGTH (STRING); /* Find out how long the variable is. */
+ STRING = TEMP; /* Restore the string. */
+ RETURN (K); /* The declared length of the string. */
+ END MAXLEN_graphic;
+
+ /* This procedure returns the maximum length that a VARYING bit string may take. */
+ MAXLEN_bit:
+ PROCEDURE (STRING) RETURNS (FIXED BINARY);
+ DECLARE STRING BIT (*) VARYING;
+
+ DECLARE LENGTH BUILTIN;
+ DECLARE TEMP BIT (32767) VARYING;
+ DECLARE STR BIT (32767) STATIC INITIAL ( '0'B);
+ DECLARE K FIXED BINARY;
+
+ TEMP = STRING; /* Preserve a copy of the string. */
+ (NOSTRINGSIZE):
+ STRING = STR; /* Assign something very long to it. */
+ K = LENGTH (STRING); /* Find out how long the variable is. */
+ STRING = TEMP; /* Restore the string. */
+ RETURN (K); /* The declared length of the string. */
+ END MAXLEN_bit;
diff --git a/projects/languages/pli/src/search.pli b/projects/languages/pli/src/search.pli
new file mode 100644
index 00000000..ed9a2314
--- /dev/null
+++ b/projects/languages/pli/src/search.pli
@@ -0,0 +1,246 @@
+ /* Copyright (c) 1995 by R. A. Vowels, from "Introduction to PL/I, Algorithms, and */
+ /* Structured Programming". Permission is given to reproduce and to use these procedures */
+ /* as part of a program, and to include them as part of a larger work to be sold for profit. */
+ /* However, the user is not permitted to sell the procedures separately. Provided always */
+ /* that these procedures and this copyright notice are reproduced in full. */
+
+ DECLARE SEARCH GENERIC
+ (SEARCH_all_graphic WHEN ( GRAPHIC, GRAPHIC),
+ SEARCH_all_graphic WHEN ( GRAPHIC, *),
+ SEARCH_all_graphic WHEN (*, GRAPHIC),
+ SEARCH_all_bit WHEN ( BIT, BIT),
+ SEARCH_all WHEN (*,*),
+ SEARCH_sub_graphic WHEN ( GRAPHIC, GRAPHIC, *),
+ SEARCH_sub_graphic WHEN ( GRAPHIC, *, *),
+ SEARCH_sub_graphic WHEN (*, GRAPHIC, *),
+ SEARCH_sub_bit WHEN ( BIT, BIT, *),
+ SEARCH_sub WHEN (*,*,*) );
+
+ /* This function procedure searches the first string STRING for any characters given in the */
+ /* second string SUB. If there are any such characters, the function returns the position */
+ /* of the left-most. */
+ SEARCH_all:
+ PROCEDURE (STRING, SUB) OPTIONS (REORDER)
+ RETURNS (FIXED BINARY (31));
+ /* INCOMING: STRING = the string to be searched; */
+ /* SUB = contains characters to look for. */
+ DECLARE (STRING, SUB) CHARACTER (*);
+
+ DECLARE (LENGTH, SUBSTR,
+ UNSPEC, INDEX) BUILTIN;
+ DECLARE Table (0:255) BIT (1) STATIC ALIGNED;
+ DECLARE (J, K) FIXED BINARY (31);
+
+ IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */
+ RETURN (0);
+ IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */
+ RETURN (0);
+ IF LENGTH (SUB) = 1 THEN /* Looking for one character is fast. */
+ RETURN (INDEX (STRING, SUB));
+
+ /* SETS UP A LOOK-UP TABLE (which is independent of the character set). */
+ Table = '0'B; /* All entries are FALSE. */
+ DO J = 1 TO LENGTH (Sub);
+ K = UNSPEC (SUBSTR (Sub, J, 1));
+ Table (K) = '1'B; /* Table(k) is TRUE for each character in SUB. */
+ END;
+
+ /* CONDUCT THE SEARCH. */
+ DO J = 1 TO LENGTH (STRING);
+ K = UNSPEC (SUBSTR (STRING, J, 1));
+ IF Table(K) THEN /* TRUE when a SUB character matches one in */
+ RETURN (J); /* STRING. */
+ END;
+ RETURN (0); /* Unsuccessful search. */
+ END SEARCH_all;
+
+ /* This function procedure searches the first string STRING for any characters given in the */
+ /* second string SUB. If there are any such characters, the function returns the position */
+ /* of the left-most. */
+ /* The search is performed from left to right, commencing from character position */
+ /* POSITION. */
+ SEARCH_sub:
+ PROCEDURE (STRING, SUB, POSITION) RETURNS (FIXED BINARY (31));
+ /* INCOMING: STRING = the string to be searched; */
+ /* SUB = contains characters to look for; */
+ /* POSITION = where to start the search (measured from the left-hand end of */
+ /* STRING). */
+ DECLARE (STRING, SUB) CHARACTER (*);
+ DECLARE POSITION FIXED BINARY (31);
+
+ DECLARE (LENGTH, INDEX) BUILTIN;
+ DECLARE K FIXED BINARY (31);
+
+ IF (Position > LENGTH (String)+1) | (Position <= 0) THEN
+ DO;
+ SIGNAL STRINGRANGE;
+ RETURN (0);
+ END;
+ IF LENGTH (STRING) = 0 THEN RETURN (0);
+ K = SEARCH_all ( SUBSTR (STRING, POSITION), SUB);
+ IF K = 0 THEN RETURN (0);
+ RETURN (POSITION+K-1);
+ END SEARCH_sub;
+
+ /* This function procedure searches the first string STRING for any characters given in the */
+ /* second string SUB. If there are any such characters, the function returns the position */
+ /* of the left-most. */
+ SEARCH_all_graphic:
+ PROCEDURE (STRING, SUB) OPTIONS (REORDER)
+ RETURNS ( FIXED BINARY (31));
+ /* INCOMING: STRING = the string to be searched; */
+ /* SUB = contains characters to look for. */
+ DECLARE (STRING, SUB) GRAPHIC (*);
+
+ DECLARE (LENGTH,
+ SUBSTR,
+ INDEX) BUILTIN;
+ DECLARE (J, K) FIXED BINARY (31);
+ DECLARE Ch GRAPHIC (1);
+
+ IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */
+ RETURN (0);
+ IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */
+ RETURN (0);
+ IF LENGTH (SUB) = 1 THEN /* Looking for one character is fast. */
+ RETURN (INDEX (STRING, SUB));
+
+ DO J = 1 TO LENGTH(String);
+ Ch = SUBSTR(String, J, 1); /* Select one graphic character from the string to*/
+ /* be searched. */
+ K = INDEX (Sub, Ch); /* Check whether it is one of those on our search list.*/
+ IF K ^= 0 THEN /* If it is, we are done. */
+ RETURN (J);
+ END;
+
+ RETURN (0); /* The search was unsuccessful. */
+ END SEARCH_all_graphic;
+
+ /* This function procedure searches the first string STRING for any graphic characters */
+ /* given in the second string SUB. If there are any such graphic characters, the function */
+ /* returns the position of the left-most. */
+ /* The search is performed from left to right, commencing from graphic character position */
+ /* POSITION. */
+ SEARCH_sub_graphic:
+ PROCEDURE (STRING, SUB, POSITION) RETURNS (FIXED BINARY (31));
+ /* INCOMING: STRING = the string to be searched; */
+ /* SUB = contains characters to look for; */
+ /* POSITION = where to start the search (measured from the left-hand end of */
+ /* STRING). */
+ DECLARE (STRING, SUB) GRAPHIC (*);
+ DECLARE POSITION FIXED BINARY (31);
+
+ DECLARE (LENGTH, SUBSTR,
+ INDEX) BUILTIN;
+ DECLARE (J, K) FIXED BINARY (31);
+ DECLARE Ch GRAPHIC (1);
+
+ IF (Position > LENGTH (String)+1) | (Position <= 0) THEN
+ DO;
+ SIGNAL STRINGRANGE;
+ RETURN (0);
+ END;
+ IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */
+ RETURN (0);
+ IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */
+ RETURN (0);
+ IF LENGTH (SUB) = 1 THEN /* Looking for one character is fast. */
+ RETURN (INDEX (SUBSTR (STRING, Position), SUB)+Position-1);
+
+ DO J = Position TO LENGTH(String);
+ Ch = SUBSTR(String, J, 1); /* Select one graphic character from the string to */
+ /* be searched. */
+ K = INDEX (Sub, Ch); /* Check whether it is one of those on our search list.*/
+ IF K ^= 0 THEN /* If it is, we are done. */
+ RETURN (J);
+ END;
+
+ RETURN (0); /* The search was unsuccessful. */
+
+ END SEARCH_sub_graphic;
+
+ /* This function procedure searches the first string STRING for any bits given in the */
+ /* second string SUB. If there are any such bits, the function returns the position */
+ /* of the left-most. */
+ SEARCH_all_bit:
+ PROCEDURE (STRING, SUB) OPTIONS (REORDER)
+ RETURNS ( FIXED BINARY (31));
+ /* INCOMING: STRING = the string to be searched; */
+ /* SUB = contains bits to look for. */
+ DECLARE (STRING, SUB) BIT (*);
+
+ DECLARE (LENGTH, SUBSTR,
+ INDEX) BUILTIN;
+ DECLARE (J, K) FIXED BINARY (31);
+
+ IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */
+ RETURN (0);
+ IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */
+ RETURN (0);
+ IF LENGTH (SUB) = 1 THEN /* Looking for one bit is fast. */
+ RETURN (INDEX (STRING, SUB));
+
+ /* When we come here, SUB has 2 or more bits. */
+
+ K = INDEX (SUB, ^SUBSTR(SUB, 1, 1)); /* Look for a bit of the opposite kind. */
+
+ IF K > 0 THEN /* No need for a search -- the key SUB consists */
+ /* of both 0 and 1. */
+ RETURN (1); /* Always get a match at position 1. */
+
+ /* The pattern SUB contains either all ones or all zeros. */
+
+ /* CONDUCT THE SEARCH. */
+ IF SUBSTR(SUB, 1, 1) THEN
+ RETURN (INDEX(STRING, '1'B));
+ ELSE
+ RETURN (INDEX(STRING, '0'B));
+
+ END SEARCH_all_bit;
+
+ /* This function procedure searches the first string STRING for any bits given in the */
+ /* second string SUB. If there are any such bits, the function returns the position */
+ /* of the left-most. */
+ SEARCH_sub_bit:
+ PROCEDURE (String, Sub, Position) OPTIONS (REORDER)
+ RETURNS ( FIXED BINARY (31));
+ /* INCOMING: STRING = the string to be searched; */
+ /* SUB = contains bits to look for. */
+ DECLARE (String, Sub) BIT (*);
+
+ DECLARE (LENGTH, SUBSTR,
+ INDEX) BUILTIN;
+ DECLARE (J, K) FIXED BINARY (31);
+
+ IF (Position > LENGTH (String)+1) | (Position <= 0) THEN
+ DO;
+ SIGNAL STRINGRANGE;
+ RETURN (0);
+ END;
+ IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */
+ RETURN (0);
+ IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */
+ RETURN (0);
+ IF Position = LENGTH(String)+1 THEN
+ RETURN (0);
+ IF LENGTH (SUB) = 1 THEN /* Looking for one bit is fast. */
+ RETURN (INDEX(SUBSTR(STRING, Position), SUB)+Position-1);
+
+ /* When we come here, SUB has 2 or more bits. */
+
+ K = INDEX (SUBSTR(String, Position), ^SUBSTR(SUB, 1, 1));
+ /* Look for a bit of the opposite kind. */
+
+ IF K > 0 THEN /* No need for a search -- the key SUB consists */
+ /* of both 0 and 1. */
+ RETURN (Position); /* Always get a match at position "Position". */
+
+ /* The pattern SUB contains either all ones or all zeros. */
+
+ /* CONDUCT THE SEARCH. */
+ IF SUBSTR(SUB, 1, 1) THEN
+ RETURN (INDEX(SUBSTR(STRING, Position), '1'B)+Position-1);
+ ELSE
+ RETURN (INDEX(SUBSTR(STRING, Position), '0'B)+Position-1);
+
+ END SEARCH_sub_bit;
diff --git a/projects/languages/pli/validation.txt b/projects/languages/pli/validation.txt
new file mode 100644
index 00000000..f2fa221f
--- /dev/null
+++ b/projects/languages/pli/validation.txt
@@ -0,0 +1,8 @@
+start server
+ with plugin pli 1.3.1
+sonar-runner
+verify org.sonarqube:pli-simple-sq-scanner
+ measure lines is 1289
+ measure ncloc is 970
+ measure files is 4
+stop server
diff --git a/projects/languages/plsql/plsql-oracle-forms/README.md b/projects/languages/plsql/plsql-oracle-forms/README.md
new file mode 100644
index 00000000..37cf6723
--- /dev/null
+++ b/projects/languages/plsql/plsql-oracle-forms/README.md
@@ -0,0 +1,19 @@
+This example demonstrates how to analyze PL/SQL from Oracle Forms.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarSource PL/SQL Plugin](http://www.sonarsource.com/products/plugins/languages/plsql/) 2.7.1+
+* [SonarQube Oracle Forms PL/SQL Extractor](https://github.com/SonarCommunity/sonar-forms-plsql-extractor) 1.1+
+
+Usage
+=====
+* Extract the PL/SQL source code from your Oracle Forms. Let's say that you downloaded the project sample to C:\plsql-oracle-forms.
+
+ set FORMS_PATH=C:\plsql-oracle-forms\forms
+ java -DinputDir=C:\plsql-oracle-forms\forms -DoutputDir=C:\plsql-oracle-forms\src -cp C:\path\to\sonar-forms-plsql-extractor-X.X-jar-with-dependencies.jar;C:\path\to\oracle\forms\java\frmjdapi.jar org.sonar.oracleforms.plsql.PlSqlExtractor
+
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/plsql/plsql-oracle-forms/forms/ue_samp.fmb b/projects/languages/plsql/plsql-oracle-forms/forms/ue_samp.fmb
new file mode 100644
index 00000000..d946e157
Binary files /dev/null and b/projects/languages/plsql/plsql-oracle-forms/forms/ue_samp.fmb differ
diff --git a/projects/languages/plsql/plsql-oracle-forms/sonar-project.properties b/projects/languages/plsql/plsql-oracle-forms/sonar-project.properties
new file mode 100644
index 00000000..0bee029c
--- /dev/null
+++ b/projects/languages/plsql/plsql-oracle-forms/sonar-project.properties
@@ -0,0 +1,7 @@
+sonar.projectKey=org.sonarqube:plsql-oracle-forms-sq-scanner
+sonar.projectName=Oracle Forms :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.sources=src
+sonar.language=plsql
+sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/projects/languages/plsql/plsql-sonar-runner/README.md b/projects/languages/plsql/plsql-sonar-runner/README.md
new file mode 100644
index 00000000..eb49a95e
--- /dev/null
+++ b/projects/languages/plsql/plsql-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a PL/SQL project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarSource PL/SQL Plugin](http://www.sonarsource.com/products/plugins/languages/plsql/) 2.7.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/plsql/plsql-sonar-runner/sonar-project.properties b/projects/languages/plsql/plsql-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..d88b0a12
--- /dev/null
+++ b/projects/languages/plsql/plsql-sonar-runner/sonar-project.properties
@@ -0,0 +1,10 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:plsql-simple-sq-scanner
+sonar.projectName=PL/SQL :: Simple Project : SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/plsql/plsql-sonar-runner/src/ddl.sql b/projects/languages/plsql/plsql-sonar-runner/src/ddl.sql
new file mode 100644
index 00000000..78a3ddd1
--- /dev/null
+++ b/projects/languages/plsql/plsql-sonar-runner/src/ddl.sql
@@ -0,0 +1,9 @@
+CREATE TABLE OWNER.TABLE01 (ID NUMBER(12));
+/
+ALTER TABLE OWNER.TABLE01 ADD (COL1 VARCHAR2(4000));
+/
+
+CREATE TABLE OWNER.TABLE02 (ID NUMBER(12));
+/
+ALTER TABLE OWNER.TABLE02 ADD (COL1 VARCHAR2(4000));
+/
diff --git a/projects/languages/plsql/plsql-sonar-runner/src/ut_report.pkb b/projects/languages/plsql/plsql-sonar-runner/src/ut_report.pkb
new file mode 100644
index 00000000..15bdc4e4
--- /dev/null
+++ b/projects/languages/plsql/plsql-sonar-runner/src/ut_report.pkb
@@ -0,0 +1,213 @@
+/* Formatted on 2002/03/31 23:53 (Formatter Plus v4.5.2) */
+CREATE OR REPLACE PACKAGE BODY Utreport
+IS
+
+/************************************************************************
+GNU General Public License for utPLSQL
+
+Copyright (C) 2000-2003
+Steven Feuerstein and the utPLSQL Project
+(steven@stevenfeuerstein.com)
+
+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 2 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 (see license.txt); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+************************************************************************
+$Log: ut_report.pkb,v $
+Revision 1.3 2005/05/11 21:33:36 chrisrimmer
+Added testing of reporter infrastructure
+
+Revision 1.2 2004/11/16 09:46:49 chrisrimmer
+Changed to new version detection system.
+
+Revision 1.1 2004/07/14 17:01:57 chrisrimmer
+Added first version of pluggable reporter packages
+
+
+************************************************************************/
+
+ DEFAULT_REPORTER VARCHAR2(100) := 'Output';
+
+ DYNAMIC_PLSQL_FAILURE NUMBER(10) := -6550;
+
+ --This is the reporter we have been asked to use
+ g_reporter VARCHAR2(100);
+
+ --This is the reporter we are actually using
+ --(this differs from the above in the event of error)
+ g_actual VARCHAR2(100);
+
+ FUNCTION parse_it(proc IN VARCHAR2, params IN NUMBER, force_reporter IN VARCHAR2)
+ RETURN INTEGER
+ IS
+ dyn_handle INTEGER := NULL;
+ query VARCHAR2(1000);
+ BEGIN
+ dyn_handle := DBMS_SQL.OPEN_CURSOR;
+ QUERY := 'BEGIN ut' || NVL(force_reporter, g_actual) || 'Reporter.' || proc ;
+ IF params = 1 THEN
+ QUERY := QUERY || '(:p)';
+ END IF;
+ QUERY := QUERY || '; END;';
+ DBMS_SQL.PARSE(dyn_handle, QUERY, DBMS_SQL.NATIVE);
+ RETURN dyn_handle;
+ EXCEPTION
+ WHEN OTHERS THEN
+ DBMS_SQL.CLOSE_CURSOR (dyn_handle);
+ RAISE;
+ END;
+
+ PROCEDURE execute_it(dyn_handle IN OUT INTEGER)
+ IS
+ dyn_result INTEGER;
+ BEGIN
+ dyn_result := DBMS_SQL.EXECUTE (dyn_handle);
+ DBMS_SQL.CLOSE_CURSOR (dyn_handle);
+ END;
+
+ --We use this to make dynamic calls to reporter packages
+ PROCEDURE call(proc IN VARCHAR2,
+ param IN VARCHAR2,
+ params IN NUMBER := 1,
+ force_reporter IN VARCHAR2 := NULL,
+ failover IN BOOLEAN := TRUE)
+ IS
+ dyn_handle INTEGER := NULL;
+ BEGIN
+ dyn_handle := parse_it(proc, params, force_reporter);
+ IF params = 1 THEN
+ DBMS_SQL.BIND_VARIABLE (dyn_handle, 'p', param);
+ END IF;
+ execute_it(dyn_handle);
+ EXCEPTION
+ WHEN OTHERS THEN
+
+ IF dyn_handle IS NOT NULL THEN
+ DBMS_SQL.CLOSE_CURSOR (dyn_handle);
+ END IF;
+
+ IF g_actual <> DEFAULT_REPORTER THEN
+
+ IF NOT failover OR SQLCODE <> DYNAMIC_PLSQL_FAILURE THEN
+ g_actual := DEFAULT_REPORTER;
+ pl(SQLERRM);
+ pl('** REVERTING TO DEFAULT REPORTER **');
+ END IF;
+
+ ELSE
+ RAISE;
+ END IF;
+
+ call(proc, param, params, force_reporter => DEFAULT_REPORTER);
+ END;
+
+ PROCEDURE call(proc IN VARCHAR2,
+ failover IN BOOLEAN := TRUE)
+ IS
+ BEGIN
+ call(proc => proc,
+ param => '',
+ params => 0,
+ failover => failover);
+ END;
+
+ PROCEDURE use(reporter IN VARCHAR2)
+ IS
+ BEGIN
+ g_reporter := NVL(reporter, DEFAULT_REPORTER);
+ g_actual := g_reporter;
+ END;
+
+ FUNCTION using RETURN VARCHAR2
+ IS
+ BEGIN
+ RETURN g_reporter;
+ END;
+
+ PROCEDURE open
+ IS
+ BEGIN
+ g_actual := g_reporter;
+ call('open', failover => FALSE);
+ END;
+
+ PROCEDURE pl (str IN VARCHAR2)
+ IS
+ BEGIN
+ call('pl', str);
+ END;
+
+ PROCEDURE pl (bool IN BOOLEAN)
+ IS
+ BEGIN
+ pl (Utplsql.bool2vc (bool));
+ END;
+
+ PROCEDURE before_results(run_id IN utr_outcome.run_id%TYPE)
+ IS
+ BEGIN
+ call('before_results', run_id);
+ END;
+
+ PROCEDURE show_failure(rec_result IN utr_outcome%ROWTYPE)
+ IS
+ BEGIN
+ outcome := rec_result;
+ call('show_failure');
+ END;
+
+ PROCEDURE show_result(rec_result IN utr_outcome%ROWTYPE)
+ IS
+ BEGIN
+ outcome := rec_result;
+ call('show_result');
+ END;
+
+ PROCEDURE after_results(run_id IN utr_outcome.run_id%TYPE)
+ IS
+ BEGIN
+ call('after_results', run_id);
+ END;
+
+ PROCEDURE before_errors(run_id IN utr_error.run_id%TYPE)
+ IS
+ BEGIN
+ call('before_errors', run_id);
+ END;
+
+ PROCEDURE show_error(rec_error IN utr_error%ROWTYPE)
+ IS
+ BEGIN
+ error := rec_error;
+ call('show_error');
+ END;
+
+ PROCEDURE after_errors(run_id IN utr_error.run_id%TYPE)
+ IS
+ BEGIN
+ call('after_errors', run_id);
+ END;
+
+ PROCEDURE close
+ IS
+ BEGIN
+ call('close');
+ END;
+
+BEGIN
+
+ g_reporter := NVL(utconfig.getreporter, DEFAULT_REPORTER);
+ g_actual := g_reporter;
+
+END;
+/
diff --git a/projects/languages/python/python-sonar-runner-coverage/README.md b/projects/languages/python/python-sonar-runner-coverage/README.md
new file mode 100644
index 00000000..8ddc6a3f
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-coverage/README.md
@@ -0,0 +1,22 @@
+This example demonstrates how to import Python Coverage Execution Results into SonarQube with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Python Plugin](http://docs.sonarqube.org/display/PLUG/Python+Plugin) 1.5+
+* [Coverage from Ned Batchelder](http://nedbatchelder.com/code/coverage/cmd.html)
+
+Tests Execution Results Generation
+==================================
+* Run from your project root directory:
+** coverage erase
+** coverage run --branch --source=src ./src/purchase.py
+** coverage xml -i
+* Path to the generated file coverage.xml is referenced in sonar-project.properties
+
+Usage
+=====
+* Analyze the projec with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/python/python-sonar-runner-coverage/coverage.xml b/projects/languages/python/python-sonar-runner-coverage/coverage.xml
new file mode 100644
index 00000000..2d769712
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-coverage/coverage.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+ /Users/alexandregigleux/Repos/sonar-examples/projects/languages/python/python-sonar-runner-coverage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/languages/python/python-sonar-runner-coverage/sonar-project.properties b/projects/languages/python/python-sonar-runner-coverage/sonar-project.properties
new file mode 100644
index 00000000..e3c48305
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-coverage/sonar-project.properties
@@ -0,0 +1,15 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:python-coverage-sonar-scanner
+sonar.projectName=Python :: Import Coverage Report :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=py
+
+sonar.python.coverage.reportPath=coverage.xml
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/python/python-sonar-runner-coverage/src/purchase.py b/projects/languages/python/python-sonar-runner-coverage/src/purchase.py
new file mode 100644
index 00000000..dfedf672
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-coverage/src/purchase.py
@@ -0,0 +1,9 @@
+print 'Bill Computation Start'
+
+prices = {'apple': 0.40, 'banana': 0.50}
+my_purchase = {
+ 'apple': 1,
+ 'banana': 6}
+grocery_bill = sum(prices[fruit] * my_purchase[fruit]
+ for fruit in my_purchase)
+print 'I owe the grocer $%.2f' % grocery_bill
diff --git a/projects/languages/python/python-sonar-runner-coverage/validation.txt b/projects/languages/python/python-sonar-runner-coverage/validation.txt
new file mode 100644
index 00000000..f89b7b2a
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-coverage/validation.txt
@@ -0,0 +1,8 @@
+start server
+ with plugin python 1.5
+sonar-runner
+verify org.sonarqube:python-coverage-sonar-scanner
+ measure lines is 10
+ measure ncloc is 8
+ measure files is 1
+stop server
diff --git a/projects/languages/python/python-sonar-runner-ut/README.md b/projects/languages/python/python-sonar-runner-ut/README.md
new file mode 100644
index 00000000..e26e1be8
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-ut/README.md
@@ -0,0 +1,19 @@
+This example demonstrates how to import Python Tests Execution Results into SonarQube with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Python Plugin](http://docs.sonarqube.org/display/PLUG/Python+Plugin) 1.5+
+
+Tests Execution Results Generation
+==================================
+* Go in nosetests directory and run the command : nosetests --with-xunit ../src/samples/datepattern.py
+* Tests Execution Results report is generated in nosetests under this name nosetests.xml
+* Path to this file is referenced in sonar-project.properties
+
+Usage
+=====
+* Analyze the projec with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/python/python-sonar-runner-ut/nosetests/nosetests.xml b/projects/languages/python/python-sonar-runner-ut/nosetests/nosetests.xml
new file mode 100644
index 00000000..a69479f8
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-ut/nosetests/nosetests.xml
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/projects/languages/python/python-sonar-runner-ut/sonar-project.properties b/projects/languages/python/python-sonar-runner-ut/sonar-project.properties
new file mode 100644
index 00000000..a6b378a8
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-ut/sonar-project.properties
@@ -0,0 +1,15 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:python-ut-sonar-scanner
+sonar.projectName=Python :: Import Unit Test Report :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=py
+
+sonar.python.xunit.reportPath=nosetests/nosetests.xml
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/python/python-sonar-runner-ut/src/__init__.py b/projects/languages/python/python-sonar-runner-ut/src/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/projects/languages/python/python-sonar-runner-ut/src/samples/__init__.py b/projects/languages/python/python-sonar-runner-ut/src/samples/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/projects/languages/python/python-sonar-runner-ut/src/samples/datepattern.py b/projects/languages/python/python-sonar-runner-ut/src/samples/datepattern.py
new file mode 100644
index 00000000..7250ea70
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-ut/src/samples/datepattern.py
@@ -0,0 +1,34 @@
+import unittest
+import datetime
+
+class DatePattern:
+
+ def __init__(self, year, month, day):
+ self.year = year
+ self.month = month
+ self.day = day
+
+ def matches(self, date):
+ return ((self.year and self.year == date.year or True) and
+ self.month == date.month and
+ self.day == date.day)
+
+class DatePatternTest(unittest.TestCase):
+
+ def testMatchesYearAndMonthAsWildCards(self):
+ p = DatePattern(0, 0, 1)
+ d = datetime.date(2004, 10, 1)
+ self.failUnless(p.matches(d))
+
+ def testMatchesWeekday(self):
+ p = DatePattern(0, 0, 0, 2) # 2 is Wednesday
+ d = datetime.date(2004, 9, 29)
+ self.failUnless(p.matches(d))
+
+ def testMatchesYearAsWildCard(self):
+ p = DatePattern(0, 4, 10)
+ d = datetime.date(2005, 4, 10)
+ self.failUnless(p.matches(d))
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file
diff --git a/projects/languages/python/python-sonar-runner-ut/validation.txt b/projects/languages/python/python-sonar-runner-ut/validation.txt
new file mode 100644
index 00000000..61f75e34
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner-ut/validation.txt
@@ -0,0 +1,11 @@
+start server
+ with plugin python 1.5
+sonar-runner
+verify org.sonarqube:python-ut-sonar-scanner
+ measure lines is 36
+ measure ncloc is 26
+ measure files is 3
+verify org.sonarqube:python-ut-sonar-scanner:src/samples/datepattern.py
+ measure lines is 34
+ measure ncloc is 26
+stop server
diff --git a/projects/languages/python/python-sonar-runner/README.md b/projects/languages/python/python-sonar-runner/README.md
new file mode 100644
index 00000000..dc1974fe
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a Python project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Python Plugin](http://docs.sonarqube.org/display/PLUG/Python+Plugin) 1.5+
+
+Usage
+=====
+* Analyze the projec with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/python/python-sonar-runner/sonar-project.properties b/projects/languages/python/python-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..518873ca
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:python-simple-sonar-scanner
+sonar.projectName=Python :: Simple Project : SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=py
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/python/python-sonar-runner/src/__init__.py b/projects/languages/python/python-sonar-runner/src/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/projects/languages/python/python-sonar-runner/src/badfortune.py b/projects/languages/python/python-sonar-runner/src/badfortune.py
new file mode 100644
index 00000000..b0900dc1
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner/src/badfortune.py
@@ -0,0 +1,92 @@
+
+# fortune.py -- chooses a random fortune, as the fortune(8) program in
+# the BSD-games package does
+#
+# Copyright (c) 2010, Andrew M. Kuchling
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import struct, random, string
+
+# C long variables are different sizes on 32-bit and 64-bit machines,
+# so we have to measure how big they are on the machine where this is running.
+LONG_SIZE = struct.calcsize('L')
+is_64_bit = (LONG_SIZE == 8)
+
+def get(filename):
+ "Select a random quotation, using a pregenerated .dat file"
+
+ # First, we open the .dat file, and read the header information.
+ # The C structure containing this info looks like:
+ ## typedef struct { /* information table */
+ ## #define VERSION 1
+ ## unsigned long str_version; /* version number */
+ ## unsigned long str_numstr; /* # of strings in the file */
+ ## unsigned long str_longlen; /* length of longest string */
+ ## unsigned long str_shortlen; /* length of shortest string */
+ ## #define STR_RANDOM 0x1 /* randomized pointers */
+ ## #define STR_ORDERED 0x2 /* ordered pointers */
+ ## #define STR_ROTATED 0x4 /* rot-13'd text */
+ ## unsigned long str_flags; /* bit field for flags */
+ ## unsigned char stuff[4]; /* long aligned space */
+ ## #define str_delim stuff[0] /* delimiting character */
+ ## } STRFILE;
+
+ datfile = open(filename+'.dat', 'r')
+ data = datfile.read(5 * LONG_SIZE)
+ if is_64_bit:
+ v1, v2, n1, n2, l1, l2, s1, s2, f1, f2 = struct.unpack('!10L', data)
+ version = v1 + (v2 << 32)
+ numstr = n1 + (n2 << 32)
+ longlen = l1 + (l2 << 32)
+ shortlen = s1 + (s2 << 32)
+ flags = f1 + (f2 << 32)
+ else:
+ version, numstr, longlen, shortlen, flags = struct.unpack('5l', data)
+
+ delimiter = datfile.read(1)
+ datfile.read(3) # Throw away padding bytes
+ if is_64_bit: datfile.read(4) # 64-bit machines align to 8 bytes
+
+ # Pick a random number
+ r = random.randint(0, numstr)
+ datfile.seek(LONG_SIZE * r, 1) # Seek to the chosen pointer
+ data = datfile.read(LONG_SIZE * 2)
+
+ if is_64_bit:
+ s1, s2, e1, e2 = struct.unpack('!4L', data)
+ start, end = s1 + (s2 << 32), e1 + (e2 << 32)
+ else:
+ start, end = struct.unpack('!ll', data)
+ datfile.close()
+
+ file = open(filename, 'r')
+ file.seek(start)
+ quotation = file.read(end-start)
+ L=string.split(quotation, '\n')
+ while string.strip(L[-1]) == delimiter or string.strip(L[-1]) == "":
+ L=L[:-1]
+ return string.join(L, '\n')
+
+if __name__ == '__main__':
+ import sys
+ if len(sys.argv) == 1:
+ print 'Usage: fortune.py '
+ sys.exit()
+ print get(sys.argv[1])
diff --git a/projects/languages/python/python-sonar-runner/src/directory/file_in_directory.py b/projects/languages/python/python-sonar-runner/src/directory/file_in_directory.py
new file mode 100644
index 00000000..0708437a
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner/src/directory/file_in_directory.py
@@ -0,0 +1 @@
+lst = []
diff --git a/projects/languages/python/python-sonar-runner/src/package/__init__.py b/projects/languages/python/python-sonar-runner/src/package/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/projects/languages/python/python-sonar-runner/src/package/file_in_package.py b/projects/languages/python/python-sonar-runner/src/package/file_in_package.py
new file mode 100644
index 00000000..fc7f2ba0
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner/src/package/file_in_package.py
@@ -0,0 +1 @@
+dictionary = {}
diff --git a/projects/languages/python/python-sonar-runner/src/samples/__init__.py b/projects/languages/python/python-sonar-runner/src/samples/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/projects/languages/python/python-sonar-runner/src/samples/fortune.py b/projects/languages/python/python-sonar-runner/src/samples/fortune.py
new file mode 100644
index 00000000..b0900dc1
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner/src/samples/fortune.py
@@ -0,0 +1,92 @@
+
+# fortune.py -- chooses a random fortune, as the fortune(8) program in
+# the BSD-games package does
+#
+# Copyright (c) 2010, Andrew M. Kuchling
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import struct, random, string
+
+# C long variables are different sizes on 32-bit and 64-bit machines,
+# so we have to measure how big they are on the machine where this is running.
+LONG_SIZE = struct.calcsize('L')
+is_64_bit = (LONG_SIZE == 8)
+
+def get(filename):
+ "Select a random quotation, using a pregenerated .dat file"
+
+ # First, we open the .dat file, and read the header information.
+ # The C structure containing this info looks like:
+ ## typedef struct { /* information table */
+ ## #define VERSION 1
+ ## unsigned long str_version; /* version number */
+ ## unsigned long str_numstr; /* # of strings in the file */
+ ## unsigned long str_longlen; /* length of longest string */
+ ## unsigned long str_shortlen; /* length of shortest string */
+ ## #define STR_RANDOM 0x1 /* randomized pointers */
+ ## #define STR_ORDERED 0x2 /* ordered pointers */
+ ## #define STR_ROTATED 0x4 /* rot-13'd text */
+ ## unsigned long str_flags; /* bit field for flags */
+ ## unsigned char stuff[4]; /* long aligned space */
+ ## #define str_delim stuff[0] /* delimiting character */
+ ## } STRFILE;
+
+ datfile = open(filename+'.dat', 'r')
+ data = datfile.read(5 * LONG_SIZE)
+ if is_64_bit:
+ v1, v2, n1, n2, l1, l2, s1, s2, f1, f2 = struct.unpack('!10L', data)
+ version = v1 + (v2 << 32)
+ numstr = n1 + (n2 << 32)
+ longlen = l1 + (l2 << 32)
+ shortlen = s1 + (s2 << 32)
+ flags = f1 + (f2 << 32)
+ else:
+ version, numstr, longlen, shortlen, flags = struct.unpack('5l', data)
+
+ delimiter = datfile.read(1)
+ datfile.read(3) # Throw away padding bytes
+ if is_64_bit: datfile.read(4) # 64-bit machines align to 8 bytes
+
+ # Pick a random number
+ r = random.randint(0, numstr)
+ datfile.seek(LONG_SIZE * r, 1) # Seek to the chosen pointer
+ data = datfile.read(LONG_SIZE * 2)
+
+ if is_64_bit:
+ s1, s2, e1, e2 = struct.unpack('!4L', data)
+ start, end = s1 + (s2 << 32), e1 + (e2 << 32)
+ else:
+ start, end = struct.unpack('!ll', data)
+ datfile.close()
+
+ file = open(filename, 'r')
+ file.seek(start)
+ quotation = file.read(end-start)
+ L=string.split(quotation, '\n')
+ while string.strip(L[-1]) == delimiter or string.strip(L[-1]) == "":
+ L=L[:-1]
+ return string.join(L, '\n')
+
+if __name__ == '__main__':
+ import sys
+ if len(sys.argv) == 1:
+ print 'Usage: fortune.py '
+ sys.exit()
+ print get(sys.argv[1])
diff --git a/projects/languages/python/python-sonar-runner/src/samples/letters.py b/projects/languages/python/python-sonar-runner/src/samples/letters.py
new file mode 100644
index 00000000..0f54b31c
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner/src/samples/letters.py
@@ -0,0 +1,203 @@
+
+#
+# Copyright (c) 2010, Andrew M. Kuchling
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import random, string
+
+# Logic game
+# From a program by Judith Haris, John Swets, and Wallace Feurzeig
+# Reference: The Secret Guide to Computers, by Russ Walter, 18th ed 1993.
+# Written in Python by A.M. Kuchling (amk@amk.ca)
+
+# For each letter, we need the various characteristics:
+# (curves, loose ends, obliques, horizontals, verticals).
+# There should really be a sample character set for the user to look
+# at; otherwise, there are ambiguities. For example, does B have
+# horizontals? Does D? How about P and R?
+
+# There's a bug lurking in this data! Can you catch it?
+# (See the bottom of the program for the answer.)
+
+letter_stats={'a': (0, 2, 2, 1, 0), 'b':(2, 0, 0, 3, 1),
+ 'c': (1, 2, 0, 0, 0), 'd':(1, 0, 0, 0, 1),
+ 'e': (0, 3, 0, 3, 1), 'f':(0, 3, 0, 2, 1),
+ 'g': (1, 2, 0, 1, 1), 'h':(0, 4, 0, 1, 2),
+ 'i': (0, 2, 0, 0, 1), 'j':(1, 2, 0, 0, 1),
+ 'k': (0, 4, 2, 0, 1), 'l':(0, 2, 0, 1, 1),
+ 'm': (0, 2, 2, 0, 2), 'n':(0, 2, 1, 0, 2),
+ 'o': (1, 0, 0, 0, 0), 'p':(1, 1, 0, 2, 1),
+ 'q': (1, 2, 1, 0, 0), 'r':(1, 2, 1, 0, 1),
+ 's': (1, 2, 0, 0, 0), 't':(0, 3, 0, 1, 1),
+ 'u': (1, 2, 0, 0, 2), 'v':(0, 2, 2, 0, 0),
+ 'w': (0, 2, 4, 0, 0), 'x':(0, 4, 2, 0, 0),
+ 'y': (0, 3, 2, 0, 1), 'z':(0, 2, 1, 2, 0)}
+
+# We'll define constants for the various statistics; each constant is
+# equal to the position of the statistic in the tuples in
+#letter_stats.
+CURVES=0 ; LOOSE_ENDS=1 ; OBLIQUES=2 ; HORIZONTALS=3 ; VERTICALS=4
+
+# This dictionary is used to map questions to corresponding
+# statistics. Note that different keys can map to the same value;
+# for example, 'obliques' and 'diagonals' both map to the OBLIQUES constant.
+questions={'curves':CURVES, 'looseends':LOOSE_ENDS,
+ 'obliques':OBLIQUES, 'diagonals':OBLIQUES,
+ 'horizontals':HORIZONTALS, 'verticals':VERTICALS}
+
+# Play a single game
+
+def play_once():
+ # Choose a random number between 0 and 26, inclusive.
+ choice=26*random.random()
+ # Convert the numeric choice to a letter: 0->a, 1->b, etc.
+ choice=chr(ord('a')+choice)
+
+ #choice=raw_input("What should I choose?") # (for debugging)
+
+ # We'll track how many possibilities the user still has available.
+ # Start with all of the letters.
+ possibilities=string.lower("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+ # We'll also track which questions have been asked, and chide the
+ # user when he repeats a question.
+ asked=[]
+
+ # Loop forever; the play_once() function will exit by hitting a
+ # 'return' statement inside the loop.
+ while (1):
+ try:
+ #print possibilities # (for debugging)
+
+ # Get input from the user
+ query=raw_input('Next? ')
+ # Convert the input to lowercase
+ query=string.lower(query)
+ # Remove all non-letter characters
+ query=filter(lambda x: x in string.lowercase, query)
+ # Remove whitespace
+ query=string.strip(query)
+
+ except (EOFError, KeyboardInterrupt):
+ # End-Of-File : the user
+ print '\nOK; give up if you like.'
+ return
+
+ if len(query)==1:
+ # The query is one character long, so it's a guess
+ if query not in possibilities:
+ print ("Wrong! That guess is inconsistent "
+ "with the information you've been given.\n"
+ "I think you made that guess just to see "
+ "what I would say.")
+ elif len(possibilities)>1:
+ print "You don't have enough information yet."
+ # Temporarily remove the user's guess from
+ # possibilities, and pick a random letter.
+ temp=filter(lambda x, query=query: x!=query, possibilities)
+ r=int(random.random()*len(temp))
+ print "How do you know it isn't", temp[r]+',',
+ print "for example?"
+ else:
+ # query is in possibilities, and
+ # len(possibilities)==1, so the user is right.
+ print "Yes, you've done it. Good work!" ; return
+ elif questions.has_key(query):
+ # Get the field of the letter_stats tuple to compare.
+ field=questions[query]
+ # Determine the answer for the computer's letter
+ result=letter_stats[choice][field]
+ original_length=len(possibilities)
+
+ # Exclude possibilities that don't match those of the
+ # mystery letter.
+ # filter(func, sequence) calls func() on each element in
+ # the sequence, and returns a new sequence object
+ # containing only elements for which func() returned true.
+ # For strings, each character is an element. Instead of
+ # defining a formal function, a lambda is used to create
+ # an anonymous function (one without a name).
+ # Various other things required by the function are set
+ # as default arguments, so they're accessible inside the
+ # scope of the anonymous function.
+ possibilities=filter(lambda letter, letter_stats=letter_stats,
+ field=field, result=result:
+ letter_stats[letter][field]==result,
+ possibilities)
+ new_length=len(possibilities)
+ if field in asked:
+ print "You asked me that already."
+ print "The answer is the same as before:",
+ else: asked.append(field) # Note that this question was asked.
+ print str(result)+'.'
+ if (original_length==new_length):
+ print 'That was a wasted question; it did not exclude any possibilities.'
+ elif (new_length")
+
+# The solution to the bug-hunt is below...
+
+
+
+
+
+
+
+
+
+
+
+# It's not a bug that the Python interpreter can catch; instead, it's
+# a specification bug:
+#
+# 'C' and 'S' both have the same stats: 1 curve, 2 loose ends,
+# and no obliques, horizontals, or verticals. If either C or S is
+# chosen as the computer's letter, the user can never get the right
+# answer, because he/she can't narrow down the possibilities to just
+# one! To fix this, you'd have to add another statistic, like
+# number of intersections or number of closed loops. However, the
+# statistic would have to be *different* for 'C' and 'S', and neither
+# of those two suggestions qualify. Can you think of a property to
+# distinguish between the two letters?
diff --git a/projects/languages/python/python-sonar-runner/src/samples/strfile.py b/projects/languages/python/python-sonar-runner/src/samples/strfile.py
new file mode 100644
index 00000000..ca15a607
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner/src/samples/strfile.py
@@ -0,0 +1,100 @@
+
+# strfile.py -- write an index file for a fortune file, as the strfile(8)
+# program in the BSD-games package does
+#
+# Copyright (c) 2010, Andrew M. Kuchling
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import struct, string, sys
+
+if len(sys.argv)==1:
+ print "Usage: strfile.py "
+ sys.exit()
+
+# C long variables are different sizes on 32-bit and 64-bit machines,
+# so we have to measure how big they are on the machine where this is running.
+LONG_SIZE = struct.calcsize('L')
+is_64_bit = (LONG_SIZE == 8)
+
+delimiter = '%' # The standard delimiter
+
+filename = sys.argv[1]
+input = open(filename, 'r')
+output = open(filename + '.dat', 'w')
+output.seek(LONG_SIZE * 6) # Skip over the header for now
+
+# Output a 32- or 64-bit integer
+
+def write_long(x):
+ if is_64_bit:
+ output.write( struct.pack("!LL", x & 0xffffFFFFL, x >> 32) )
+ else:
+ output.write( struct.pack("!L", x) )
+
+write_long(0) # Write the first pointer
+
+# We need to track various statistics: the longest and shortest
+# quotations, and their number
+
+shortest = sys.maxint ; longest = 0
+numstr = 0
+quotation = ""
+
+while (1):
+ L=input.readline() # Get a line
+ if L=="": break # Check for end-of-file
+ if string.strip(L) != delimiter:
+ # We haven't come to the end yet, so we just add the line to
+ # the quotation we're building and continue
+ quotation = quotation + L ; continue
+
+ # If there's a leading % in the file, the first quotation will be
+ # empty; we'll just ignore it
+ if quotation == "": continue
+
+ # Update the shortest and longest variables
+ shortest = min(shortest, len(quotation) )
+ longest = max(longest, len(quotation) )
+
+ # Output the current file pointer
+ write_long( input.tell() )
+ numstr = numstr + 1
+ quotation = "" # Reset the quotation to null
+
+# To simplify the programming, we'll assume there's a trailing % line
+# in the file, with no quotation following.
+assert quotation == ""
+
+input.close()
+
+# We're done, so rewind to the beginning of the file and write the header
+output.seek(0)
+write_long( 1 ) # Version
+write_long(numstr) # Number of strings
+write_long(longest) # Longest string length
+write_long(shortest) # Shortest string length
+write_long(0) # Flags; we'll set them to zero
+output.write(delimiter + '\0'*(LONG_SIZE-1))
+output.close()
+
+print '''"%s.dat" created
+There were %i strings
+Longest string: %i bytes
+Shortest string: %i bytes''' % (filename, numstr, longest, shortest)
diff --git a/projects/languages/python/python-sonar-runner/validation.txt b/projects/languages/python/python-sonar-runner/validation.txt
new file mode 100644
index 00000000..fcd7e336
--- /dev/null
+++ b/projects/languages/python/python-sonar-runner/validation.txt
@@ -0,0 +1,11 @@
+start server
+ with plugin python 1.5
+sonar-runner
+verify org.sonarqube:python-simple-sonar-scanner
+ measure lines is 498
+ measure ncloc is 215
+ measure files is 9
+verify org.sonarqube:python-simple-sonar-scanner:src/badfortune.py
+ measure lines is 93
+ measure ncloc is 41
+stop server
diff --git a/projects/languages/rpg/README.md b/projects/languages/rpg/README.md
new file mode 100644
index 00000000..d27e4898
--- /dev/null
+++ b/projects/languages/rpg/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze an RPG project with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarSource RPG Plugin](http://www.sonarsource.com/products/plugins/languages/rpg/) 1.4.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/rpg/sonar-project.properties b/projects/languages/rpg/sonar-project.properties
new file mode 100644
index 00000000..0f2212ed
--- /dev/null
+++ b/projects/languages/rpg/sonar-project.properties
@@ -0,0 +1,8 @@
+sonar.projectKey=org.sonarqube:rpg-sq-scanner
+sonar.projectName=RPG :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.sources=src
+sonar.language=rpg
+
+sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/projects/languages/rpg/src/MYPROGRAM.rpg b/projects/languages/rpg/src/MYPROGRAM.rpg
new file mode 100644
index 00000000..b7d36daa
--- /dev/null
+++ b/projects/languages/rpg/src/MYPROGRAM.rpg
@@ -0,0 +1,53 @@
+123456789012 C* Expressions in Extended Factor 2 syntax
+123456789012 C IF A=X OR A=Y AND A=Z
+123456789012 C AND B=Y
+123456789012 C READ Y
+123456789012 C ENDIF
+123456789012 C IF A=X OR A=Y AND A=Z
+123456789012 C AND B=Y OR B=Z
+123456789012 C READ Y
+123456789012 C ENDIF
+123456789012 C* Expressions composed over several operations in IF
+123456789012 C A IFEQ X
+123456789012 C A OREQ Y
+123456789012 C A ANDEQ Z
+123456789012 C B ANDEQ Y
+123456789012 C READ Y
+123456789012 C ENDIF
+123456789012 C A IFEQ X
+123456789012 C A OREQ Y
+123456789012 C A ANDEQ Z
+123456789012 C B ANDEQ Y
+123456789012 C B OREQ Z
+123456789012 C READ Y
+123456789012 C ENDIF
+123456789012 C* Expressions composed over several operations in DO
+123456789012 C A DOUEQ X
+123456789012 C A OREQ Y
+123456789012 C A ANDEQ Z
+123456789012 C B ANDEQ Y
+123456789012 C READ Y
+123456789012 C END
+123456789012 C A DOUEQ X
+123456789012 C A OREQ Y
+123456789012 C A ANDEQ Z
+123456789012 C B ANDEQ Y
+123456789012 C B OREQ Z
+123456789012 C READ Y
+123456789012 C END
+123456789012 C* Expressions composed over several operations in WHEN
+123456789012 C SELECT
+123456789012 C A WHENEQ X
+123456789012 C A OREQ Y
+123456789012 C A ANDEQ Z
+123456789012 C B ANDEQ Y
+123456789012 C READ Y
+123456789012 C END
+123456789012 C SELECT
+123456789012 C A WHENEQ X
+123456789012 C A OREQ Y
+123456789012 C A ANDEQ Z
+123456789012 C B ANDEQ Y
+123456789012 C B OREQ Z
+123456789012 C READ Y
+123456789012 C END
\ No newline at end of file
diff --git a/projects/languages/rpg/validation.txt b/projects/languages/rpg/validation.txt
new file mode 100644
index 00000000..b316550d
--- /dev/null
+++ b/projects/languages/rpg/validation.txt
@@ -0,0 +1,11 @@
+start server
+ with plugin rpg 1.4.1
+sonar-runner
+verify org.sonarqube:rpg-sq-scanner
+ measure lines is 53
+ measure ncloc is 49
+ measure files is 1
+verify org.sonarqube:rpg-sq-scanner:src/MYPROGRAM.rpg
+ measure lines is 53
+ measure ncloc is 49
+stop server
diff --git a/projects/languages/sonar-project.properties b/projects/languages/sonar-project.properties
new file mode 100644
index 00000000..d92d181a
--- /dev/null
+++ b/projects/languages/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:it-sonar-examples
+sonar.projectName=IT Sonar Examples Quality
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=.
+
+# Language
+sonar.language=text
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/projects/languages/swift/swift-sonar-runner/README.md b/projects/languages/swift/swift-sonar-runner/README.md
new file mode 100644
index 00000000..97d12f0e
--- /dev/null
+++ b/projects/languages/swift/swift-sonar-runner/README.md
@@ -0,0 +1,12 @@
+This example demonstrates how to analyze a simple Swift project with the Sonar Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/swift/swift-sonar-runner/sonar-project.properties b/projects/languages/swift/swift-sonar-runner/sonar-project.properties
new file mode 100755
index 00000000..a39df615
--- /dev/null
+++ b/projects/languages/swift/swift-sonar-runner/sonar-project.properties
@@ -0,0 +1,5 @@
+sonar.projectKey=org.sonarqube:swift-simple-sq-scanner
+sonar.projectName=Swift :: Simple Project :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+sonar.sources=src
diff --git a/projects/languages/swift/swift-sonar-runner/src/example.swift b/projects/languages/swift/swift-sonar-runner/src/example.swift
new file mode 100644
index 00000000..194455d6
--- /dev/null
+++ b/projects/languages/swift/swift-sonar-runner/src/example.swift
@@ -0,0 +1,10 @@
+
+let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
+
+func backwards(s1: String, s2: String) -> Bool {
+ return s1 > s2
+}
+
+var reversed = sorted(names, backwards);
+
+if (true) { print(reversed) }
diff --git a/projects/languages/swift/swift-sonar-runner/validation.txt b/projects/languages/swift/swift-sonar-runner/validation.txt
new file mode 100644
index 00000000..a80b0eb5
--- /dev/null
+++ b/projects/languages/swift/swift-sonar-runner/validation.txt
@@ -0,0 +1,11 @@
+start server
+ with plugin swift 1.5
+sonar-runner
+verify org.sonarqube:swift-simple-sq-scanner
+ measure lines is 11
+ measure ncloc is 6
+ measure files is 1
+verify org.sonarqube:swift-simple-sq-scanner:src/example.swift
+ measure lines is 11
+ measure ncloc is 6
+stop server
diff --git a/projects/languages/vb6/README.md b/projects/languages/vb6/README.md
new file mode 100644
index 00000000..0e81957b
--- /dev/null
+++ b/projects/languages/vb6/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a VB6 project with the Sonar Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarSource VB6 Plugin](http://www.sonarsource.com/products/plugins/languages/visual-basic-6/) 2.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/vb6/sonar-project.properties b/projects/languages/vb6/sonar-project.properties
new file mode 100644
index 00000000..00ec016b
--- /dev/null
+++ b/projects/languages/vb6/sonar-project.properties
@@ -0,0 +1,16 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:vb-simple-sq-scanner
+sonar.projectName=VB6 :: Simple Project :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Description of project (optional)
+sonar.projectDescription=Simple Visual Basic 6 project analyzed using the SonarQube Runner
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=vb
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
diff --git a/projects/languages/vb6/src/Info.frm b/projects/languages/vb6/src/Info.frm
new file mode 100644
index 00000000..d762b1c4
--- /dev/null
+++ b/projects/languages/vb6/src/Info.frm
@@ -0,0 +1,67 @@
+VERSION 5.00
+Begin VB.Form frmInfo
+ BorderStyle = 3 'Fixed Dialog
+ Caption = "Info"
+ ClientHeight = 3750
+ ClientLeft = 45
+ ClientTop = 330
+ ClientWidth = 6270
+ Icon = "Info.frx":0000
+ LinkTopic = "Form1"
+ MaxButton = 0 'False
+ MinButton = 0 'False
+ ScaleHeight = 3750
+ ScaleWidth = 6270
+ ShowInTaskbar = 0 'False
+ StartUpPosition = 1 'CenterOwner
+ Begin VB.CommandButton cmdOK
+ Caption = "&OK"
+ Default = -1 'True
+ Height = 375
+ Left = 5100
+ TabIndex = 1
+ Top = 3300
+ Width = 1095
+ End
+ Begin VB.TextBox txtGPL
+ BackColor = &H8000000F&
+ BorderStyle = 0 'None
+ Height = 3075
+ Left = 120
+ Locked = -1 'True
+ MultiLine = -1 'True
+ TabIndex = 0
+ Text = "Info.frx":000C
+ Top = 120
+ Width = 6015
+ End
+End
+Attribute VB_Name = "frmInfo"
+Attribute VB_GlobalNameSpace = False
+Attribute VB_Creatable = False
+Attribute VB_PredeclaredId = True
+Attribute VB_Exposed = False
+' --- GPL ---
+'
+' Copyright (C) 1999 SAP AG
+'
+' 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 2
+' 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, write to the Free Software
+' Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+'
+' --- GPL ---
+Option Explicit
+
+Private Sub cmdOK_Click()
+ Unload Me
+End Sub
diff --git a/projects/languages/vb6/src/Registry.bas b/projects/languages/vb6/src/Registry.bas
new file mode 100644
index 00000000..17c2cb1a
--- /dev/null
+++ b/projects/languages/vb6/src/Registry.bas
@@ -0,0 +1,166 @@
+Attribute VB_Name = "modRegistry"
+' --- GPL ---
+'
+' Copyright (C) 1999 SAP AG
+'
+' 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 2
+' 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, write to the Free Software
+' Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+'
+' --- GPL ---
+Option Explicit
+
+'Structures Needed For Registry Prototypes
+Public Type SECURITY_ATTRIBUTES
+ nLength As Long
+ lpSecurityDescriptor As Long
+ bInheritHandle As Boolean
+End Type
+
+Public Type FILETIME
+ dwLowDateTime As Long
+ dwHighDateTime As Long
+End Type
+
+'Registry Function Prototypes
+Public Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" ( _
+ ByVal hKey As Long, _
+ ByVal lpSubKey As String, _
+ ByVal ulOptions As Long, _
+ ByVal samDesired As Long, _
+ phkResult As Long) As Long
+
+Public Declare Function RegCreateKeyEx Lib "advapi32" Alias "RegCreateKeyExA" ( _
+ ByVal hKey As Long, _
+ ByVal lpSubKey As String, _
+ ByVal Reserved As Long, _
+ ByVal lpClass As String, _
+ ByVal dwOptions As Long, _
+ ByVal samDesired As Long, _
+ lpSecurityAttributes As SECURITY_ATTRIBUTES, _
+ phkResult As Long, _
+ lpdwDisposition As Long) As Long
+
+Public Declare Function RegQueryValueExNull Lib "advapi32.dll" Alias "RegQueryValueExA" ( _
+ ByVal hKey As Long, _
+ ByVal lpValueName As String, _
+ ByVal lpReserved As Long, _
+ lpType As Long, _
+ ByVal lpData As Long, _
+ lpcbData As Long) As Long
+
+Public Declare Function RegQueryValueExString Lib "advapi32.dll" Alias "RegQueryValueExA" ( _
+ ByVal hKey As Long, _
+ ByVal lpValueName As String, _
+ ByVal lpReserved As Long, _
+ lpType As Long, _
+ ByVal lpData As String, _
+ lpcbData As Long) As Long
+
+Public Declare Function RegQueryValueExLong Lib "advapi32.dll" Alias "RegQueryValueExA" ( _
+ ByVal hKey As Long, _
+ ByVal lpValueName As String, _
+ ByVal lpReserved As Long, _
+ lpType As Long, _
+ lpData As Long, _
+ lpcbData As Long) As Long
+
+Public Declare Function RegSetValueExString Lib "advapi32.dll" Alias "RegSetValueExA" ( _
+ ByVal hKey As Long, _
+ ByVal lpValueName As String, _
+ ByVal Reserved As Long, _
+ ByVal dwType As Long, _
+ ByVal lpValue As String, _
+ ByVal cbData As Long) As Long
+
+Public Declare Function RegSetValueExLong Lib "advapi32.dll" Alias "RegSetValueExA" ( _
+ ByVal hKey As Long, _
+ ByVal lpValueName As String, _
+ ByVal Reserved As Long, _
+ ByVal dwType As Long, _
+ lpValue As Long, _
+ ByVal cbData As Long) As Long
+
+Public Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" ( _
+ ByVal hKey As Long, _
+ ByVal dwIndex As Long, _
+ ByVal lpName As String, _
+ lpcbName As Long, _
+ ByVal lpReserved As Long, _
+ ByVal lpClass As String, _
+ lpcbClass As Long, _
+ lpftLastWriteTime As FILETIME) As Long
+
+Public Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" ( _
+ ByVal hKey As Long, _
+ ByVal dwIndex As Long, _
+ ByVal lpValueName As String, _
+ lpcbValueName As Long, _
+ ByVal lpReserved As Long, _
+ lpType As Long, _
+ lpData As Any, _
+ lpcbData As Long) As Long
+
+Public Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" ( _
+ ByVal hKey As Long, _
+ ByVal lpSubKey As String) As Long
+
+Public Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" ( _
+ ByVal hKey As Long, _
+ ByVal lpValueName As String) As Long
+
+Public Declare Function RegCloseKey Lib "advapi32" ( _
+ ByVal hKey As Long) As Long
+
+'
+''masks for the predefined standard access types
+'Private Const STANDARD_RIGHTS_ALL = &H1F0000
+'Private Const SPECIFIC_RIGHTS_ALL = &HFFFF
+'
+''Define severity codes
+'
+''Public Const ERROR_ACCESS_DENIED = 5
+''
+''Global Const ERROR_NONE = 0
+''Global Const ERROR_BADDB = 1
+''Global Const ERROR_CANTOPEN = 3
+''Global Const ERROR_CANTREAD = 4
+''Global Const ERROR_CANTWRITE = 5
+''Global Const ERROR_OUTOFMEMORY = 6
+''Global Const ERROR_INVALID_PARAMETER = 7
+''Global Const ERROR_ACCESS_DENIED = 8
+''Global Const ERROR_INVALID_PARAMETERS = 87
+''Global Const ERROR_NO_MORE_ITEMS = 259
+
+Public Type ByteValue
+ b(1024) As Byte
+End Type
+
+Public Type LongValue
+ l As Long
+End Type
+
+Public Function BytesToString(bValue As ByteValue) As String
+ Dim s As String
+ Dim i As Integer
+ s = StrConv(bValue.b(), vbUnicode)
+ i = InStr(s, Chr(0)) - 1
+ BytesToString = Left(s, i)
+End Function
+
+Public Function BytesToLong(bValue As ByteValue) As Long
+ Dim lValue As LongValue
+ LSet lValue = bValue
+ BytesToLong = lValue.l
+End Function
+
diff --git a/projects/languages/vb6/src/Registry.cls b/projects/languages/vb6/src/Registry.cls
new file mode 100644
index 00000000..f0321eeb
--- /dev/null
+++ b/projects/languages/vb6/src/Registry.cls
@@ -0,0 +1,428 @@
+VERSION 1.0 CLASS
+BEGIN
+ MultiUse = -1 'True
+ Persistable = 0 'NotPersistable
+ DataBindingBehavior = 0 'vbNone
+ DataSourceBehavior = 0 'vbNone
+ MTSTransactionMode = 0 'NotAnMTSObject
+END
+Attribute VB_Name = "Registry"
+Attribute VB_GlobalNameSpace = False
+Attribute VB_Creatable = True
+Attribute VB_PredeclaredId = False
+Attribute VB_Exposed = False
+' --- GPL ---
+'
+' Copyright (C) 1999 SAP AG
+'
+' 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 2
+' 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, write to the Free Software
+' Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+'
+' --- GPL ---
+Option Explicit
+
+Public Enum RegistryHKeyConstants
+ HKEY_CLASSES_ROOT = &H80000000
+ HKEY_CURRENT_USER = &H80000001
+ HKEY_LOCAL_MACHINE = &H80000002
+ HKEY_USERS = &H80000003
+ HKEY_PERFORMANCE_DATA = &H80000004
+ HKEY_CURRENT_CONFIG = &H80000005
+ HKEY_DYN_DATA = &H80000006
+End Enum
+
+Public Enum RegistryTypeConstants
+ REG_NONE = (0) 'No value type
+ REG_SZ = (1) 'Unicode nul terminated string
+' REG_EXPAND_SZ = (2) 'Unicode nul terminated string w/enviornment var
+' REG_BINARY = (3) 'Free form binary
+ REG_DWORD = (4) '32-bit number
+' REG_DWORD_LITTLE_ENDIAN = (4) '32-bit number (same as REG_DWORD)
+' REG_DWORD_BIG_ENDIAN = (5) '32-bit number
+' REG_LINK = (6) 'Symbolic Link (unicode)
+' REG_MULTI_SZ = (7) 'Multiple Unicode strings
+' REG_RESOURCE_LIST = (8) 'Resource list in the resource map
+' REG_FULL_RESOURCE_DESCRIPTOR = (9) 'Resource list in the hardware description
+' REG_RESOURCE_REQUIREMENTS_LIST = (10)
+End Enum
+
+Public Enum RegistryAccessConstants
+ KEY_QUERY_VALUE = &H1
+ KEY_SET_VALUE = &H2
+ KEY_CREATE_SUB_KEY = &H4
+ KEY_ENUMERATE_SUB_KEYS = &H8
+ KEY_NOTIFY = &H10
+ KEY_CREATE_LINK = &H20
+ KEY_ALL_ACCESS = &H3F
+End Enum
+
+Public Enum RegistryErrorConstants
+ ERROR_SUCCESS = 0
+ ERROR_BADKEY = 2
+ ERROR_OUTOFMEMORY = 6
+ ERROR_MORE_DATA = 234
+ ERROR_NO_MORE_ITEMS = 259
+End Enum
+
+Public Enum RegistryVolatileConstants
+ REG_OPTION_NON_VOLATILE = 0&
+ REG_OPTION_VOLATILE = &H1
+End Enum
+
+Public Enum RegistryDispositionConstants
+ REG_CREATED_NEW_KEY = &H1
+ REG_OPENED_EXISTING_KEY = &H2
+End Enum
+
+Private oKeys As Keys
+
+Private bShowErrors As Boolean
+Private bRaiseErrors As Boolean
+'
+' Public Properties
+'
+Public Property Get Keys() As Keys
+ If oKeys Is Nothing Then
+ Set oKeys = New Keys
+ With oKeys
+ Set .Registry = Me
+ Set .Parent = Me
+ .Root = True
+ End With
+ End If
+ Set Keys = oKeys
+End Property
+
+Public Property Get ShowErrors() As Boolean
+ ShowErrors = bShowErrors
+End Property
+Public Property Let ShowErrors(ByVal NewVal As Boolean)
+ bShowErrors = NewVal
+End Property
+
+Public Property Get RaiseErrors() As Boolean
+ RaiseErrors = bRaiseErrors
+End Property
+Public Property Let RaiseErrors(ByVal NewVal As Boolean)
+ bRaiseErrors = NewVal
+End Property
+'
+' Public Sub/Function
+'
+' Base Functions
+'
+Public Function OpenKey(ByVal hKey As RegistryHKeyConstants, _
+ ByVal Path As String, _
+ ByVal Access As RegistryAccessConstants, _
+ Key As Long) As Boolean
+
+ Dim lRC As Long
+
+ OpenKey = False
+
+ lRC = RegOpenKeyEx(hKey, Path, 0&, Access, Key)
+ If lRC = ERROR_SUCCESS Then
+ OpenKey = True
+ Else
+ HandleError lRC, Path
+ End If
+End Function
+
+Public Function CreateKey(ByVal hKey As RegistryHKeyConstants, _
+ ByVal Path As String, _
+ ByVal Volatile As RegistryVolatileConstants, _
+ ByVal Access As RegistryAccessConstants, _
+ Key As Long, _
+ Disposition As Long) As Boolean
+
+ Dim lRC As Long
+ Dim saKey As SECURITY_ATTRIBUTES
+
+ CreateKey = False
+
+ lRC = RegCreateKeyEx(hKey, Path, 0, "", Volatile, Access, saKey, Key, Disposition)
+ If lRC = ERROR_SUCCESS Then
+ CreateKey = True
+ Else
+ HandleError lRC, Path
+ End If
+End Function
+
+Public Function DeleteKey(ByVal hKey As RegistryHKeyConstants, _
+ ByVal Path As String) As Boolean
+
+ Dim lRC As Long
+
+ DeleteKey = False
+
+ lRC = RegDeleteKey(hKey, Path)
+ If lRC = ERROR_SUCCESS Then
+ DeleteKey = True
+ Else
+ HandleError lRC, Path
+ End If
+End Function
+
+Public Function CloseKey(ByVal Path, _
+ Key As Long) As Boolean
+
+ Dim lRC As Long
+
+ CloseKey = False
+
+ lRC = RegCloseKey(Key)
+ If lRC = ERROR_SUCCESS Then
+ Key = 0
+ CloseKey = True
+ Else
+ HandleError lRC, Path
+ End If
+End Function
+
+Public Function QueryValueNull(ByVal hKey As Long, _
+ ByVal Name As String, _
+ ValueType As RegistryTypeConstants, _
+ ValueLen As Long) As Boolean
+
+ Dim lRC As Long
+
+ QueryValueNull = False
+
+ lRC = RegQueryValueExNull(hKey, Name, 0&, ValueType, 0&, ValueLen)
+ If lRC = ERROR_SUCCESS Then
+ QueryValueNull = True
+ Else
+ HandleError lRC, Name
+ End If
+End Function
+
+Public Function QueryValueString(ByVal hKey As Long, _
+ ByVal Name As String, _
+ Value As String, _
+ ValueLen As Long) As Boolean
+
+ Dim lRC As Long
+
+ QueryValueString = False
+
+ Value = String(ValueLen, 0)
+
+ lRC = RegQueryValueExString(hKey, Name, 0&, REG_SZ, Value, ValueLen)
+ If lRC = ERROR_SUCCESS Then
+ Value = Left(Value, ValueLen - 1)
+ QueryValueString = True
+ Else
+ HandleError lRC, Name
+ End If
+End Function
+
+Public Function QueryValueLong(ByVal hKey As Long, _
+ ByVal Name As String, _
+ Value As Long) As Boolean
+
+ Dim lRC As Long
+ Dim lValueLen As Long
+
+ QueryValueLong = False
+
+ Value = 0
+
+ lRC = RegQueryValueExLong(hKey, Name, 0&, REG_DWORD, Value, 4)
+ If lRC = ERROR_SUCCESS Then
+ QueryValueLong = True
+ Else
+ HandleError lRC, Name
+ End If
+End Function
+
+Public Function SetValueString(ByVal hKey As Long, _
+ ByVal Name As String, _
+ ByVal Value As String) As Boolean
+
+ Dim lRC As Long
+
+ SetValueString = False
+
+ Value = Value & Chr(0)
+
+ lRC = RegSetValueExString(hKey, Name, 0&, REG_SZ, Value, Len(Value))
+ If lRC = ERROR_SUCCESS Then
+ SetValueString = True
+ Else
+ HandleError lRC, Name
+ End If
+End Function
+
+Public Function SetValueLong(ByVal hKey As Long, _
+ ByVal Name As String, _
+ ByVal Value As Long) As Boolean
+
+ Dim lRC As Long
+
+ SetValueLong = False
+
+ lRC = RegSetValueExLong(hKey, Name, 0&, REG_DWORD, Value, 4)
+ If lRC = ERROR_SUCCESS Then
+ SetValueLong = True
+ Else
+ HandleError lRC, Name
+ End If
+End Function
+
+Public Function DeleteValue(ByVal hKey As Long, _
+ ByVal Name As String) As Boolean
+
+ Dim lRC As Long
+
+ DeleteValue = False
+
+ lRC = RegDeleteValue(hKey, Name)
+ If lRC = ERROR_SUCCESS Then
+ DeleteValue = True
+ Else
+ HandleError lRC, Name
+ End If
+End Function
+'
+'
+'
+Public Function Check(ByVal WithSubKeys As Boolean, _
+ ByVal WithValues As Boolean) As Boolean
+
+ Dim oKey As Key
+
+ Check = False
+
+ For Each oKey In Keys
+ If Not oKey.Check(WithSubKeys, WithValues) Then
+ Exit Function
+ End If
+ Next
+
+ Check = True
+End Function
+
+Public Function Create(ByVal WithSubKeys As Boolean, _
+ ByVal WithValues As Boolean) As Boolean
+
+ Dim oKey As Key
+
+ Create = False
+
+ For Each oKey In Keys
+ If Not oKey.Create(WithSubKeys, WithValues) Then
+ Exit Function
+ End If
+ Next
+
+ Create = True
+End Function
+
+Public Function QueryValues(ByVal WithSubKeys As Boolean) As Boolean
+
+ Dim oKey As Key
+
+ QueryValues = False
+
+ For Each oKey In Keys
+ If Not oKey.QueryValues(WithSubKeys) Then
+ Exit Function
+ End If
+ Next
+
+ QueryValues = True
+End Function
+
+Public Function SetValues(ByVal WithSubKeys As Boolean) As Boolean
+
+ Dim oKey As Key
+
+ SetValues = False
+
+ For Each oKey In Keys
+ If Not oKey.SetValues(WithSubKeys) Then
+ Exit Function
+ End If
+ Next
+
+ SetValues = True
+End Function
+
+Public Function EnumKeys(ByVal WithSubKeys As Boolean, _
+ ByVal WithValues As Boolean) As Boolean
+
+ Dim oKey As Key
+
+ EnumKeys = False
+
+ For Each oKey In Keys
+ If Not oKey.EnumKeys(WithSubKeys, WithValues) Then
+ Exit Function
+ End If
+ Next
+
+ EnumKeys = True
+End Function
+
+Public Function FindKeyByPath(ByVal WithSubKeys As Boolean, _
+ ByVal FindPath As String) As Key
+ Dim oKey As Key
+
+ Set FindKeyByPath = Nothing
+
+ For Each oKey In Keys
+ If FindPath = oKey.Path Then
+ Set FindKeyByPath = oKey
+ Exit Function
+ End If
+ If WithSubKeys Then
+ Set FindKeyByPath = oKey.FindKeyByPath(WithSubKeys, FindPath)
+ End If
+ Next
+End Function
+
+Friend Sub HandleError(ByVal RC As Long, ByVal Text As String)
+ Dim sMsg As String
+
+ If bShowErrors Then
+ sMsg = "Error: " & ErrorText(RC) & ". " & Text
+ MsgBox sMsg, vbExclamation
+ End If
+End Sub
+'
+' Private Sub/Function
+'
+Private Sub Class_Initialize()
+ 'Debug.Print "INIT Registry"
+ Set oKeys = Nothing
+ bShowErrors = True
+ bRaiseErrors = False
+End Sub
+
+Private Sub Class_Terminate()
+ 'Debug.Print "TERM Registry"
+End Sub
+
+Private Function ErrorText(ByVal lRC As Long) As String
+ Dim s As String
+ Select Case lRC
+ Case ERROR_BADKEY: s = "Bad key"
+ Case ERROR_MORE_DATA: s = "More data"
+ Case ERROR_OUTOFMEMORY: s = "Out of memory"
+ Case ERROR_NO_MORE_ITEMS: s = "No more items"
+ Case Else: s = "RC=" & CStr(lRC)
+ End Select
+ ErrorText = s
+End Function
+
diff --git a/projects/languages/vb6/validation.txt b/projects/languages/vb6/validation.txt
new file mode 100644
index 00000000..cbf66174
--- /dev/null
+++ b/projects/languages/vb6/validation.txt
@@ -0,0 +1,8 @@
+start server
+ with plugin vb 2.1
+sonar-runner
+verify org.sonarqube:vb-simple-sq-scanner
+ measure lines is 664
+ measure ncloc is 453
+ measure files is 3
+stop server
diff --git a/projects/languages/vbnet/.gitignore b/projects/languages/vbnet/.gitignore
new file mode 100644
index 00000000..356bd15a
--- /dev/null
+++ b/projects/languages/vbnet/.gitignore
@@ -0,0 +1,20 @@
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+x64/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+
+# NuGet
+packages/
+
+# Roslyn
+*.sln.ide/
diff --git a/projects/languages/vbnet/ConsoleApplication1.sln b/projects/languages/vbnet/ConsoleApplication1.sln
new file mode 100644
index 00000000..6e530397
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.31101.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ConsoleApplication1", "ConsoleApplication1\ConsoleApplication1.vbproj", "{65E63AB4-1055-4104-B233-A9F7CF2233DA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {65E63AB4-1055-4104-B233-A9F7CF2233DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {65E63AB4-1055-4104-B233-A9F7CF2233DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {65E63AB4-1055-4104-B233-A9F7CF2233DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {65E63AB4-1055-4104-B233-A9F7CF2233DA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/projects/languages/vbnet/ConsoleApplication1/App.config b/projects/languages/vbnet/ConsoleApplication1/App.config
new file mode 100644
index 00000000..8e156463
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/languages/vbnet/ConsoleApplication1/ConsoleApplication1.vbproj b/projects/languages/vbnet/ConsoleApplication1/ConsoleApplication1.vbproj
new file mode 100644
index 00000000..669f7d88
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/ConsoleApplication1.vbproj
@@ -0,0 +1,114 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {65E63AB4-1055-4104-B233-A9F7CF2233DA}
+ Exe
+ ConsoleApplication1.Module1
+ ConsoleApplication1
+ ConsoleApplication1
+ 512
+ Console
+ v4.5
+
+
+ AnyCPU
+ true
+ full
+ true
+ true
+ bin\Debug\
+ ConsoleApplication1.xml
+ 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
+
+
+ AnyCPU
+ pdbonly
+ false
+ true
+ true
+ bin\Release\
+ ConsoleApplication1.xml
+ 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
+
+
+ On
+
+
+ Binary
+
+
+ Off
+
+
+ On
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ Application.myapp
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+ VbMyResourcesResXFileCodeGenerator
+ Resources.Designer.vb
+ My.Resources
+ Designer
+
+
+
+
+ MyApplicationCodeGenerator
+ Application.Designer.vb
+
+
+ SettingsSingleFileGenerator
+ My
+ Settings.Designer.vb
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/languages/vbnet/ConsoleApplication1/Module1.vb b/projects/languages/vbnet/ConsoleApplication1/Module1.vb
new file mode 100644
index 00000000..5d7e3a34
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/Module1.vb
@@ -0,0 +1,7 @@
+Module Module1
+
+ Sub Main()
+
+ End Sub
+
+End Module
diff --git a/projects/languages/vbnet/ConsoleApplication1/My Project/Application.Designer.vb b/projects/languages/vbnet/ConsoleApplication1/My Project/Application.Designer.vb
new file mode 100644
index 00000000..88dd01c7
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/My Project/Application.Designer.vb
@@ -0,0 +1,13 @@
+'------------------------------------------------------------------------------
+'
+' This code was generated by a tool.
+' Runtime Version:4.0.30319.42000
+'
+' Changes to this file may cause incorrect behavior and will be lost if
+' the code is regenerated.
+'
+'------------------------------------------------------------------------------
+
+Option Strict On
+Option Explicit On
+
diff --git a/projects/languages/vbnet/ConsoleApplication1/My Project/Application.myapp b/projects/languages/vbnet/ConsoleApplication1/My Project/Application.myapp
new file mode 100644
index 00000000..e62f1a53
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/My Project/Application.myapp
@@ -0,0 +1,10 @@
+
+
+ false
+ false
+ 0
+ true
+ 0
+ 2
+ true
+
diff --git a/projects/languages/vbnet/ConsoleApplication1/My Project/AssemblyInfo.vb b/projects/languages/vbnet/ConsoleApplication1/My Project/AssemblyInfo.vb
new file mode 100644
index 00000000..d1ad4666
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/My Project/AssemblyInfo.vb
@@ -0,0 +1,35 @@
+Imports System
+Imports System.Reflection
+Imports System.Runtime.InteropServices
+
+' General Information about an assembly is controlled through the following
+' set of attributes. Change these attribute values to modify the information
+' associated with an assembly.
+
+' Review the values of the assembly attributes
+
+
+
+
+
+
+
+
+
+
+'The following GUID is for the ID of the typelib if this project is exposed to COM
+
+
+' Version information for an assembly consists of the following four values:
+'
+' Major Version
+' Minor Version
+' Build Number
+' Revision
+'
+' You can specify all the values or you can default the Build and Revision Numbers
+' by using the '*' as shown below:
+'
+
+
+
diff --git a/projects/languages/vbnet/ConsoleApplication1/My Project/Resources.Designer.vb b/projects/languages/vbnet/ConsoleApplication1/My Project/Resources.Designer.vb
new file mode 100644
index 00000000..0f9ffbaa
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/My Project/Resources.Designer.vb
@@ -0,0 +1,62 @@
+'------------------------------------------------------------------------------
+'
+' This code was generated by a tool.
+' Runtime Version:4.0.30319.42000
+'
+' Changes to this file may cause incorrect behavior and will be lost if
+' the code is regenerated.
+'
+'------------------------------------------------------------------------------
+
+Option Strict On
+Option Explicit On
+
+
+Namespace My.Resources
+
+ 'This class was auto-generated by the StronglyTypedResourceBuilder
+ 'class via a tool like ResGen or Visual Studio.
+ 'To add or remove a member, edit your .ResX file then rerun ResGen
+ 'with the /str option, or rebuild your VS project.
+ '''
+ ''' A strongly-typed resource class, for looking up localized strings, etc.
+ '''
+ _
+ Friend Module Resources
+
+ Private resourceMan As Global.System.Resources.ResourceManager
+
+ Private resourceCulture As Global.System.Globalization.CultureInfo
+
+ '''
+ ''' Returns the cached ResourceManager instance used by this class.
+ '''
+ _
+ Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
+ Get
+ If Object.ReferenceEquals(resourceMan, Nothing) Then
+ Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("ConsoleApplication1.Resources", GetType(Resources).Assembly)
+ resourceMan = temp
+ End If
+ Return resourceMan
+ End Get
+ End Property
+
+ '''
+ ''' Overrides the current thread's CurrentUICulture property for all
+ ''' resource lookups using this strongly typed resource class.
+ '''
+ _
+ Friend Property Culture() As Global.System.Globalization.CultureInfo
+ Get
+ Return resourceCulture
+ End Get
+ Set(ByVal value As Global.System.Globalization.CultureInfo)
+ resourceCulture = value
+ End Set
+ End Property
+ End Module
+End Namespace
diff --git a/projects/languages/vbnet/ConsoleApplication1/My Project/Resources.resx b/projects/languages/vbnet/ConsoleApplication1/My Project/Resources.resx
new file mode 100644
index 00000000..af7dbebb
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/My Project/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/projects/languages/vbnet/ConsoleApplication1/My Project/Settings.Designer.vb b/projects/languages/vbnet/ConsoleApplication1/My Project/Settings.Designer.vb
new file mode 100644
index 00000000..d4f93818
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/My Project/Settings.Designer.vb
@@ -0,0 +1,73 @@
+'------------------------------------------------------------------------------
+'
+' This code was generated by a tool.
+' Runtime Version:4.0.30319.42000
+'
+' Changes to this file may cause incorrect behavior and will be lost if
+' the code is regenerated.
+'
+'------------------------------------------------------------------------------
+
+Option Strict On
+Option Explicit On
+
+
+Namespace My
+
+ _
+ Partial Friend NotInheritable Class MySettings
+ Inherits Global.System.Configuration.ApplicationSettingsBase
+
+ Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings)
+
+#Region "My.Settings Auto-Save Functionality"
+#If _MyType = "WindowsForms" Then
+ Private Shared addedHandler As Boolean
+
+ Private Shared addedHandlerLockObject As New Object
+
+ _
+ Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
+ If My.Application.SaveMySettingsOnExit Then
+ My.Settings.Save()
+ End If
+ End Sub
+#End If
+#End Region
+
+ Public Shared ReadOnly Property [Default]() As MySettings
+ Get
+
+#If _MyType = "WindowsForms" Then
+ If Not addedHandler Then
+ SyncLock addedHandlerLockObject
+ If Not addedHandler Then
+ AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
+ addedHandler = True
+ End If
+ End SyncLock
+ End If
+#End If
+ Return defaultInstance
+ End Get
+ End Property
+ End Class
+End Namespace
+
+Namespace My
+
+ _
+ Friend Module MySettingsProperty
+
+ _
+ Friend ReadOnly Property Settings() As Global.ConsoleApplication1.My.MySettings
+ Get
+ Return Global.ConsoleApplication1.My.MySettings.Default
+ End Get
+ End Property
+ End Module
+End Namespace
diff --git a/projects/languages/vbnet/ConsoleApplication1/My Project/Settings.settings b/projects/languages/vbnet/ConsoleApplication1/My Project/Settings.settings
new file mode 100644
index 00000000..85b890b3
--- /dev/null
+++ b/projects/languages/vbnet/ConsoleApplication1/My Project/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/projects/languages/vbnet/README.md b/projects/languages/vbnet/README.md
new file mode 100644
index 00000000..00d4b1ba
--- /dev/null
+++ b/projects/languages/vbnet/README.md
@@ -0,0 +1,3 @@
+# Analyze this project with SonarQube
+
+See http://docs.sonarqube.org/x/DgEW for details on how to analyze this project using the MSBuild SonarQube Runner.
diff --git a/projects/languages/web/web-sonar-runner/README.md b/projects/languages/web/web-sonar-runner/README.md
new file mode 100644
index 00000000..9f9b47f7
--- /dev/null
+++ b/projects/languages/web/web-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze Web projects with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube Web Plugin](http://docs.sonarqube.org/display/PLUG/Web+Plugin) 2.4+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/web/web-sonar-runner/sonar-project.properties b/projects/languages/web/web-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..2c423258
--- /dev/null
+++ b/projects/languages/web/web-sonar-runner/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:web-sq-scanner
+sonar.projectName=Web :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=web
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/projects/languages/web/web-sonar-runner/src/sample.xhtml b/projects/languages/web/web-sonar-runner/src/sample.xhtml
new file mode 100644
index 00000000..f9507854
--- /dev/null
+++ b/projects/languages/web/web-sonar-runner/src/sample.xhtml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+ User list
+
+
+
+
+
Apple
+
Strawberry
+
+
+
+
+
+
+ User
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/languages/web/web-sonar-runner/validation.txt b/projects/languages/web/web-sonar-runner/validation.txt
new file mode 100644
index 00000000..f4086fc8
--- /dev/null
+++ b/projects/languages/web/web-sonar-runner/validation.txt
@@ -0,0 +1,11 @@
+start server
+ with plugin web 2.4
+sonar-runner
+verify org.sonarqube:web-sq-scanner
+ measure lines is 51
+ measure ncloc is 37
+ measure files is 1
+verify org.sonarqube:web-sq-scanner:src/sample.xhtml
+ measure lines is 51
+ measure ncloc is 37
+stop server
diff --git a/projects/languages/xml/xml-sonar-runner-custom-schema/README.md b/projects/languages/xml/xml-sonar-runner-custom-schema/README.md
new file mode 100644
index 00000000..d2abcf18
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner-custom-schema/README.md
@@ -0,0 +1,21 @@
+This example demonstrates how to analyze an XML project with the SonarQube Scanner.
+File validation against a custom schema.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarsource.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SONAR/Analyzing+with+SonarQube+Scanner) 2.4+
+* [SonarQube XML Plugin](http://docs.sonarqube.org/display/PLUG/XML+Plugin) 1.4.1+
+
+Usage
+=====
+* Copy the 'XML Schema Check' rule:
+ * Name: Validation against custom schema
+ * Default Severity: Blocker
+ * filePattern: leave it empty
+ * schemas: schemas/shiporder.xsd
+ * Description: Validation against custom schema
+* Activate the 'Validation against custom schema' rule
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/xml/xml-sonar-runner-custom-schema/schemas/shiporder.xsd b/projects/languages/xml/xml-sonar-runner-custom-schema/schemas/shiporder.xsd
new file mode 100644
index 00000000..6d1c83ad
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner-custom-schema/schemas/shiporder.xsd
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/languages/xml/xml-sonar-runner-custom-schema/sonar-project.properties b/projects/languages/xml/xml-sonar-runner-custom-schema/sonar-project.properties
new file mode 100644
index 00000000..ccd98ca2
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner-custom-schema/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:xml-custom-schema-sq-scanner
+sonar.projectName=XML :: Custom Schema :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=xml
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/projects/languages/xml/xml-sonar-runner-custom-schema/src/shiporder1.xml b/projects/languages/xml/xml-sonar-runner-custom-schema/src/shiporder1.xml
new file mode 100644
index 00000000..12a007ca
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner-custom-schema/src/shiporder1.xml
@@ -0,0 +1,22 @@
+
+
+
+
+ John Smith
+ Main Street
+ New York
+ United States
+
+
+ Book1
+ 1
+ 10.90
+
+
+ Book2
+ 3
+ 20.00
+
+
\ No newline at end of file
diff --git a/projects/languages/xml/xml-sonar-runner-custom-schema/src/shiporder2.xml b/projects/languages/xml/xml-sonar-runner-custom-schema/src/shiporder2.xml
new file mode 100644
index 00000000..7a219ce5
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner-custom-schema/src/shiporder2.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ Jack
+ Second Street
+ New York
+ United States
+
+
+ Book1
+ 1
+ 10.90
+ blabla...
+
+
\ No newline at end of file
diff --git a/projects/languages/xml/xml-sonar-runner-custom-schema/validation.txt b/projects/languages/xml/xml-sonar-runner-custom-schema/validation.txt
new file mode 100644
index 00000000..18d3d553
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner-custom-schema/validation.txt
@@ -0,0 +1,14 @@
+start server
+ with plugin xml 1.4
+sonar-runner
+verify org.sonarqube:xml-custom-schema-sq-scanner
+ measure lines is 40
+ measure ncloc is 38
+ measure files is 2
+verify org.sonarqube:xml-custom-schema-sq-scanner:src/shiporder1.xml
+ measure lines is 22
+ measure ncloc is 21
+verify org.sonarqube:xml-custom-schema-sq-scanner:src/shiporder2.xml
+ measure lines is 18
+ measure ncloc is 17
+stop server
diff --git a/projects/languages/xml/xml-sonar-runner/README.md b/projects/languages/xml/xml-sonar-runner/README.md
new file mode 100644
index 00000000..597353ae
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze XML projects with the SonarQube Scanner.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+* [SonarQube XML Plugin](http://docs.sonarqube.org/display/PLUG/XML+Plugin) 1.4.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/languages/xml/xml-sonar-runner/sonar-project.properties b/projects/languages/xml/xml-sonar-runner/sonar-project.properties
new file mode 100644
index 00000000..8366771b
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner/sonar-project.properties
@@ -0,0 +1,13 @@
+# Required metadata
+sonar.projectKey=org.sonarqube:xml-sq-scanner
+sonar.projectName=XML :: SonarQube Scanner
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+
+# Language
+sonar.language=xml
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/projects/languages/xml/xml-sonar-runner/src/sonar_backup.xml b/projects/languages/xml/xml-sonar-runner/src/sonar_backup.xml
new file mode 100644
index 00000000..76e4dd45
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner/src/sonar_backup.xml
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/languages/xml/xml-sonar-runner/validation.txt b/projects/languages/xml/xml-sonar-runner/validation.txt
new file mode 100644
index 00000000..07a96790
--- /dev/null
+++ b/projects/languages/xml/xml-sonar-runner/validation.txt
@@ -0,0 +1,11 @@
+start server
+ with plugin xml 1.4
+sonar-runner
+verify org.sonarqube:xml-sq-scanner
+ measure lines is 233
+ measure ncloc is 233
+ measure files is 1
+verify org.sonarqube:xml-sq-scanner:src/sonar_backup.xml
+ measure lines is 233
+ measure ncloc is 233
+stop server
diff --git a/projects/multi-module/ant/README.md b/projects/multi-module/ant/README.md
new file mode 100644
index 00000000..6d0acc76
--- /dev/null
+++ b/projects/multi-module/ant/README.md
@@ -0,0 +1,4 @@
+The best way to understand how the SonarQube Ant Task 2.0+ works is to give a try to the examples following this order:
+* /projects/languages/java/ant/java-ant-simple
+* java-ant-modules-same-structure
+* java-ant-modules-different-structures
\ No newline at end of file
diff --git a/projects/multi-module/ant/java-ant-modules-different-structures/Module 1/build.xml b/projects/multi-module/ant/java-ant-modules-different-structures/Module 1/build.xml
new file mode 100644
index 00000000..7b8b399a
--- /dev/null
+++ b/projects/multi-module/ant/java-ant-modules-different-structures/Module 1/build.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/ant-modules/module-one/src/java/One.java b/projects/multi-module/ant/java-ant-modules-different-structures/Module 1/sources/java/One.java
similarity index 100%
rename from projects/ant-modules/module-one/src/java/One.java
rename to projects/multi-module/ant/java-ant-modules-different-structures/Module 1/sources/java/One.java
diff --git a/projects/multi-module/ant/java-ant-modules-different-structures/README.md b/projects/multi-module/ant/java-ant-modules-different-structures/README.md
new file mode 100644
index 00000000..37e0a1f8
--- /dev/null
+++ b/projects/multi-module/ant/java-ant-modules-different-structures/README.md
@@ -0,0 +1,16 @@
+This example demonstrates how to analyze a multi-module Java project with Ant.
+Modules have different structures.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarsource.org/downloads/) 4.5+
+* [SonarQube Scanner for Ant](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Ant) 2.4.1+
+* [Ant](http://ant.apache.org/) 1.7.1 or higher
+
+Usage
+=====
+* Set the path to the SonarQube Ant Task in the build.xml file
+* Set the sonar.jdbc.* properties in the build.xml file
+* Run the following command:
+
+ ant all
diff --git a/projects/multi-module/ant/java-ant-modules-different-structures/build.xml b/projects/multi-module/ant/java-ant-modules-different-structures/build.xml
new file mode 100644
index 00000000..bf03347c
--- /dev/null
+++ b/projects/multi-module/ant/java-ant-modules-different-structures/build.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/ant-modules/module-two/build.xml b/projects/multi-module/ant/java-ant-modules-different-structures/module-two/build.xml
similarity index 53%
rename from projects/ant-modules/module-two/build.xml
rename to projects/multi-module/ant/java-ant-modules-different-structures/module-two/build.xml
index 790eca04..86bdf84a 100644
--- a/projects/ant-modules/module-two/build.xml
+++ b/projects/multi-module/ant/java-ant-modules-different-structures/module-two/build.xml
@@ -1,27 +1,15 @@
-
-
- Module Two
-
-
-
-
-
-
+
+
-
+
-
@@ -31,11 +19,10 @@
-
+
-
+
diff --git a/projects/ant-modules/module-two/src/java/Two.java b/projects/multi-module/ant/java-ant-modules-different-structures/module-two/src/java/Two.java
similarity index 100%
rename from projects/ant-modules/module-two/src/java/Two.java
rename to projects/multi-module/ant/java-ant-modules-different-structures/module-two/src/java/Two.java
diff --git a/projects/multi-module/ant/java-ant-modules-same-structure/README.md b/projects/multi-module/ant/java-ant-modules-same-structure/README.md
new file mode 100644
index 00000000..85f42e13
--- /dev/null
+++ b/projects/multi-module/ant/java-ant-modules-same-structure/README.md
@@ -0,0 +1,16 @@
+This example demonstrates how to analyze a multi-module Java project with Ant.
+The structure is the same for every module.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarsource.org/downloads/) 4.5+
+* [SonarQube Scanner for Ant](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Ant) 2.4.1+
+* [Ant](http://ant.apache.org/) 1.7.1 or higher
+
+Usage
+=====
+* Set the path to the SonarQube Ant Task in the build.xml file
+* Set the sonar.jdbc.* properties in the build.xml file
+* Run the following command:
+
+ ant all
diff --git a/projects/multi-module/ant/java-ant-modules-same-structure/build.xml b/projects/multi-module/ant/java-ant-modules-same-structure/build.xml
new file mode 100644
index 00000000..5cb359e9
--- /dev/null
+++ b/projects/multi-module/ant/java-ant-modules-same-structure/build.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/ant-modules/module-one/build.xml b/projects/multi-module/ant/java-ant-modules-same-structure/module-one/build.xml
similarity index 53%
rename from projects/ant-modules/module-one/build.xml
rename to projects/multi-module/ant/java-ant-modules-same-structure/module-one/build.xml
index f335acf3..f8c66c53 100644
--- a/projects/ant-modules/module-one/build.xml
+++ b/projects/multi-module/ant/java-ant-modules-same-structure/module-one/build.xml
@@ -1,28 +1,15 @@
-
-
- Module One
-
-
-
-
-
-
-
+
+
-
+
-
@@ -32,11 +19,10 @@
-
+
-
+
diff --git a/projects/gradle-modules/module-one/src/main/java/One.java b/projects/multi-module/ant/java-ant-modules-same-structure/module-one/src/java/One.java
similarity index 100%
rename from projects/gradle-modules/module-one/src/main/java/One.java
rename to projects/multi-module/ant/java-ant-modules-same-structure/module-one/src/java/One.java
diff --git a/projects/multi-module/ant/java-ant-modules-same-structure/module-two/build.xml b/projects/multi-module/ant/java-ant-modules-same-structure/module-two/build.xml
new file mode 100644
index 00000000..dff3e4e2
--- /dev/null
+++ b/projects/multi-module/ant/java-ant-modules-same-structure/module-two/build.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/gradle-modules/module-two/src/main/java/Two.java b/projects/multi-module/ant/java-ant-modules-same-structure/module-two/src/java/Two.java
similarity index 100%
rename from projects/gradle-modules/module-two/src/main/java/Two.java
rename to projects/multi-module/ant/java-ant-modules-same-structure/module-two/src/java/Two.java
diff --git a/projects/multi-module/gradle/README.md b/projects/multi-module/gradle/README.md
new file mode 100644
index 00000000..2a3b27c8
--- /dev/null
+++ b/projects/multi-module/gradle/README.md
@@ -0,0 +1 @@
+A simple gradle project (no modules) is available at ../../languages/java/gradle/java-gradle-simple
diff --git a/projects/multi-module/gradle/java-gradle-modules/README.md b/projects/multi-module/gradle/java-gradle-modules/README.md
new file mode 100644
index 00000000..a484590f
--- /dev/null
+++ b/projects/multi-module/gradle/java-gradle-modules/README.md
@@ -0,0 +1,12 @@
+This example demonstrates how to analyze a multi-module Java project with Gradle.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarsource.org/downloads/) 4.5+
+* [Gradle](http://www.gradle.org/) 1.12 or higher
+
+Usage
+=====
+* Analyze the project with SonarQube using Gradle:
+
+ gradle sonarqube [-Dsonar.host.url=... -Dsonar.jdbc.url=... -Dsonar.jdbc.username=... -Dsonar.jdbc.password=...]
diff --git a/projects/multi-module/gradle/java-gradle-modules/build.gradle b/projects/multi-module/gradle/java-gradle-modules/build.gradle
new file mode 100644
index 00000000..f2cad3a1
--- /dev/null
+++ b/projects/multi-module/gradle/java-gradle-modules/build.gradle
@@ -0,0 +1,36 @@
+apply plugin: 'java'
+apply plugin: 'org.sonarqube'
+
+allprojects {
+ ext.baseVersion = "0.1"
+ ext.snapshotVersion = true
+
+ group = "org.sonarqube"
+ version = "$baseVersion" + (snapshotVersion ? "-SNAPSHOT" : "")
+}
+
+sonarqube {
+ properties {
+ property "sonar.projectName", "Java :: MultiModules Project :: Gradle SonarQube Plugin"
+ property "sonar.projectKey", "org.sonarqube:java-gradle-multimodules"
+ }
+}
+
+subprojects {
+ apply plugin: 'java'
+}
+
+buildscript {
+ repositories {
+ maven {
+ url "http://repo1.maven.org/maven2/"
+ }
+ maven {
+ url "https://plugins.gradle.org/m2/"
+ }
+ mavenLocal()
+ }
+ dependencies {
+ classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:1.2'
+ }
+}
diff --git a/projects/multi-module/gradle/java-gradle-modules/module-one/src/main/java/One.java b/projects/multi-module/gradle/java-gradle-modules/module-one/src/main/java/One.java
new file mode 100644
index 00000000..1a883cfc
--- /dev/null
+++ b/projects/multi-module/gradle/java-gradle-modules/module-one/src/main/java/One.java
@@ -0,0 +1,8 @@
+public class One {
+
+ public String message = "";
+
+ public String foo() {
+ return "foo";
+ }
+}
diff --git a/projects/multi-module/gradle/java-gradle-modules/module-two/src/main/java/Two.java b/projects/multi-module/gradle/java-gradle-modules/module-two/src/main/java/Two.java
new file mode 100644
index 00000000..dd6b972f
--- /dev/null
+++ b/projects/multi-module/gradle/java-gradle-modules/module-two/src/main/java/Two.java
@@ -0,0 +1,5 @@
+public class Two {
+ public String foo() {
+ return "foo";
+ }
+}
diff --git a/projects/gradle-modules/settings.gradle b/projects/multi-module/gradle/java-gradle-modules/settings.gradle
similarity index 100%
rename from projects/gradle-modules/settings.gradle
rename to projects/multi-module/gradle/java-gradle-modules/settings.gradle
diff --git a/projects/multi-module/sonar-runner/README.md b/projects/multi-module/sonar-runner/README.md
new file mode 100644
index 00000000..69592117
--- /dev/null
+++ b/projects/multi-module/sonar-runner/README.md
@@ -0,0 +1,5 @@
+The best way to understand how SonarQube Runner 2.0+ works is to give a try to the examples following this order:
+* /projects/languages/java/java-sonar-runner-simple
+* java-sonar-runner-modules-same-structure
+* java-sonar-runner-modules-different-structures
+* java-sonar-runner-modules-own-configuration-file
\ No newline at end of file
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/Module 2/sources/Helloworld2.java b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/Module 2/sources/Helloworld2.java
new file mode 100644
index 00000000..31f17de6
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/Module 2/sources/Helloworld2.java
@@ -0,0 +1,7 @@
+public class Helloworld2 {
+
+ public void printHelloWorld2() {
+ System.out.println("Hello World 2!");
+ }
+
+}
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/README.md b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/README.md
new file mode 100644
index 00000000..f19ff1f4
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a multi-module Java project with the SonarQube Scanner.
+Modules have different structures.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/module1/src/Helloworld1.java b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/module1/src/Helloworld1.java
new file mode 100644
index 00000000..bbf16532
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/module1/src/Helloworld1.java
@@ -0,0 +1,8 @@
+public class Helloworld1 {
+
+ public void printHelloWorld1() {
+ System.out.println("Hello World 1!");
+ }
+
+}
+
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/sonar-project.properties b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/sonar-project.properties
new file mode 100644
index 00000000..6029a138
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/sonar-project.properties
@@ -0,0 +1,19 @@
+sonar.projectKey=java-sonar-runner-modules-different-structures
+sonar.projectName=Multi-module Java project analyzed with the SonarQube Runner (modules have different structures)
+sonar.projectVersion=1.0
+
+# Set modules IDs
+sonar.modules=module1,module2
+
+# Modules inherit properties set at parent level
+sonar.sources=src
+sonar.sourceEncoding=UTF-8
+sonar.language=java
+
+# Default module base directory is /
+# It has to be overriden for module2
+module2.sonar.projectBaseDir=Module 2
+
+# Overrides some parent properties in module2
+module2.sonar.sources=sources
+module2.sonar.projectName=Module #2
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/validation.txt b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/validation.txt
new file mode 100644
index 00000000..c0d56802
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-different-structures/validation.txt
@@ -0,0 +1,25 @@
+start server
+ with plugin java 3.7.1
+sonar-runner
+verify java-sonar-runner-modules-different-structures
+ measure lines is 17
+ measure ncloc is 10
+ measure files is 2
+ measure classes is 2
+verify java-sonar-runner-modules-different-structures:module1
+ measure lines is 9
+ measure ncloc is 5
+ measure files is 1
+ measure classes is 1
+verify java-sonar-runner-modules-different-structures:module1:src/Helloworld1.java
+ measure lines is 9
+ measure ncloc is 5
+verify java-sonar-runner-modules-different-structures:module2
+ measure lines is 8
+ measure ncloc is 5
+ measure files is 1
+ measure classes is 1
+verify java-sonar-runner-modules-different-structures:module2:sources/Helloworld2.java
+ measure lines is 8
+ measure ncloc is 5
+stop server
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/Module 2/sonar-project.properties b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/Module 2/sonar-project.properties
new file mode 100644
index 00000000..63ba27cf
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/Module 2/sonar-project.properties
@@ -0,0 +1,2 @@
+sonar.projectName=Module #2
+sonar.sources=sources
\ No newline at end of file
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/Module 2/sources/Helloworld2.java b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/Module 2/sources/Helloworld2.java
new file mode 100644
index 00000000..31f17de6
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/Module 2/sources/Helloworld2.java
@@ -0,0 +1,7 @@
+public class Helloworld2 {
+
+ public void printHelloWorld2() {
+ System.out.println("Hello World 2!");
+ }
+
+}
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/README.md b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/README.md
new file mode 100644
index 00000000..036e6cb5
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/README.md
@@ -0,0 +1,12 @@
+This example demonstrates how to analyze a multi-module Java project with the SonarQube Scanner.
+Each module has its own configuration file (sonar-project.properties).
+
+Prerequisites
+=============
+./projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/README.md
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/module1/sonar-project.properties b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/module1/sonar-project.properties
new file mode 100644
index 00000000..c7955df8
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/module1/sonar-project.properties
@@ -0,0 +1 @@
+sonar.projectName=Module #1
\ No newline at end of file
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/module1/src/Helloworld1.java b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/module1/src/Helloworld1.java
new file mode 100644
index 00000000..bbf16532
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/module1/src/Helloworld1.java
@@ -0,0 +1,8 @@
+public class Helloworld1 {
+
+ public void printHelloWorld1() {
+ System.out.println("Hello World 1!");
+ }
+
+}
+
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/sonar-project.properties b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/sonar-project.properties
new file mode 100644
index 00000000..105629ba
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/sonar-project.properties
@@ -0,0 +1,14 @@
+sonar.projectKey=java-sonar-runner-modules-own-configuration-file
+sonar.projectName=Multi-module Java project analyzed with the SonarQube Runner (each module has its own configuration file)
+sonar.projectVersion=1.0
+
+# Set modules IDs
+sonar.modules=module1,module2
+
+# Modules inherit properties set at parent level
+sonar.sources=src
+sonar.sourceEncoding=UTF-8
+sonar.language=java
+
+# By default, the base directory for a module is /.
+module2.sonar.projectBaseDir=Module 2
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/validation.txt b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/validation.txt
new file mode 100644
index 00000000..ca76513f
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-own-configuration-file/validation.txt
@@ -0,0 +1,25 @@
+start server
+ with plugin java 3.7.1
+sonar-runner
+verify java-sonar-runner-modules-own-configuration-file
+ measure lines is 17
+ measure ncloc is 10
+ measure files is 2
+ measure classes is 2
+verify java-sonar-runner-modules-own-configuration-file:module1
+ measure lines is 9
+ measure ncloc is 5
+ measure files is 1
+ measure classes is 1
+verify java-sonar-runner-modules-own-configuration-file:module1:src/Helloworld1.java
+ measure lines is 9
+ measure ncloc is 5
+verify java-sonar-runner-modules-own-configuration-file:module2
+ measure lines is 8
+ measure ncloc is 5
+ measure files is 1
+ measure classes is 1
+verify java-sonar-runner-modules-own-configuration-file:module2:sources/Helloworld2.java
+ measure lines is 8
+ measure ncloc is 5
+stop server
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/README.md b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/README.md
new file mode 100644
index 00000000..e3870ad0
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/README.md
@@ -0,0 +1,13 @@
+This example demonstrates how to analyze a multi-module Java project with the SonarQube Scanner.
+The structure is the same for every module.
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) 2.6.1+
+
+Usage
+=====
+* Analyze the project with SonarQube using the SonarQube Scanner:
+
+ sonar-scanner
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/module1/src/Helloworld1.java b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/module1/src/Helloworld1.java
new file mode 100644
index 00000000..bbf16532
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/module1/src/Helloworld1.java
@@ -0,0 +1,8 @@
+public class Helloworld1 {
+
+ public void printHelloWorld1() {
+ System.out.println("Hello World 1!");
+ }
+
+}
+
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/module2/src/Helloworld2.java b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/module2/src/Helloworld2.java
new file mode 100644
index 00000000..31f17de6
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/module2/src/Helloworld2.java
@@ -0,0 +1,7 @@
+public class Helloworld2 {
+
+ public void printHelloWorld2() {
+ System.out.println("Hello World 2!");
+ }
+
+}
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/sonar-project.properties b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/sonar-project.properties
new file mode 100644
index 00000000..bdff3d0a
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/sonar-project.properties
@@ -0,0 +1,11 @@
+sonar.projectKey=java-sonar-runner-modules-same-structure
+sonar.projectName=Multi-module Java project analyzed with the SonarQube Runner (same structure for every module)
+sonar.projectVersion=1.0
+
+# Set modules IDs
+sonar.modules=module1,module2
+
+# Modules inherit properties set at parent level
+sonar.sources=src
+sonar.sourceEncoding=UTF-8
+sonar.language=java
\ No newline at end of file
diff --git a/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/validation.txt b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/validation.txt
new file mode 100644
index 00000000..224d5452
--- /dev/null
+++ b/projects/multi-module/sonar-runner/java-sonar-runner-modules-same-structure/validation.txt
@@ -0,0 +1,25 @@
+start server
+ with plugin java 3.7.1
+sonar-runner
+verify java-sonar-runner-modules-same-structure
+ measure lines is 17
+ measure ncloc is 10
+ measure files is 2
+ measure classes is 2
+verify java-sonar-runner-modules-same-structure:module1
+ measure lines is 9
+ measure ncloc is 5
+ measure files is 1
+ measure classes is 1
+verify java-sonar-runner-modules-same-structure:module1:src/Helloworld1.java
+ measure lines is 9
+ measure ncloc is 5
+verify java-sonar-runner-modules-same-structure:module2
+ measure lines is 8
+ measure ncloc is 5
+ measure files is 1
+ measure classes is 1
+verify java-sonar-runner-modules-same-structure:module2:src/Helloworld2.java
+ measure lines is 8
+ measure ncloc is 5
+stop server
diff --git a/projects/tycho/README.md b/projects/tycho/README.md
new file mode 100644
index 00000000..fdb55b14
--- /dev/null
+++ b/projects/tycho/README.md
@@ -0,0 +1,18 @@
+This example demonstrates how to collect code coverage by tests, which executed by [tycho-surefire-plugin](http://www.eclipse.org/tycho/).
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarqube.org/downloads/) 4.5+
+* [SonarQube Java Plugin](http://docs.sonarqube.org/display/PLUG/Java+Plugin) 3.13.1+
+* Maven 3.0.3+
+
+Execution
+=========
+
+1. Build project and execute all tests:
+
+ mvn clean install
+
+2. Analyze with SonarQube:
+
+ mvn sonar:sonar
diff --git a/projects/tycho/plugin.tests/META-INF/MANIFEST.MF b/projects/tycho/plugin.tests/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..9cfe3a8c
--- /dev/null
+++ b/projects/tycho/plugin.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Example Plug-in Tests
+Bundle-SymbolicName: plugin.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.junit4;bundle-version="[4.0.0,5.0.0)",
+ plugin;bundle-version="1.0.0"
diff --git a/projects/tycho/plugin.tests/build.properties b/projects/tycho/plugin.tests/build.properties
new file mode 100644
index 00000000..56d77655
--- /dev/null
+++ b/projects/tycho/plugin.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = target/classes/
+bin.includes = META-INF/,\
+ .
diff --git a/projects/tycho/plugin.tests/pom.xml b/projects/tycho/plugin.tests/pom.xml
new file mode 100644
index 00000000..c99e7676
--- /dev/null
+++ b/projects/tycho/plugin.tests/pom.xml
@@ -0,0 +1,22 @@
+
+
+ 4.0.0
+
+
+ org.example.tycho-example
+ parent
+ 1.0.0-SNAPSHOT
+
+
+ plugin.tests
+ eclipse-test-plugin
+
+ JaCoCo Examples :: tycho-example :: plugin.tests
+
+
+
+
+ src
+
+
+
diff --git a/projects/tycho/plugin.tests/src/example/GreetingTest.java b/projects/tycho/plugin.tests/src/example/GreetingTest.java
new file mode 100644
index 00000000..5ae738be
--- /dev/null
+++ b/projects/tycho/plugin.tests/src/example/GreetingTest.java
@@ -0,0 +1,12 @@
+package example;
+
+import org.junit.Test;
+
+public class GreetingTest
+{
+ @Test
+ public void test()
+ {
+ new Greeting().coveredByTest();
+ }
+}
diff --git a/projects/tycho/plugin/META-INF/MANIFEST.MF b/projects/tycho/plugin/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..ea1934e6
--- /dev/null
+++ b/projects/tycho/plugin/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Example Plug-in
+Bundle-SymbolicName: plugin;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: example
diff --git a/projects/tycho/plugin/build.properties b/projects/tycho/plugin/build.properties
new file mode 100644
index 00000000..56d77655
--- /dev/null
+++ b/projects/tycho/plugin/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = target/classes/
+bin.includes = META-INF/,\
+ .
diff --git a/projects/tycho/plugin/pom.xml b/projects/tycho/plugin/pom.xml
new file mode 100644
index 00000000..d999146c
--- /dev/null
+++ b/projects/tycho/plugin/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+
+ org.example.tycho-example
+ parent
+ 1.0.0-SNAPSHOT
+
+
+ plugin
+ eclipse-plugin
+
+ JaCoCo Examples :: tycho-example :: plugin
+
+
diff --git a/projects/tycho/plugin/src/example/Greeting.java b/projects/tycho/plugin/src/example/Greeting.java
new file mode 100644
index 00000000..170658dc
--- /dev/null
+++ b/projects/tycho/plugin/src/example/Greeting.java
@@ -0,0 +1,9 @@
+package example;
+
+public class Greeting
+{
+ public void coveredByTest()
+ {
+ System.out.println("Hello, world.");
+ }
+}
diff --git a/projects/tycho/pom.xml b/projects/tycho/pom.xml
new file mode 100644
index 00000000..c5ad9c37
--- /dev/null
+++ b/projects/tycho/pom.xml
@@ -0,0 +1,63 @@
+
+
+ 4.0.0
+
+ org.example.tycho-example
+ parent
+ pom
+ 1.0.0-SNAPSHOT
+
+ JaCoCo Examples :: tycho-example :: parent
+
+
+ plugin
+ plugin.tests
+
+
+
+ UTF-8
+ UTF-8
+
+
+ ${project.basedir}/../target/jacoco.exec
+
+
+
+
+
+ org.eclipse.tycho
+ tycho-maven-plugin
+ 0.24.0
+ true
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.7.5.201505241946
+
+ true
+
+ example.*
+
+ ${sonar.jacoco.reportPath}
+
+
+
+
+ prepare-agent
+
+
+
+
+
+
+
+
+
+ eclipse-indigo
+ p2
+ http://download.eclipse.org/releases/indigo
+
+
+
+
diff --git a/scripts/database/mysql/create_database.sql b/scripts/database/mysql/create_database.sql
new file mode 100644
index 00000000..554cfcf1
--- /dev/null
+++ b/scripts/database/mysql/create_database.sql
@@ -0,0 +1,11 @@
+# Create SonarQube database and user.
+#
+# Command: mysql -u root -p < create_database.sql
+#
+
+CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
+
+CREATE USER 'sonar' IDENTIFIED BY 'sonar';
+GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar';
+GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar';
+FLUSH PRIVILEGES;
diff --git a/scripts/database/mysql/drop_database.sql b/scripts/database/mysql/drop_database.sql
new file mode 100644
index 00000000..de3beac9
--- /dev/null
+++ b/scripts/database/mysql/drop_database.sql
@@ -0,0 +1,8 @@
+# Drop SonarQube database and user.
+#
+# Command: mysql -u root -p < drop_database.sql
+#
+
+DROP DATABASE IF EXISTS sonar;
+DROP USER 'sonar'@'localhost';
+DROP USER 'sonar'@'%';
\ No newline at end of file
diff --git a/ws/manual-measure-ws/README.md b/ws/manual-measure-ws/README.md
new file mode 100644
index 00000000..dce85598
--- /dev/null
+++ b/ws/manual-measure-ws/README.md
@@ -0,0 +1,23 @@
+This example demonstrates how to use the SonarQube web service API (manual_measures).
+
+Documentation
+=============
+* http://docs.codehaus.org/x/iABuC
+
+Prerequisites
+=============
+* [SonarQube](http://www.sonarsource.org/downloads/) 3.5 or higher
+
+Usage
+=====
+* In src/main/java/sample/Sample.java, set the proper values to connect to your SonarQube server and project.
+* Compile the project:
+
+ mvn clean compile assembly:single
+
+* Call the web service:
+
+ cd target
+ java -jar manual-measure-ws-1.0-SNAPSHOT-jar-with-dependencies.jar
+
+* Check the output
diff --git a/ws/manual-measure-ws/pom.xml b/ws/manual-measure-ws/pom.xml
new file mode 100644
index 00000000..207d59ff
--- /dev/null
+++ b/ws/manual-measure-ws/pom.xml
@@ -0,0 +1,40 @@
+
+ 4.0.0
+ org.codehaus.sonar
+ manual-measure-ws
+ 1.0-SNAPSHOT
+ Example of Sonar manual measure web service call
+
+
+
+ org.codehaus.sonar
+ sonar-ws-client
+ 3.7.4
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+
+
+
+
+ maven-assembly-plugin
+
+
+
+ sample.Sample
+
+
+
+ jar-with-dependencies
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ws/manual-measure-ws/src/main/java/sample/Sample.java b/ws/manual-measure-ws/src/main/java/sample/Sample.java
new file mode 100644
index 00000000..9e9e37fa
--- /dev/null
+++ b/ws/manual-measure-ws/src/main/java/sample/Sample.java
@@ -0,0 +1,26 @@
+package sample;
+
+import org.sonar.wsclient.Host;
+import org.sonar.wsclient.Sonar;
+import org.sonar.wsclient.connectors.HttpClient4Connector;
+import org.sonar.wsclient.services.*;
+
+public class Sample {
+
+ public static void main(String args[]) {
+ String url = "http://localhost:9000";
+ String login = "admin";
+ String password = "admin";
+ Sonar sonar = new Sonar(new HttpClient4Connector(new Host(url, login, password)));
+
+ String projectKey = "java-sonar-runner-simple";
+ String manualMetricKey = "burned_budget";
+
+ sonar.create(ManualMeasureCreateQuery.create(projectKey, manualMetricKey).setValue(50.0));
+
+ for (ManualMeasure manualMeasure : sonar.findAll(ManualMeasureQuery.create(projectKey))) {
+ System.out.println("Manual measure on project: " + manualMeasure);
+ }
+ }
+
+}