]> source.dussan.org Git - sonarqube.git/commitdiff
Try to improve performance of MeasurePersister
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 18 Jun 2014 08:10:36 +0000 (10:10 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Wed, 18 Jun 2014 14:26:00 +0000 (16:26 +0200)
50 files changed:
pom.xml
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/Analyzer.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerContext.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerDescriptor.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssue.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/package-info.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/AnalyzerMeasure.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/package-info.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/package-info.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/FilenameUtils.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/Preconditions.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/StringUtils.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/WildcardPattern.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/package-info.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/languages/Language.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/languages/package-info.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/measures/Metric.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/measures/package-info.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/rules/QProfile.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/rules/RuleKey.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/rules/package-info.java [new file with mode: 0644]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/BatchComponent.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/BatchExtension.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/InstantiationStrategy.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/Analyzer.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/AnalyzerContext.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/AnalyzerDescriptor.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/issue/AnalyzerIssue.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/issue/package-info.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/measure/AnalyzerMeasure.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/measure/package-info.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/package-info.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/FilenameUtils.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/Preconditions.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/StringUtils.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/WildcardPattern.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/package-info.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/languages/Language.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/languages/package-info.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/measures/Metric.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/measures/package-info.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/rules/QProfile.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/rules/RuleKey.java [deleted file]
sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/rules/package-info.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/index/Caches.java
sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java
sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureValueCoder.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/scan/measure/MeasureCacheTest.java
sonar-core/src/main/resources/org/sonar/core/source/db/SnapshotSourceMapper.xml
sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java

diff --git a/pom.xml b/pom.xml
index 2b63e2a50210da18674644308de5a11c547aae68..907c04df713d83b0d69a7e7eea01e02fe58debc4 100644 (file)
--- a/pom.xml
+++ b/pom.xml
       <dependency>
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis</artifactId>
-        <version>3.2.2</version>
+        <version>3.2.7</version>
       </dependency>
       <dependency>
         <groupId>org.picocontainer</groupId>
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/Analyzer.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/Analyzer.java
new file mode 100644 (file)
index 0000000..6123545
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.analyzer;
+
+import org.sonar.batch.api.BatchExtension;
+
+/**
+ * <p>
+ * An Analyzer is invoked once during the analysis of a project. The analyzer can parse a flat file, connect to a web server... Analyzers are
+ * used to add measure and issues at file level.
+ * </p>
+ *
+ * <p>
+ * For example the Cobertura Analyzer parses Cobertura report and saves the first-level of measures on files.
+ * </p>
+ *
+ * @since 4.4
+ */
+public interface Analyzer extends BatchExtension {
+
+  /**
+   * Describe what this analyzer is doing.
+   * @return
+   */
+  AnalyzerDescriptor describe();
+
+  /**
+   * The method that is going to be run when the analyzer is called
+   *
+   * @param context the context
+   */
+  void analyse(AnalyzerContext context);
+
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerContext.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerContext.java
new file mode 100644 (file)
index 0000000..e29dfaf
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.analyzer;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.batch.api.analyzer.issue.AnalyzerIssue;
+import org.sonar.batch.api.analyzer.measure.AnalyzerMeasure;
+import org.sonar.batch.api.measures.Metric;
+
+import javax.annotation.CheckForNull;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+/**
+ * @since 4.4
+ */
+public interface AnalyzerContext {
+
+  // ----------- MEASURES --------------
+
+  /**
+   * Find a project measure.
+   */
+  @CheckForNull
+  AnalyzerMeasure<?> getMeasure(String metricKey);
+
+  /**
+   * Find a project measure.
+   */
+  @CheckForNull
+  <G extends Serializable> AnalyzerMeasure<G> getMeasure(Metric<G> metric);
+
+  /**
+   * Find a file measure.
+   */
+  @CheckForNull
+  AnalyzerMeasure<?> getMeasure(InputFile file, String metricKey);
+
+  /**
+   * Find a file measure.
+   */
+  @CheckForNull
+  <G extends Serializable> AnalyzerMeasure<G> getMeasure(InputFile file, Metric<G> metric);
+
+  /**
+   * Add a measure.
+   */
+  void addMeasure(AnalyzerMeasure<?> measure);
+
+  // ----------- ISSUES --------------
+
+  /**
+   * Add an issue.
+   */
+  void addIssue(AnalyzerIssue issue);
+
+  /**
+   * Add a list of issues.
+   */
+  void addIssues(Collection<AnalyzerIssue> issues);
+
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerDescriptor.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerDescriptor.java
new file mode 100644 (file)
index 0000000..0b97200
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.analyzer;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.batch.api.measures.Metric;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+public class AnalyzerDescriptor {
+
+  private final String name;
+  private final Metric<?>[] dependsOn;
+  private final Metric<?>[] provides;
+  private final String[] languages;
+  private final InputFile.Type[] types;
+
+  private AnalyzerDescriptor(Builder builder) {
+    this.name = builder.name;
+    this.dependsOn = builder.dependsOn != null ? builder.dependsOn : new Metric<?>[0];
+    this.provides = builder.provides != null ? builder.provides : new Metric<?>[0];
+    this.languages = builder.languages != null ? builder.languages : new String[0];
+    this.types = builder.types;
+  }
+
+  public String name() {
+    return name;
+  }
+
+  public Metric<?>[] dependsOn() {
+    return dependsOn;
+  }
+
+  public Metric<?>[] provides() {
+    return provides;
+  }
+
+  public Collection<String> languages() {
+    return Arrays.asList(languages);
+  }
+
+  public InputFile.Type[] types() {
+    return types;
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder {
+
+    private String name;
+    private Metric<?>[] dependsOn;
+    private Metric<?>[] provides;
+    private String[] languages;
+    private InputFile.Type[] types;
+
+    public Builder name(String name) {
+      this.name = name;
+      return this;
+    }
+
+    public Builder dependsOn(Metric<?>... metrics) {
+      this.dependsOn = metrics;
+      return this;
+    }
+
+    public Builder provides(Metric<?>... metrics) {
+      this.provides = metrics;
+      return this;
+    }
+
+    public Builder runOnLanguages(String... languageKeys) {
+      this.languages = languageKeys;
+      return this;
+    }
+
+    public Builder runOnTypes(InputFile.Type... types) {
+      this.types = types;
+      return this;
+    }
+
+    public AnalyzerDescriptor build() {
+      return new AnalyzerDescriptor(this);
+    }
+
+  }
+
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssue.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssue.java
new file mode 100644 (file)
index 0000000..f39d884
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.analyzer.issue;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.batch.api.analyzer.Analyzer;
+import org.sonar.batch.api.internal.Preconditions;
+import org.sonar.batch.api.rules.RuleKey;
+
+import javax.annotation.Nullable;
+
+/**
+ * Issue reported by an {@link Analyzer}
+ *
+ * @since 4.4
+ */
+public class AnalyzerIssue {
+
+  private final InputFile inputFile;
+  private final RuleKey ruleKey;
+  private final String message;
+  private final Integer line;
+  private final Double effortToFix;
+
+  private AnalyzerIssue(Builder builder) {
+    this.inputFile = builder.file;
+    this.ruleKey = builder.ruleKey;
+    this.message = builder.message;
+    this.line = builder.line;
+    this.effortToFix = builder.effortToFix;
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  @Nullable
+  public InputFile inputFile() {
+    return inputFile;
+  }
+
+  public RuleKey ruleKey() {
+    return ruleKey;
+  }
+
+  public String message() {
+    return message;
+  }
+
+  public Integer line() {
+    return line;
+  }
+
+  @Nullable
+  public Double effortToFix() {
+    return effortToFix;
+  }
+
+  public static class Builder {
+
+    private Boolean onProject = null;
+    private InputFile file;
+    private RuleKey ruleKey;
+    private String message;
+    private Integer line;
+    private Double effortToFix;
+
+    public AnalyzerIssue build() {
+      return new AnalyzerIssue(this);
+    }
+
+    public Builder ruleKey(RuleKey ruleKey) {
+      this.ruleKey = ruleKey;
+      return this;
+    }
+
+    public Builder onFile(InputFile file) {
+      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
+      Preconditions.checkNotNull(file, "InputFile should be non null");
+      this.file = file;
+      this.onProject = false;
+      return this;
+    }
+
+    public Builder onProject() {
+      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
+      this.file = null;
+      this.onProject = true;
+      return this;
+    }
+
+    public Builder atLine(int line) {
+      this.line = line;
+      return this;
+    }
+
+    public Builder effortToFix(@Nullable Double effortToFix) {
+      this.effortToFix = effortToFix;
+      return this;
+    }
+
+    public Builder message(String message) {
+      this.message = message;
+      return this;
+    }
+
+  }
+
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/package-info.java
new file mode 100644 (file)
index 0000000..70a6600
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.batch.api.analyzer.issue;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/AnalyzerMeasure.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/AnalyzerMeasure.java
new file mode 100644 (file)
index 0000000..3d74dca
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.analyzer.measure;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.batch.api.internal.Preconditions;
+import org.sonar.batch.api.measures.Metric;
+
+import javax.annotation.Nullable;
+
+import java.io.Serializable;
+
+public class AnalyzerMeasure<G extends Serializable> implements Serializable {
+
+  private final InputFile inputFile;
+  private final String metricKey;
+  private final G value;
+
+  private AnalyzerMeasure(Builder<G> builder) {
+    Preconditions.checkNotNull(builder.value, "Measure value can't be null");
+    Preconditions.checkNotNull(builder.metricKey, "Measure metricKey can't be null");
+    this.inputFile = builder.file;
+    this.metricKey = builder.metricKey;
+    this.value = builder.value;
+  }
+
+  @Nullable
+  public InputFile inputFile() {
+    return inputFile;
+  }
+
+  public String metricKey() {
+    return metricKey;
+  }
+
+  public Serializable value() {
+    return value;
+  }
+
+  public static <G extends Serializable> Builder<G> builder() {
+    return new Builder<G>();
+  }
+
+  public static class Builder<G extends Serializable> {
+
+    private Boolean onProject = null;
+    private InputFile file;
+    private String metricKey;
+    private G value;
+
+    public Builder<G> onFile(InputFile file) {
+      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
+      Preconditions.checkNotNull(file, "InputFile should be non null");
+      this.file = file;
+      this.onProject = false;
+      return this;
+    }
+
+    public Builder<G> onProject() {
+      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
+      this.file = null;
+      this.onProject = true;
+      return this;
+    }
+
+    private Builder<G> metricKey(String metricKey) {
+      Preconditions.checkState(metricKey != null, "Metric already defined");
+      this.metricKey = metricKey;
+      return this;
+    }
+
+    public Builder<G> forMetric(Metric<G> metric) {
+      return metricKey(metric.key());
+    }
+
+    public Builder<G> withValue(G value) {
+      Preconditions.checkState(value != null, "Measure value already defined");
+      Preconditions.checkNotNull(value, "Measure value can't be null");
+      this.value = value;
+      return this;
+    }
+
+    public AnalyzerMeasure<G> build() {
+      return new AnalyzerMeasure<G>(this);
+    }
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof AnalyzerMeasure)) {
+      return false;
+    }
+    AnalyzerMeasure<?> other = (AnalyzerMeasure<?>) obj;
+    return metricKey.equals(other.metricKey)
+      && value.equals(other.value)
+      && (inputFile == null ? other.inputFile == null : inputFile.equals(other.inputFile));
+  }
+
+  @Override
+  public int hashCode() {
+    return metricKey.hashCode()
+      + value.hashCode()
+      + (inputFile != null ? inputFile.hashCode() : 0);
+  }
+
+  @Override
+  public String toString() {
+    return "AnalyzerMeasure[" + (inputFile != null ? "inputFile=" + inputFile.toString() : "onProject")
+      + ",metricKey=" + metricKey + ",value=" + value + "]";
+  }
+
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/package-info.java
new file mode 100644 (file)
index 0000000..b490662
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.batch.api.analyzer.measure;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/analyzer/package-info.java
new file mode 100644 (file)
index 0000000..5b72f8c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.batch.api.analyzer;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/FilenameUtils.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/FilenameUtils.java
new file mode 100644 (file)
index 0000000..0461255
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.internal;
+
+import java.io.File;
+
+/**
+ * Copied from commons io
+ *
+ */
+public class FilenameUtils {
+
+  public static final char EXTENSION_SEPARATOR = '.';
+
+  private static final char UNIX_SEPARATOR = '/';
+
+  /**
+   * The Windows separator character.
+   */
+  private static final char WINDOWS_SEPARATOR = '\\';
+
+  /**
+   * The system separator character.
+   */
+  private static final char SYSTEM_SEPARATOR = File.separatorChar;
+
+  /**
+   * The separator character that is the opposite of the system separator.
+   */
+  private static final char OTHER_SEPARATOR;
+  static {
+    if (isSystemWindows()) {
+      OTHER_SEPARATOR = UNIX_SEPARATOR;
+    } else {
+      OTHER_SEPARATOR = WINDOWS_SEPARATOR;
+    }
+  }
+
+  static boolean isSystemWindows() {
+    return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR;
+  }
+
+  public static String normalize(String filename) {
+    return doNormalize(filename, UNIX_SEPARATOR, true);
+  }
+
+  private static String doNormalize(String filename, char separator, boolean keepSeparator) {
+    if (filename == null) {
+      return null;
+    }
+    int size = filename.length();
+    if (size == 0) {
+      return filename;
+    }
+    int prefix = getPrefixLength(filename);
+    if (prefix < 0) {
+      return null;
+    }
+
+    char[] array = new char[size + 2]; // +1 for possible extra slash, +2 for arraycopy
+    filename.getChars(0, filename.length(), array, 0);
+
+    // fix separators throughout
+    char otherSeparator = separator == SYSTEM_SEPARATOR ? OTHER_SEPARATOR : SYSTEM_SEPARATOR;
+    for (int i = 0; i < array.length; i++) {
+      if (array[i] == otherSeparator) {
+        array[i] = separator;
+      }
+    }
+
+    // add extra separator on the end to simplify code below
+    boolean lastIsDirectory = true;
+    if (array[size - 1] != separator) {
+      array[size++] = separator;
+      lastIsDirectory = false;
+    }
+
+    // adjoining slashes
+    for (int i = prefix + 1; i < size; i++) {
+      if (array[i] == separator && array[i - 1] == separator) {
+        System.arraycopy(array, i, array, i - 1, size - i);
+        size--;
+        i--;
+      }
+    }
+
+    // dot slash
+    for (int i = prefix + 1; i < size; i++) {
+      if (array[i] == separator && array[i - 1] == '.' &&
+        (i == prefix + 1 || array[i - 2] == separator)) {
+        if (i == size - 1) {
+          lastIsDirectory = true;
+        }
+        System.arraycopy(array, i + 1, array, i - 1, size - i);
+        size -= 2;
+        i--;
+      }
+    }
+
+    // double dot slash
+    outer: for (int i = prefix + 2; i < size; i++) {
+      if (array[i] == separator && array[i - 1] == '.' && array[i - 2] == '.' &&
+        (i == prefix + 2 || array[i - 3] == separator)) {
+        if (i == prefix + 2) {
+          return null;
+        }
+        if (i == size - 1) {
+          lastIsDirectory = true;
+        }
+        int j;
+        for (j = i - 4; j >= prefix; j--) {
+          if (array[j] == separator) {
+            // remove b/../ from a/b/../c
+            System.arraycopy(array, i + 1, array, j + 1, size - i);
+            size -= i - j;
+            i = j + 1;
+            continue outer;
+          }
+        }
+        // remove a/../ from a/../c
+        System.arraycopy(array, i + 1, array, prefix, size - i);
+        size -= i + 1 - prefix;
+        i = prefix + 1;
+      }
+    }
+
+    if (size <= 0) { // should never be less than 0
+      return "";
+    }
+    if (size <= prefix) { // should never be less than prefix
+      return new String(array, 0, size);
+    }
+    if (lastIsDirectory && keepSeparator) {
+      return new String(array, 0, size); // keep trailing separator
+    }
+    return new String(array, 0, size - 1); // lose trailing separator
+  }
+
+  public static int getPrefixLength(String filename) {
+    if (filename == null) {
+      return -1;
+    }
+    int len = filename.length();
+    if (len == 0) {
+      return 0;
+    }
+    char ch0 = filename.charAt(0);
+    if (ch0 == ':') {
+      return -1;
+    }
+    if (len == 1) {
+      if (ch0 == '~') {
+        return 2; // return a length greater than the input
+      }
+      return isSeparator(ch0) ? 1 : 0;
+    } else {
+      if (ch0 == '~') {
+        int posUnix = filename.indexOf(UNIX_SEPARATOR, 1);
+        int posWin = filename.indexOf(WINDOWS_SEPARATOR, 1);
+        if (posUnix == -1 && posWin == -1) {
+          return len + 1; // return a length greater than the input
+        }
+        posUnix = posUnix == -1 ? posWin : posUnix;
+        posWin = posWin == -1 ? posUnix : posWin;
+        return Math.min(posUnix, posWin) + 1;
+      }
+      char ch1 = filename.charAt(1);
+      if (ch1 == ':') {
+        ch0 = Character.toUpperCase(ch0);
+        if (ch0 >= 'A' && ch0 <= 'Z') {
+          if (len == 2 || isSeparator(filename.charAt(2)) == false) {
+            return 2;
+          }
+          return 3;
+        }
+        return -1;
+
+      } else if (isSeparator(ch0) && isSeparator(ch1)) {
+        int posUnix = filename.indexOf(UNIX_SEPARATOR, 2);
+        int posWin = filename.indexOf(WINDOWS_SEPARATOR, 2);
+        if (posUnix == -1 && posWin == -1 || posUnix == 2 || posWin == 2) {
+          return -1;
+        }
+        posUnix = posUnix == -1 ? posWin : posUnix;
+        posWin = posWin == -1 ? posUnix : posWin;
+        return Math.min(posUnix, posWin) + 1;
+      } else {
+        return isSeparator(ch0) ? 1 : 0;
+      }
+    }
+  }
+
+  private static boolean isSeparator(char ch) {
+    return ch == UNIX_SEPARATOR || ch == WINDOWS_SEPARATOR;
+  }
+
+  public static String getExtension(String filename) {
+    if (filename == null) {
+      return null;
+    }
+    int index = indexOfExtension(filename);
+    if (index == -1) {
+      return "";
+    } else {
+      return filename.substring(index + 1);
+    }
+  }
+
+  public static int indexOfExtension(String filename) {
+    if (filename == null) {
+      return -1;
+    }
+    int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
+    int lastSeparator = indexOfLastSeparator(filename);
+    return lastSeparator > extensionPos ? -1 : extensionPos;
+  }
+
+  public static int indexOfLastSeparator(String filename) {
+    if (filename == null) {
+      return -1;
+    }
+    int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
+    int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
+    return Math.max(lastUnixPos, lastWindowsPos);
+  }
+
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/Preconditions.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/Preconditions.java
new file mode 100644 (file)
index 0000000..75ac73f
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.internal;
+
+import javax.annotation.Nullable;
+
+/**
+ * Copied from Guava
+ */
+public final class Preconditions {
+  private Preconditions() {
+  }
+
+  /**
+   * Ensures the truth of an expression involving one or more parameters to the
+   * calling method.
+   *
+   * @param expression a boolean expression
+   * @throws IllegalArgumentException if {@code expression} is false
+   */
+  public static void checkArgument(boolean expression) {
+    if (!expression) {
+      throw new IllegalArgumentException();
+    }
+  }
+
+  /**
+   * Ensures the truth of an expression involving one or more parameters to the
+   * calling method.
+   *
+   * @param expression a boolean expression
+   * @param errorMessage the exception message to use if the check fails; will
+   *     be converted to a string using {@link String#valueOf(Object)}
+   * @throws IllegalArgumentException if {@code expression} is false
+   */
+  public static void checkArgument(
+    boolean expression, @Nullable Object errorMessage) {
+    if (!expression) {
+      throw new IllegalArgumentException(String.valueOf(errorMessage));
+    }
+  }
+
+  /**
+   * Ensures the truth of an expression involving one or more parameters to the
+   * calling method.
+   *
+   * @param expression a boolean expression
+   * @param errorMessageTemplate a template for the exception message should the
+   *     check fail. The message is formed by replacing each {@code %s}
+   *     placeholder in the template with an argument. These are matched by
+   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+   *     Unmatched arguments will be appended to the formatted message in square
+   *     braces. Unmatched placeholders will be left as-is.
+   * @param errorMessageArgs the arguments to be substituted into the message
+   *     template. Arguments are converted to strings using
+   *     {@link String#valueOf(Object)}.
+   * @throws IllegalArgumentException if {@code expression} is false
+   * @throws NullPointerException if the check fails and either {@code
+   *     errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
+   *     this happen)
+   */
+  public static void checkArgument(boolean expression,
+    @Nullable String errorMessageTemplate,
+    @Nullable Object... errorMessageArgs) {
+    if (!expression) {
+      throw new IllegalArgumentException(
+        format(errorMessageTemplate, errorMessageArgs));
+    }
+  }
+
+  /**
+   * Ensures the truth of an expression involving the state of the calling
+   * instance, but not involving any parameters to the calling method.
+   *
+   * @param expression a boolean expression
+   * @throws IllegalStateException if {@code expression} is false
+   */
+  public static void checkState(boolean expression) {
+    if (!expression) {
+      throw new IllegalStateException();
+    }
+  }
+
+  /**
+   * Ensures the truth of an expression involving the state of the calling
+   * instance, but not involving any parameters to the calling method.
+   *
+   * @param expression a boolean expression
+   * @param errorMessage the exception message to use if the check fails; will
+   *     be converted to a string using {@link String#valueOf(Object)}
+   * @throws IllegalStateException if {@code expression} is false
+   */
+  public static void checkState(
+    boolean expression, @Nullable Object errorMessage) {
+    if (!expression) {
+      throw new IllegalStateException(String.valueOf(errorMessage));
+    }
+  }
+
+  /**
+   * Ensures the truth of an expression involving the state of the calling
+   * instance, but not involving any parameters to the calling method.
+   *
+   * @param expression a boolean expression
+   * @param errorMessageTemplate a template for the exception message should the
+   *     check fail. The message is formed by replacing each {@code %s}
+   *     placeholder in the template with an argument. These are matched by
+   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+   *     Unmatched arguments will be appended to the formatted message in square
+   *     braces. Unmatched placeholders will be left as-is.
+   * @param errorMessageArgs the arguments to be substituted into the message
+   *     template. Arguments are converted to strings using
+   *     {@link String#valueOf(Object)}.
+   * @throws IllegalStateException if {@code expression} is false
+   * @throws NullPointerException if the check fails and either {@code
+   *     errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
+   *     this happen)
+   */
+  public static void checkState(boolean expression,
+    @Nullable String errorMessageTemplate,
+    @Nullable Object... errorMessageArgs) {
+    if (!expression) {
+      throw new IllegalStateException(
+        format(errorMessageTemplate, errorMessageArgs));
+    }
+  }
+
+  /**
+   * Ensures that an object reference passed as a parameter to the calling
+   * method is not null.
+   *
+   * @param reference an object reference
+   * @return the non-null reference that was validated
+   * @throws NullPointerException if {@code reference} is null
+   */
+  public static <T> T checkNotNull(T reference) {
+    if (reference == null) {
+      throw new NullPointerException();
+    }
+    return reference;
+  }
+
+  /**
+   * Ensures that an object reference passed as a parameter to the calling
+   * method is not null.
+   *
+   * @param reference an object reference
+   * @param errorMessage the exception message to use if the check fails; will
+   *     be converted to a string using {@link String#valueOf(Object)}
+   * @return the non-null reference that was validated
+   * @throws NullPointerException if {@code reference} is null
+   */
+  public static <T> T checkNotNull(T reference, @Nullable Object errorMessage) {
+    if (reference == null) {
+      throw new NullPointerException(String.valueOf(errorMessage));
+    }
+    return reference;
+  }
+
+  /**
+   * Ensures that an object reference passed as a parameter to the calling
+   * method is not null.
+   *
+   * @param reference an object reference
+   * @param errorMessageTemplate a template for the exception message should the
+   *     check fail. The message is formed by replacing each {@code %s}
+   *     placeholder in the template with an argument. These are matched by
+   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+   *     Unmatched arguments will be appended to the formatted message in square
+   *     braces. Unmatched placeholders will be left as-is.
+   * @param errorMessageArgs the arguments to be substituted into the message
+   *     template. Arguments are converted to strings using
+   *     {@link String#valueOf(Object)}.
+   * @return the non-null reference that was validated
+   * @throws NullPointerException if {@code reference} is null
+   */
+  public static <T> T checkNotNull(T reference,
+    @Nullable String errorMessageTemplate,
+    @Nullable Object... errorMessageArgs) {
+    if (reference == null) {
+      // If either of these parameters is null, the right thing happens anyway
+      throw new NullPointerException(
+        format(errorMessageTemplate, errorMessageArgs));
+    }
+    return reference;
+  }
+
+  /*
+   * All recent hotspots (as of 2009) *really* like to have the natural code
+   * 
+   * if (guardExpression) {
+   * throw new BadException(messageExpression);
+   * }
+   * 
+   * refactored so that messageExpression is moved to a separate
+   * String-returning method.
+   * 
+   * if (guardExpression) {
+   * throw new BadException(badMsg(...));
+   * }
+   * 
+   * The alternative natural refactorings into void or Exception-returning
+   * methods are much slower. This is a big deal - we're talking factors of
+   * 2-8 in microbenchmarks, not just 10-20%. (This is a hotspot optimizer
+   * bug, which should be fixed, but that's a separate, big project).
+   * 
+   * The coding pattern above is heavily used in java.util, e.g. in ArrayList.
+   * There is a RangeCheckMicroBenchmark in the JDK that was used to test this.
+   * 
+   * But the methods in this class want to throw different exceptions,
+   * depending on the args, so it appears that this pattern is not directly
+   * applicable. But we can use the ridiculous, devious trick of throwing an
+   * exception in the middle of the construction of another exception.
+   * Hotspot is fine with that.
+   */
+
+  /**
+   * Ensures that {@code index} specifies a valid <i>element</i> in an array,
+   * list or string of size {@code size}. An element index may range from zero,
+   * inclusive, to {@code size}, exclusive.
+   *
+   * @param index a user-supplied index identifying an element of an array, list
+   *     or string
+   * @param size the size of that array, list or string
+   * @return the value of {@code index}
+   * @throws IndexOutOfBoundsException if {@code index} is negative or is not
+   *     less than {@code size}
+   * @throws IllegalArgumentException if {@code size} is negative
+   */
+  public static int checkElementIndex(int index, int size) {
+    return checkElementIndex(index, size, "index");
+  }
+
+  /**
+   * Ensures that {@code index} specifies a valid <i>element</i> in an array,
+   * list or string of size {@code size}. An element index may range from zero,
+   * inclusive, to {@code size}, exclusive.
+   *
+   * @param index a user-supplied index identifying an element of an array, list
+   *     or string
+   * @param size the size of that array, list or string
+   * @param desc the text to use to describe this index in an error message
+   * @return the value of {@code index}
+   * @throws IndexOutOfBoundsException if {@code index} is negative or is not
+   *     less than {@code size}
+   * @throws IllegalArgumentException if {@code size} is negative
+   */
+  public static int checkElementIndex(
+    int index, int size, @Nullable String desc) {
+    // Carefully optimized for execution by hotspot (explanatory comment above)
+    if (index < 0 || index >= size) {
+      throw new IndexOutOfBoundsException(badElementIndex(index, size, desc));
+    }
+    return index;
+  }
+
+  private static String badElementIndex(int index, int size, String desc) {
+    if (index < 0) {
+      return format("%s (%s) must not be negative", desc, index);
+    } else if (size < 0) {
+      throw new IllegalArgumentException("negative size: " + size);
+    } else { // index >= size
+      return format("%s (%s) must be less than size (%s)", desc, index, size);
+    }
+  }
+
+  /**
+   * Ensures that {@code index} specifies a valid <i>position</i> in an array,
+   * list or string of size {@code size}. A position index may range from zero
+   * to {@code size}, inclusive.
+   *
+   * @param index a user-supplied index identifying a position in an array, list
+   *     or string
+   * @param size the size of that array, list or string
+   * @return the value of {@code index}
+   * @throws IndexOutOfBoundsException if {@code index} is negative or is
+   *     greater than {@code size}
+   * @throws IllegalArgumentException if {@code size} is negative
+   */
+  public static int checkPositionIndex(int index, int size) {
+    return checkPositionIndex(index, size, "index");
+  }
+
+  /**
+   * Ensures that {@code index} specifies a valid <i>position</i> in an array,
+   * list or string of size {@code size}. A position index may range from zero
+   * to {@code size}, inclusive.
+   *
+   * @param index a user-supplied index identifying a position in an array, list
+   *     or string
+   * @param size the size of that array, list or string
+   * @param desc the text to use to describe this index in an error message
+   * @return the value of {@code index}
+   * @throws IndexOutOfBoundsException if {@code index} is negative or is
+   *     greater than {@code size}
+   * @throws IllegalArgumentException if {@code size} is negative
+   */
+  public static int checkPositionIndex(
+    int index, int size, @Nullable String desc) {
+    // Carefully optimized for execution by hotspot (explanatory comment above)
+    if (index < 0 || index > size) {
+      throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc));
+    }
+    return index;
+  }
+
+  private static String badPositionIndex(int index, int size, String desc) {
+    if (index < 0) {
+      return format("%s (%s) must not be negative", desc, index);
+    } else if (size < 0) {
+      throw new IllegalArgumentException("negative size: " + size);
+    } else { // index > size
+      return format("%s (%s) must not be greater than size (%s)",
+        desc, index, size);
+    }
+  }
+
+  /**
+   * Ensures that {@code start} and {@code end} specify a valid <i>positions</i>
+   * in an array, list or string of size {@code size}, and are in order. A
+   * position index may range from zero to {@code size}, inclusive.
+   *
+   * @param start a user-supplied index identifying a starting position in an
+   *     array, list or string
+   * @param end a user-supplied index identifying a ending position in an array,
+   *     list or string
+   * @param size the size of that array, list or string
+   * @throws IndexOutOfBoundsException if either index is negative or is
+   *     greater than {@code size}, or if {@code end} is less than {@code start}
+   * @throws IllegalArgumentException if {@code size} is negative
+   */
+  public static void checkPositionIndexes(int start, int end, int size) {
+    // Carefully optimized for execution by hotspot (explanatory comment above)
+    if (start < 0 || end < start || end > size) {
+      throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
+    }
+  }
+
+  private static String badPositionIndexes(int start, int end, int size) {
+    if (start < 0 || start > size) {
+      return badPositionIndex(start, size, "start index");
+    }
+    if (end < 0 || end > size) {
+      return badPositionIndex(end, size, "end index");
+    }
+    // end < start
+    return format("end index (%s) must not be less than start index (%s)",
+      end, start);
+  }
+
+  /**
+   * Substitutes each {@code %s} in {@code template} with an argument. These
+   * are matched by position - the first {@code %s} gets {@code args[0]}, etc.
+   * If there are more arguments than placeholders, the unmatched arguments will
+   * be appended to the end of the formatted message in square braces.
+   *
+   * @param template a non-null string containing 0 or more {@code %s}
+   *     placeholders.
+   * @param args the arguments to be substituted into the message
+   *     template. Arguments are converted to strings using
+   *     {@link String#valueOf(Object)}. Arguments can be null.
+   */
+  static String format(String template,
+    @Nullable Object... args) {
+    template = String.valueOf(template); // null -> "null"
+
+    // start substituting the arguments into the '%s' placeholders
+    StringBuilder builder = new StringBuilder(
+      template.length() + 16 * args.length);
+    int templateStart = 0;
+    int i = 0;
+    while (i < args.length) {
+      int placeholderStart = template.indexOf("%s", templateStart);
+      if (placeholderStart == -1) {
+        break;
+      }
+      builder.append(template.substring(templateStart, placeholderStart));
+      builder.append(args[i++]);
+      templateStart = placeholderStart + 2;
+    }
+    builder.append(template.substring(templateStart));
+
+    // if we run out of placeholders, append the extra args in square braces
+    if (i < args.length) {
+      builder.append(" [");
+      builder.append(args[i++]);
+      while (i < args.length) {
+        builder.append(", ");
+        builder.append(args[i++]);
+      }
+      builder.append(']');
+    }
+
+    return builder.toString();
+  }
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/StringUtils.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/StringUtils.java
new file mode 100644 (file)
index 0000000..ab279ae
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.internal;
+
+/**
+ * Copied from commons lang
+ */
+public class StringUtils {
+
+  public static final String EMPTY = "";
+
+  public static String trim(String str) {
+    return str == null ? null : str.trim();
+  }
+
+  public static String removeStart(String str, String remove) {
+    if (isEmpty(str) || isEmpty(remove)) {
+      return str;
+    }
+    if (str.startsWith(remove)) {
+      return str.substring(remove.length());
+    }
+    return str;
+  }
+
+  public static String removeEnd(String str, String remove) {
+    if (isEmpty(str) || isEmpty(remove)) {
+      return str;
+    }
+    if (str.endsWith(remove)) {
+      return str.substring(0, str.length() - remove.length());
+    }
+    return str;
+  }
+
+  public static boolean isEmpty(String str) {
+    return str == null || str.length() == 0;
+  }
+
+  public static boolean startsWithIgnoreCase(String str, String prefix) {
+    return startsWith(str, prefix, true);
+  }
+
+  private static boolean startsWith(String str, String prefix, boolean ignoreCase) {
+    if (str == null || prefix == null) {
+      return (str == null && prefix == null);
+    }
+    if (prefix.length() > str.length()) {
+      return false;
+    }
+    return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
+  }
+
+  public static String substring(String str, int start) {
+    if (str == null) {
+      return null;
+    }
+
+    // handle negatives, which means last n characters
+    if (start < 0) {
+      start = str.length() + start; // remember start is negative
+    }
+
+    if (start < 0) {
+      start = 0;
+    }
+    if (start > str.length()) {
+      return EMPTY;
+    }
+
+    return str.substring(start);
+  }
+
+  public static boolean isBlank(String str) {
+    int strLen;
+    if (str == null || (strLen = str.length()) == 0) {
+      return true;
+    }
+    for (int i = 0; i < strLen; i++) {
+      if ((Character.isWhitespace(str.charAt(i)) == false)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public static boolean isNotBlank(String str) {
+    return !StringUtils.isBlank(str);
+  }
+
+  public static String removeEndIgnoreCase(String str, String remove) {
+    if (isEmpty(str) || isEmpty(remove)) {
+      return str;
+    }
+    if (endsWithIgnoreCase(str, remove)) {
+      return str.substring(0, str.length() - remove.length());
+    }
+    return str;
+  }
+
+  public static boolean endsWithIgnoreCase(String str, String suffix) {
+    return endsWith(str, suffix, true);
+  }
+
+  private static boolean endsWith(String str, String suffix, boolean ignoreCase) {
+    if (str == null || suffix == null) {
+      return (str == null && suffix == null);
+    }
+    if (suffix.length() > str.length()) {
+      return false;
+    }
+    int strOffset = str.length() - suffix.length();
+    return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length());
+  }
+
+  public static String lowerCase(String str) {
+    if (str == null) {
+      return null;
+    }
+    return str.toLowerCase();
+  }
+
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/WildcardPattern.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/WildcardPattern.java
new file mode 100644 (file)
index 0000000..f179fd7
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Implementation of Ant-style matching patterns.
+ * Contrary to other implementations (like AntPathMatcher from Spring Framework) it is based on {@link Pattern Java Regular Expressions}.
+ * To increase performance it holds an internal cache of all processed patterns.
+ * <p>
+ * Following rules are applied:
+ * <ul>
+ * <li>? matches single character</li>
+ * <li>* matches zero or more characters</li>
+ * <li>** matches zero or more 'directories'</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Some examples of patterns:
+ * <ul>
+ * <li><code>org/T?st.java</code> - matches <code>org/Test.java</code> and also <code>org/Tost.java</code></li>
+ * <li><code>org/*.java</code> - matches all <code>.java</code> files in the <code>org</code> directory,
+ * e.g. <code>org/Foo.java</code> or <code>org/Bar.java</code></li>
+ * <li><code>org/**</code> - matches all files underneath the <code>org</code> directory,
+ * e.g. <code>org/Foo.java</code> or <code>org/foo/bar.jsp</code></li>
+ * <li><code>org/&#42;&#42;/Test.java</code> - matches all <code>Test.java</code> files underneath the <code>org</code> directory,
+ * e.g. <code>org/Test.java</code> or <code>org/foo/Test.java</code> or <code>org/foo/bar/Test.java</code></li>
+ * <li><code>org/&#42;&#42;/*.java</code> - matches all <code>.java</code> files underneath the <code>org</code> directory,
+ * e.g. <code>org/Foo.java</code> or <code>org/foo/Bar.java</code> or <code>org/foo/bar/Baz.java</code></li>
+ * </ul>
+ * </p>
+ * <p>
+ * Another implementation, which is also based on Java Regular Expressions, can be found in
+ * <a href="https://github.com/JetBrains/intellij-community/blob/idea/107.743/platform/util/src/com/intellij/openapi/util/io/FileUtil.java#L847">FileUtil</a>
+ * from IntelliJ OpenAPI.
+ * </p>
+ * 
+ */
+public class WildcardPattern {
+
+  private static final Map<String, WildcardPattern> CACHE = new HashMap<String, WildcardPattern>();
+  private static final String SPECIAL_CHARS = "()[]^$.{}+|";
+
+  private Pattern pattern;
+  private String stringRepresentation;
+
+  protected WildcardPattern(String pattern, String directorySeparator) {
+    this.stringRepresentation = pattern;
+    this.pattern = Pattern.compile(toRegexp(pattern, directorySeparator));
+  }
+
+  private static String toRegexp(String antPattern, String directorySeparator) {
+    final String escapedDirectorySeparator = '\\' + directorySeparator;
+
+    final StringBuilder sb = new StringBuilder(antPattern.length());
+
+    sb.append('^');
+
+    int i = antPattern.startsWith("/") || antPattern.startsWith("\\") ? 1 : 0;
+    while (i < antPattern.length()) {
+      final char ch = antPattern.charAt(i);
+
+      if (SPECIAL_CHARS.indexOf(ch) != -1) {
+        // Escape regexp-specific characters
+        sb.append('\\').append(ch);
+      } else if (ch == '*') {
+        if (i + 1 < antPattern.length() && antPattern.charAt(i + 1) == '*') {
+          // Double asterisk
+          // Zero or more directories
+          if (i + 2 < antPattern.length() && isSlash(antPattern.charAt(i + 2))) {
+            sb.append("(?:.*").append(escapedDirectorySeparator).append("|)");
+            i += 2;
+          } else {
+            sb.append(".*");
+            i += 1;
+          }
+        } else {
+          // Single asterisk
+          // Zero or more characters excluding directory separator
+          sb.append("[^").append(escapedDirectorySeparator).append("]*?");
+        }
+      } else if (ch == '?') {
+        // Any single character excluding directory separator
+        sb.append("[^").append(escapedDirectorySeparator).append("]");
+      } else if (isSlash(ch)) {
+        // Directory separator
+        sb.append(escapedDirectorySeparator);
+      } else {
+        // Single character
+        sb.append(ch);
+      }
+
+      i++;
+    }
+
+    sb.append('$');
+
+    return sb.toString();
+  }
+
+  private static boolean isSlash(char ch) {
+    return ch == '/' || ch == '\\';
+  }
+
+  /**
+   * Returns string representation of this pattern.
+   * 
+   * @since 2.5
+   */
+  @Override
+  public String toString() {
+    return stringRepresentation;
+  }
+
+  /**
+   * Returns true if specified value matches this pattern.
+   */
+  public boolean match(String value) {
+    value = StringUtils.removeStart(value, "/");
+    value = StringUtils.removeEnd(value, "/");
+    return pattern.matcher(value).matches();
+  }
+
+  /**
+   * Returns true if specified value matches one of specified patterns.
+   * 
+   * @since 2.4
+   */
+  public static boolean match(WildcardPattern[] patterns, String value) {
+    for (WildcardPattern pattern : patterns) {
+      if (pattern.match(value)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Creates pattern with "/" as a directory separator.
+   * 
+   * @see #create(String, String)
+   */
+  public static WildcardPattern create(String pattern) {
+    return create(pattern, "/");
+  }
+
+  /**
+   * Creates array of patterns with "/" as a directory separator.
+   * 
+   * @see #create(String, String)
+   */
+  public static WildcardPattern[] create(String[] patterns) {
+    if (patterns == null) {
+      return new WildcardPattern[0];
+    }
+    WildcardPattern[] exclusionPAtterns = new WildcardPattern[patterns.length];
+    for (int i = 0; i < patterns.length; i++) {
+      exclusionPAtterns[i] = create(patterns[i]);
+    }
+    return exclusionPAtterns;
+  }
+
+  /**
+   * Creates pattern with specified separator for directories.
+   * <p>
+   * This is used to match Java-classes, i.e. <code>org.foo.Bar</code> against <code>org/**</code>.
+   * <b>However usage of character other than "/" as a directory separator is misleading and should be avoided,
+   * so method {@link #create(String)} is preferred over this one.</b>
+   * </p>
+   * <p>
+   * Also note that no matter whether forward or backward slashes were used in the <code>antPattern</code>
+   * the returned pattern will use <code>directorySeparator</code>.
+   * Thus to match Windows-style path "dir\file.ext" against pattern "dir/file.ext" normalization should be performed.
+   * </p>
+   */
+  public static WildcardPattern create(String pattern, String directorySeparator) {
+    String key = pattern + directorySeparator;
+    WildcardPattern wildcardPattern = CACHE.get(key);
+    if (wildcardPattern == null) {
+      wildcardPattern = new WildcardPattern(pattern, directorySeparator);
+      CACHE.put(key, wildcardPattern);
+    }
+    return wildcardPattern;
+  }
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/internal/package-info.java
new file mode 100644 (file)
index 0000000..9870b99
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.batch.api.internal;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/languages/Language.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/languages/Language.java
new file mode 100644 (file)
index 0000000..7dd6c8b
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.languages;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+public final class Language {
+
+  private final String key, name;
+  private final String[] fileSuffixes;
+
+  public Language(String key, String name, String... fileSuffixes) {
+    this.key = key;
+    this.name = name;
+    this.fileSuffixes = fileSuffixes;
+  }
+
+  /**
+   * For example "java".
+   */
+  public String key() {
+    return key;
+  }
+
+  /**
+   * For example "Java"
+   */
+  public String name() {
+    return name;
+  }
+
+  /**
+   * For example ["jav", "java"].
+   */
+  public Collection<String> fileSuffixes() {
+    return Arrays.asList(fileSuffixes);
+  }
+
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/languages/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/languages/package-info.java
new file mode 100644 (file)
index 0000000..a36d1c1
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.batch.api.languages;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/measures/Metric.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/measures/Metric.java
new file mode 100644 (file)
index 0000000..52dc17c
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.measures;
+
+import java.io.Serializable;
+
+public interface Metric<G extends Serializable> {
+
+  Class<G> type();
+
+  String key();
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/measures/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/measures/package-info.java
new file mode 100644 (file)
index 0000000..e684b54
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.batch.api.measures;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/rules/QProfile.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/rules/QProfile.java
new file mode 100644 (file)
index 0000000..1d074e1
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.rules;
+
+public class QProfile {
+  private final String name, language;
+  private final Integer version;
+
+  public QProfile(String name, String language, Integer version) {
+    this.name = name;
+    this.language = language;
+    this.version = version;
+  }
+
+  public String name() {
+    return name;
+  }
+
+  public String language() {
+    return language;
+  }
+
+  public Integer version() {
+    return version;
+  }
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/rules/RuleKey.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/rules/RuleKey.java
new file mode 100644 (file)
index 0000000..3af1337
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.api.rules;
+
+import java.io.Serializable;
+
+/**
+ * Key of a rule. Unique among all the rule repositories.
+ *
+ * @since 3.6
+ */
+public class RuleKey implements Serializable {
+  private final String repository, rule;
+
+  protected RuleKey(String repositoryKey, String ruleKey) {
+    this.repository = repositoryKey;
+    this.rule = ruleKey;
+  }
+
+  /**
+   * Create a key. Parameters are NOT null.
+   */
+  public static RuleKey of(String repository, String rule) {
+    return new RuleKey(repository, rule);
+  }
+
+  /**
+   * Never null
+   */
+  public String repository() {
+    return repository;
+  }
+
+  /**
+   * Never null
+   */
+  public String rule() {
+    return rule;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    RuleKey ruleKey = (RuleKey) o;
+    if (!repository.equals(ruleKey.repository)) {
+      return false;
+    }
+    if (!rule.equals(ruleKey.rule)) {
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = repository.hashCode();
+    result = 31 * result + rule.hashCode();
+    return result;
+  }
+
+  /**
+   * Format is "repository:rule", for example "squid:AvoidCycle"
+   */
+  @Override
+  public String toString() {
+    return String.format("%s:%s", repository, rule);
+  }
+}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/rules/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/api/batch/rules/package-info.java
new file mode 100644 (file)
index 0000000..d91eb34
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.batch.api.rules;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/BatchComponent.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/BatchComponent.java
deleted file mode 100644 (file)
index d48e225..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api;
-
-/**
- * Dependency Injection : all the classes implementing this interface are available in the batch IoC container.
- * Just add a parameter to the constructor of your component.
- *
- * @since 4.4
- */
-public interface BatchComponent {
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/BatchExtension.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/BatchExtension.java
deleted file mode 100644 (file)
index 1a774a1..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api;
-
-
-/**
- * Batch extension point.
- *
- * @since 4.4
- */
-public interface BatchExtension extends BatchComponent {
-
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/InstantiationStrategy.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/InstantiationStrategy.java
deleted file mode 100644 (file)
index 521c6dd..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Define instantiation strategy of batch extensions. If an extension is not annotated, then default value
- * is {@link #PER_PROJECT}.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface InstantiationStrategy {
-
-  /**
-   * Shared extension. Lifecycle is the full analysis.
-   */
-  String PER_BATCH = "PER_BATCH";
-
-  /**
-   * Created and initialized for each project and sub-project (a project is a module in Maven terminology).
-   */
-  String PER_PROJECT = "PER_PROJECT";
-
-  String value();
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/Analyzer.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/Analyzer.java
deleted file mode 100644 (file)
index 6123545..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.analyzer;
-
-import org.sonar.batch.api.BatchExtension;
-
-/**
- * <p>
- * An Analyzer is invoked once during the analysis of a project. The analyzer can parse a flat file, connect to a web server... Analyzers are
- * used to add measure and issues at file level.
- * </p>
- *
- * <p>
- * For example the Cobertura Analyzer parses Cobertura report and saves the first-level of measures on files.
- * </p>
- *
- * @since 4.4
- */
-public interface Analyzer extends BatchExtension {
-
-  /**
-   * Describe what this analyzer is doing.
-   * @return
-   */
-  AnalyzerDescriptor describe();
-
-  /**
-   * The method that is going to be run when the analyzer is called
-   *
-   * @param context the context
-   */
-  void analyse(AnalyzerContext context);
-
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/AnalyzerContext.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/AnalyzerContext.java
deleted file mode 100644 (file)
index e29dfaf..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.analyzer;
-
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.batch.api.analyzer.issue.AnalyzerIssue;
-import org.sonar.batch.api.analyzer.measure.AnalyzerMeasure;
-import org.sonar.batch.api.measures.Metric;
-
-import javax.annotation.CheckForNull;
-
-import java.io.Serializable;
-import java.util.Collection;
-
-/**
- * @since 4.4
- */
-public interface AnalyzerContext {
-
-  // ----------- MEASURES --------------
-
-  /**
-   * Find a project measure.
-   */
-  @CheckForNull
-  AnalyzerMeasure<?> getMeasure(String metricKey);
-
-  /**
-   * Find a project measure.
-   */
-  @CheckForNull
-  <G extends Serializable> AnalyzerMeasure<G> getMeasure(Metric<G> metric);
-
-  /**
-   * Find a file measure.
-   */
-  @CheckForNull
-  AnalyzerMeasure<?> getMeasure(InputFile file, String metricKey);
-
-  /**
-   * Find a file measure.
-   */
-  @CheckForNull
-  <G extends Serializable> AnalyzerMeasure<G> getMeasure(InputFile file, Metric<G> metric);
-
-  /**
-   * Add a measure.
-   */
-  void addMeasure(AnalyzerMeasure<?> measure);
-
-  // ----------- ISSUES --------------
-
-  /**
-   * Add an issue.
-   */
-  void addIssue(AnalyzerIssue issue);
-
-  /**
-   * Add a list of issues.
-   */
-  void addIssues(Collection<AnalyzerIssue> issues);
-
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/AnalyzerDescriptor.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/AnalyzerDescriptor.java
deleted file mode 100644 (file)
index 0b97200..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.analyzer;
-
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.batch.api.measures.Metric;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-public class AnalyzerDescriptor {
-
-  private final String name;
-  private final Metric<?>[] dependsOn;
-  private final Metric<?>[] provides;
-  private final String[] languages;
-  private final InputFile.Type[] types;
-
-  private AnalyzerDescriptor(Builder builder) {
-    this.name = builder.name;
-    this.dependsOn = builder.dependsOn != null ? builder.dependsOn : new Metric<?>[0];
-    this.provides = builder.provides != null ? builder.provides : new Metric<?>[0];
-    this.languages = builder.languages != null ? builder.languages : new String[0];
-    this.types = builder.types;
-  }
-
-  public String name() {
-    return name;
-  }
-
-  public Metric<?>[] dependsOn() {
-    return dependsOn;
-  }
-
-  public Metric<?>[] provides() {
-    return provides;
-  }
-
-  public Collection<String> languages() {
-    return Arrays.asList(languages);
-  }
-
-  public InputFile.Type[] types() {
-    return types;
-  }
-
-  public static Builder builder() {
-    return new Builder();
-  }
-
-  public static class Builder {
-
-    private String name;
-    private Metric<?>[] dependsOn;
-    private Metric<?>[] provides;
-    private String[] languages;
-    private InputFile.Type[] types;
-
-    public Builder name(String name) {
-      this.name = name;
-      return this;
-    }
-
-    public Builder dependsOn(Metric<?>... metrics) {
-      this.dependsOn = metrics;
-      return this;
-    }
-
-    public Builder provides(Metric<?>... metrics) {
-      this.provides = metrics;
-      return this;
-    }
-
-    public Builder runOnLanguages(String... languageKeys) {
-      this.languages = languageKeys;
-      return this;
-    }
-
-    public Builder runOnTypes(InputFile.Type... types) {
-      this.types = types;
-      return this;
-    }
-
-    public AnalyzerDescriptor build() {
-      return new AnalyzerDescriptor(this);
-    }
-
-  }
-
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/issue/AnalyzerIssue.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/issue/AnalyzerIssue.java
deleted file mode 100644 (file)
index f39d884..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.analyzer.issue;
-
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.batch.api.analyzer.Analyzer;
-import org.sonar.batch.api.internal.Preconditions;
-import org.sonar.batch.api.rules.RuleKey;
-
-import javax.annotation.Nullable;
-
-/**
- * Issue reported by an {@link Analyzer}
- *
- * @since 4.4
- */
-public class AnalyzerIssue {
-
-  private final InputFile inputFile;
-  private final RuleKey ruleKey;
-  private final String message;
-  private final Integer line;
-  private final Double effortToFix;
-
-  private AnalyzerIssue(Builder builder) {
-    this.inputFile = builder.file;
-    this.ruleKey = builder.ruleKey;
-    this.message = builder.message;
-    this.line = builder.line;
-    this.effortToFix = builder.effortToFix;
-  }
-
-  public static Builder builder() {
-    return new Builder();
-  }
-
-  @Nullable
-  public InputFile inputFile() {
-    return inputFile;
-  }
-
-  public RuleKey ruleKey() {
-    return ruleKey;
-  }
-
-  public String message() {
-    return message;
-  }
-
-  public Integer line() {
-    return line;
-  }
-
-  @Nullable
-  public Double effortToFix() {
-    return effortToFix;
-  }
-
-  public static class Builder {
-
-    private Boolean onProject = null;
-    private InputFile file;
-    private RuleKey ruleKey;
-    private String message;
-    private Integer line;
-    private Double effortToFix;
-
-    public AnalyzerIssue build() {
-      return new AnalyzerIssue(this);
-    }
-
-    public Builder ruleKey(RuleKey ruleKey) {
-      this.ruleKey = ruleKey;
-      return this;
-    }
-
-    public Builder onFile(InputFile file) {
-      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
-      Preconditions.checkNotNull(file, "InputFile should be non null");
-      this.file = file;
-      this.onProject = false;
-      return this;
-    }
-
-    public Builder onProject() {
-      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
-      this.file = null;
-      this.onProject = true;
-      return this;
-    }
-
-    public Builder atLine(int line) {
-      this.line = line;
-      return this;
-    }
-
-    public Builder effortToFix(@Nullable Double effortToFix) {
-      this.effortToFix = effortToFix;
-      return this;
-    }
-
-    public Builder message(String message) {
-      this.message = message;
-      return this;
-    }
-
-  }
-
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/issue/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/issue/package-info.java
deleted file mode 100644 (file)
index 70a6600..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.batch.api.analyzer.issue;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/measure/AnalyzerMeasure.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/measure/AnalyzerMeasure.java
deleted file mode 100644 (file)
index 3d74dca..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.analyzer.measure;
-
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.batch.api.internal.Preconditions;
-import org.sonar.batch.api.measures.Metric;
-
-import javax.annotation.Nullable;
-
-import java.io.Serializable;
-
-public class AnalyzerMeasure<G extends Serializable> implements Serializable {
-
-  private final InputFile inputFile;
-  private final String metricKey;
-  private final G value;
-
-  private AnalyzerMeasure(Builder<G> builder) {
-    Preconditions.checkNotNull(builder.value, "Measure value can't be null");
-    Preconditions.checkNotNull(builder.metricKey, "Measure metricKey can't be null");
-    this.inputFile = builder.file;
-    this.metricKey = builder.metricKey;
-    this.value = builder.value;
-  }
-
-  @Nullable
-  public InputFile inputFile() {
-    return inputFile;
-  }
-
-  public String metricKey() {
-    return metricKey;
-  }
-
-  public Serializable value() {
-    return value;
-  }
-
-  public static <G extends Serializable> Builder<G> builder() {
-    return new Builder<G>();
-  }
-
-  public static class Builder<G extends Serializable> {
-
-    private Boolean onProject = null;
-    private InputFile file;
-    private String metricKey;
-    private G value;
-
-    public Builder<G> onFile(InputFile file) {
-      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
-      Preconditions.checkNotNull(file, "InputFile should be non null");
-      this.file = file;
-      this.onProject = false;
-      return this;
-    }
-
-    public Builder<G> onProject() {
-      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
-      this.file = null;
-      this.onProject = true;
-      return this;
-    }
-
-    private Builder<G> metricKey(String metricKey) {
-      Preconditions.checkState(metricKey != null, "Metric already defined");
-      this.metricKey = metricKey;
-      return this;
-    }
-
-    public Builder<G> forMetric(Metric<G> metric) {
-      return metricKey(metric.key());
-    }
-
-    public Builder<G> withValue(G value) {
-      Preconditions.checkState(value != null, "Measure value already defined");
-      Preconditions.checkNotNull(value, "Measure value can't be null");
-      this.value = value;
-      return this;
-    }
-
-    public AnalyzerMeasure<G> build() {
-      return new AnalyzerMeasure<G>(this);
-    }
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (!(obj instanceof AnalyzerMeasure)) {
-      return false;
-    }
-    AnalyzerMeasure<?> other = (AnalyzerMeasure<?>) obj;
-    return metricKey.equals(other.metricKey)
-      && value.equals(other.value)
-      && (inputFile == null ? other.inputFile == null : inputFile.equals(other.inputFile));
-  }
-
-  @Override
-  public int hashCode() {
-    return metricKey.hashCode()
-      + value.hashCode()
-      + (inputFile != null ? inputFile.hashCode() : 0);
-  }
-
-  @Override
-  public String toString() {
-    return "AnalyzerMeasure[" + (inputFile != null ? "inputFile=" + inputFile.toString() : "onProject")
-      + ",metricKey=" + metricKey + ",value=" + value + "]";
-  }
-
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/measure/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/measure/package-info.java
deleted file mode 100644 (file)
index b490662..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.batch.api.analyzer.measure;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/analyzer/package-info.java
deleted file mode 100644 (file)
index 5b72f8c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.batch.api.analyzer;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/FilenameUtils.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/FilenameUtils.java
deleted file mode 100644 (file)
index 0461255..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.internal;
-
-import java.io.File;
-
-/**
- * Copied from commons io
- *
- */
-public class FilenameUtils {
-
-  public static final char EXTENSION_SEPARATOR = '.';
-
-  private static final char UNIX_SEPARATOR = '/';
-
-  /**
-   * The Windows separator character.
-   */
-  private static final char WINDOWS_SEPARATOR = '\\';
-
-  /**
-   * The system separator character.
-   */
-  private static final char SYSTEM_SEPARATOR = File.separatorChar;
-
-  /**
-   * The separator character that is the opposite of the system separator.
-   */
-  private static final char OTHER_SEPARATOR;
-  static {
-    if (isSystemWindows()) {
-      OTHER_SEPARATOR = UNIX_SEPARATOR;
-    } else {
-      OTHER_SEPARATOR = WINDOWS_SEPARATOR;
-    }
-  }
-
-  static boolean isSystemWindows() {
-    return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR;
-  }
-
-  public static String normalize(String filename) {
-    return doNormalize(filename, UNIX_SEPARATOR, true);
-  }
-
-  private static String doNormalize(String filename, char separator, boolean keepSeparator) {
-    if (filename == null) {
-      return null;
-    }
-    int size = filename.length();
-    if (size == 0) {
-      return filename;
-    }
-    int prefix = getPrefixLength(filename);
-    if (prefix < 0) {
-      return null;
-    }
-
-    char[] array = new char[size + 2]; // +1 for possible extra slash, +2 for arraycopy
-    filename.getChars(0, filename.length(), array, 0);
-
-    // fix separators throughout
-    char otherSeparator = separator == SYSTEM_SEPARATOR ? OTHER_SEPARATOR : SYSTEM_SEPARATOR;
-    for (int i = 0; i < array.length; i++) {
-      if (array[i] == otherSeparator) {
-        array[i] = separator;
-      }
-    }
-
-    // add extra separator on the end to simplify code below
-    boolean lastIsDirectory = true;
-    if (array[size - 1] != separator) {
-      array[size++] = separator;
-      lastIsDirectory = false;
-    }
-
-    // adjoining slashes
-    for (int i = prefix + 1; i < size; i++) {
-      if (array[i] == separator && array[i - 1] == separator) {
-        System.arraycopy(array, i, array, i - 1, size - i);
-        size--;
-        i--;
-      }
-    }
-
-    // dot slash
-    for (int i = prefix + 1; i < size; i++) {
-      if (array[i] == separator && array[i - 1] == '.' &&
-        (i == prefix + 1 || array[i - 2] == separator)) {
-        if (i == size - 1) {
-          lastIsDirectory = true;
-        }
-        System.arraycopy(array, i + 1, array, i - 1, size - i);
-        size -= 2;
-        i--;
-      }
-    }
-
-    // double dot slash
-    outer: for (int i = prefix + 2; i < size; i++) {
-      if (array[i] == separator && array[i - 1] == '.' && array[i - 2] == '.' &&
-        (i == prefix + 2 || array[i - 3] == separator)) {
-        if (i == prefix + 2) {
-          return null;
-        }
-        if (i == size - 1) {
-          lastIsDirectory = true;
-        }
-        int j;
-        for (j = i - 4; j >= prefix; j--) {
-          if (array[j] == separator) {
-            // remove b/../ from a/b/../c
-            System.arraycopy(array, i + 1, array, j + 1, size - i);
-            size -= i - j;
-            i = j + 1;
-            continue outer;
-          }
-        }
-        // remove a/../ from a/../c
-        System.arraycopy(array, i + 1, array, prefix, size - i);
-        size -= i + 1 - prefix;
-        i = prefix + 1;
-      }
-    }
-
-    if (size <= 0) { // should never be less than 0
-      return "";
-    }
-    if (size <= prefix) { // should never be less than prefix
-      return new String(array, 0, size);
-    }
-    if (lastIsDirectory && keepSeparator) {
-      return new String(array, 0, size); // keep trailing separator
-    }
-    return new String(array, 0, size - 1); // lose trailing separator
-  }
-
-  public static int getPrefixLength(String filename) {
-    if (filename == null) {
-      return -1;
-    }
-    int len = filename.length();
-    if (len == 0) {
-      return 0;
-    }
-    char ch0 = filename.charAt(0);
-    if (ch0 == ':') {
-      return -1;
-    }
-    if (len == 1) {
-      if (ch0 == '~') {
-        return 2; // return a length greater than the input
-      }
-      return isSeparator(ch0) ? 1 : 0;
-    } else {
-      if (ch0 == '~') {
-        int posUnix = filename.indexOf(UNIX_SEPARATOR, 1);
-        int posWin = filename.indexOf(WINDOWS_SEPARATOR, 1);
-        if (posUnix == -1 && posWin == -1) {
-          return len + 1; // return a length greater than the input
-        }
-        posUnix = posUnix == -1 ? posWin : posUnix;
-        posWin = posWin == -1 ? posUnix : posWin;
-        return Math.min(posUnix, posWin) + 1;
-      }
-      char ch1 = filename.charAt(1);
-      if (ch1 == ':') {
-        ch0 = Character.toUpperCase(ch0);
-        if (ch0 >= 'A' && ch0 <= 'Z') {
-          if (len == 2 || isSeparator(filename.charAt(2)) == false) {
-            return 2;
-          }
-          return 3;
-        }
-        return -1;
-
-      } else if (isSeparator(ch0) && isSeparator(ch1)) {
-        int posUnix = filename.indexOf(UNIX_SEPARATOR, 2);
-        int posWin = filename.indexOf(WINDOWS_SEPARATOR, 2);
-        if (posUnix == -1 && posWin == -1 || posUnix == 2 || posWin == 2) {
-          return -1;
-        }
-        posUnix = posUnix == -1 ? posWin : posUnix;
-        posWin = posWin == -1 ? posUnix : posWin;
-        return Math.min(posUnix, posWin) + 1;
-      } else {
-        return isSeparator(ch0) ? 1 : 0;
-      }
-    }
-  }
-
-  private static boolean isSeparator(char ch) {
-    return ch == UNIX_SEPARATOR || ch == WINDOWS_SEPARATOR;
-  }
-
-  public static String getExtension(String filename) {
-    if (filename == null) {
-      return null;
-    }
-    int index = indexOfExtension(filename);
-    if (index == -1) {
-      return "";
-    } else {
-      return filename.substring(index + 1);
-    }
-  }
-
-  public static int indexOfExtension(String filename) {
-    if (filename == null) {
-      return -1;
-    }
-    int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
-    int lastSeparator = indexOfLastSeparator(filename);
-    return lastSeparator > extensionPos ? -1 : extensionPos;
-  }
-
-  public static int indexOfLastSeparator(String filename) {
-    if (filename == null) {
-      return -1;
-    }
-    int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
-    int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
-    return Math.max(lastUnixPos, lastWindowsPos);
-  }
-
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/Preconditions.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/Preconditions.java
deleted file mode 100644 (file)
index 75ac73f..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.internal;
-
-import javax.annotation.Nullable;
-
-/**
- * Copied from Guava
- */
-public final class Preconditions {
-  private Preconditions() {
-  }
-
-  /**
-   * Ensures the truth of an expression involving one or more parameters to the
-   * calling method.
-   *
-   * @param expression a boolean expression
-   * @throws IllegalArgumentException if {@code expression} is false
-   */
-  public static void checkArgument(boolean expression) {
-    if (!expression) {
-      throw new IllegalArgumentException();
-    }
-  }
-
-  /**
-   * Ensures the truth of an expression involving one or more parameters to the
-   * calling method.
-   *
-   * @param expression a boolean expression
-   * @param errorMessage the exception message to use if the check fails; will
-   *     be converted to a string using {@link String#valueOf(Object)}
-   * @throws IllegalArgumentException if {@code expression} is false
-   */
-  public static void checkArgument(
-    boolean expression, @Nullable Object errorMessage) {
-    if (!expression) {
-      throw new IllegalArgumentException(String.valueOf(errorMessage));
-    }
-  }
-
-  /**
-   * Ensures the truth of an expression involving one or more parameters to the
-   * calling method.
-   *
-   * @param expression a boolean expression
-   * @param errorMessageTemplate a template for the exception message should the
-   *     check fail. The message is formed by replacing each {@code %s}
-   *     placeholder in the template with an argument. These are matched by
-   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
-   *     Unmatched arguments will be appended to the formatted message in square
-   *     braces. Unmatched placeholders will be left as-is.
-   * @param errorMessageArgs the arguments to be substituted into the message
-   *     template. Arguments are converted to strings using
-   *     {@link String#valueOf(Object)}.
-   * @throws IllegalArgumentException if {@code expression} is false
-   * @throws NullPointerException if the check fails and either {@code
-   *     errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
-   *     this happen)
-   */
-  public static void checkArgument(boolean expression,
-    @Nullable String errorMessageTemplate,
-    @Nullable Object... errorMessageArgs) {
-    if (!expression) {
-      throw new IllegalArgumentException(
-        format(errorMessageTemplate, errorMessageArgs));
-    }
-  }
-
-  /**
-   * Ensures the truth of an expression involving the state of the calling
-   * instance, but not involving any parameters to the calling method.
-   *
-   * @param expression a boolean expression
-   * @throws IllegalStateException if {@code expression} is false
-   */
-  public static void checkState(boolean expression) {
-    if (!expression) {
-      throw new IllegalStateException();
-    }
-  }
-
-  /**
-   * Ensures the truth of an expression involving the state of the calling
-   * instance, but not involving any parameters to the calling method.
-   *
-   * @param expression a boolean expression
-   * @param errorMessage the exception message to use if the check fails; will
-   *     be converted to a string using {@link String#valueOf(Object)}
-   * @throws IllegalStateException if {@code expression} is false
-   */
-  public static void checkState(
-    boolean expression, @Nullable Object errorMessage) {
-    if (!expression) {
-      throw new IllegalStateException(String.valueOf(errorMessage));
-    }
-  }
-
-  /**
-   * Ensures the truth of an expression involving the state of the calling
-   * instance, but not involving any parameters to the calling method.
-   *
-   * @param expression a boolean expression
-   * @param errorMessageTemplate a template for the exception message should the
-   *     check fail. The message is formed by replacing each {@code %s}
-   *     placeholder in the template with an argument. These are matched by
-   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
-   *     Unmatched arguments will be appended to the formatted message in square
-   *     braces. Unmatched placeholders will be left as-is.
-   * @param errorMessageArgs the arguments to be substituted into the message
-   *     template. Arguments are converted to strings using
-   *     {@link String#valueOf(Object)}.
-   * @throws IllegalStateException if {@code expression} is false
-   * @throws NullPointerException if the check fails and either {@code
-   *     errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
-   *     this happen)
-   */
-  public static void checkState(boolean expression,
-    @Nullable String errorMessageTemplate,
-    @Nullable Object... errorMessageArgs) {
-    if (!expression) {
-      throw new IllegalStateException(
-        format(errorMessageTemplate, errorMessageArgs));
-    }
-  }
-
-  /**
-   * Ensures that an object reference passed as a parameter to the calling
-   * method is not null.
-   *
-   * @param reference an object reference
-   * @return the non-null reference that was validated
-   * @throws NullPointerException if {@code reference} is null
-   */
-  public static <T> T checkNotNull(T reference) {
-    if (reference == null) {
-      throw new NullPointerException();
-    }
-    return reference;
-  }
-
-  /**
-   * Ensures that an object reference passed as a parameter to the calling
-   * method is not null.
-   *
-   * @param reference an object reference
-   * @param errorMessage the exception message to use if the check fails; will
-   *     be converted to a string using {@link String#valueOf(Object)}
-   * @return the non-null reference that was validated
-   * @throws NullPointerException if {@code reference} is null
-   */
-  public static <T> T checkNotNull(T reference, @Nullable Object errorMessage) {
-    if (reference == null) {
-      throw new NullPointerException(String.valueOf(errorMessage));
-    }
-    return reference;
-  }
-
-  /**
-   * Ensures that an object reference passed as a parameter to the calling
-   * method is not null.
-   *
-   * @param reference an object reference
-   * @param errorMessageTemplate a template for the exception message should the
-   *     check fail. The message is formed by replacing each {@code %s}
-   *     placeholder in the template with an argument. These are matched by
-   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
-   *     Unmatched arguments will be appended to the formatted message in square
-   *     braces. Unmatched placeholders will be left as-is.
-   * @param errorMessageArgs the arguments to be substituted into the message
-   *     template. Arguments are converted to strings using
-   *     {@link String#valueOf(Object)}.
-   * @return the non-null reference that was validated
-   * @throws NullPointerException if {@code reference} is null
-   */
-  public static <T> T checkNotNull(T reference,
-    @Nullable String errorMessageTemplate,
-    @Nullable Object... errorMessageArgs) {
-    if (reference == null) {
-      // If either of these parameters is null, the right thing happens anyway
-      throw new NullPointerException(
-        format(errorMessageTemplate, errorMessageArgs));
-    }
-    return reference;
-  }
-
-  /*
-   * All recent hotspots (as of 2009) *really* like to have the natural code
-   * 
-   * if (guardExpression) {
-   * throw new BadException(messageExpression);
-   * }
-   * 
-   * refactored so that messageExpression is moved to a separate
-   * String-returning method.
-   * 
-   * if (guardExpression) {
-   * throw new BadException(badMsg(...));
-   * }
-   * 
-   * The alternative natural refactorings into void or Exception-returning
-   * methods are much slower. This is a big deal - we're talking factors of
-   * 2-8 in microbenchmarks, not just 10-20%. (This is a hotspot optimizer
-   * bug, which should be fixed, but that's a separate, big project).
-   * 
-   * The coding pattern above is heavily used in java.util, e.g. in ArrayList.
-   * There is a RangeCheckMicroBenchmark in the JDK that was used to test this.
-   * 
-   * But the methods in this class want to throw different exceptions,
-   * depending on the args, so it appears that this pattern is not directly
-   * applicable. But we can use the ridiculous, devious trick of throwing an
-   * exception in the middle of the construction of another exception.
-   * Hotspot is fine with that.
-   */
-
-  /**
-   * Ensures that {@code index} specifies a valid <i>element</i> in an array,
-   * list or string of size {@code size}. An element index may range from zero,
-   * inclusive, to {@code size}, exclusive.
-   *
-   * @param index a user-supplied index identifying an element of an array, list
-   *     or string
-   * @param size the size of that array, list or string
-   * @return the value of {@code index}
-   * @throws IndexOutOfBoundsException if {@code index} is negative or is not
-   *     less than {@code size}
-   * @throws IllegalArgumentException if {@code size} is negative
-   */
-  public static int checkElementIndex(int index, int size) {
-    return checkElementIndex(index, size, "index");
-  }
-
-  /**
-   * Ensures that {@code index} specifies a valid <i>element</i> in an array,
-   * list or string of size {@code size}. An element index may range from zero,
-   * inclusive, to {@code size}, exclusive.
-   *
-   * @param index a user-supplied index identifying an element of an array, list
-   *     or string
-   * @param size the size of that array, list or string
-   * @param desc the text to use to describe this index in an error message
-   * @return the value of {@code index}
-   * @throws IndexOutOfBoundsException if {@code index} is negative or is not
-   *     less than {@code size}
-   * @throws IllegalArgumentException if {@code size} is negative
-   */
-  public static int checkElementIndex(
-    int index, int size, @Nullable String desc) {
-    // Carefully optimized for execution by hotspot (explanatory comment above)
-    if (index < 0 || index >= size) {
-      throw new IndexOutOfBoundsException(badElementIndex(index, size, desc));
-    }
-    return index;
-  }
-
-  private static String badElementIndex(int index, int size, String desc) {
-    if (index < 0) {
-      return format("%s (%s) must not be negative", desc, index);
-    } else if (size < 0) {
-      throw new IllegalArgumentException("negative size: " + size);
-    } else { // index >= size
-      return format("%s (%s) must be less than size (%s)", desc, index, size);
-    }
-  }
-
-  /**
-   * Ensures that {@code index} specifies a valid <i>position</i> in an array,
-   * list or string of size {@code size}. A position index may range from zero
-   * to {@code size}, inclusive.
-   *
-   * @param index a user-supplied index identifying a position in an array, list
-   *     or string
-   * @param size the size of that array, list or string
-   * @return the value of {@code index}
-   * @throws IndexOutOfBoundsException if {@code index} is negative or is
-   *     greater than {@code size}
-   * @throws IllegalArgumentException if {@code size} is negative
-   */
-  public static int checkPositionIndex(int index, int size) {
-    return checkPositionIndex(index, size, "index");
-  }
-
-  /**
-   * Ensures that {@code index} specifies a valid <i>position</i> in an array,
-   * list or string of size {@code size}. A position index may range from zero
-   * to {@code size}, inclusive.
-   *
-   * @param index a user-supplied index identifying a position in an array, list
-   *     or string
-   * @param size the size of that array, list or string
-   * @param desc the text to use to describe this index in an error message
-   * @return the value of {@code index}
-   * @throws IndexOutOfBoundsException if {@code index} is negative or is
-   *     greater than {@code size}
-   * @throws IllegalArgumentException if {@code size} is negative
-   */
-  public static int checkPositionIndex(
-    int index, int size, @Nullable String desc) {
-    // Carefully optimized for execution by hotspot (explanatory comment above)
-    if (index < 0 || index > size) {
-      throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc));
-    }
-    return index;
-  }
-
-  private static String badPositionIndex(int index, int size, String desc) {
-    if (index < 0) {
-      return format("%s (%s) must not be negative", desc, index);
-    } else if (size < 0) {
-      throw new IllegalArgumentException("negative size: " + size);
-    } else { // index > size
-      return format("%s (%s) must not be greater than size (%s)",
-        desc, index, size);
-    }
-  }
-
-  /**
-   * Ensures that {@code start} and {@code end} specify a valid <i>positions</i>
-   * in an array, list or string of size {@code size}, and are in order. A
-   * position index may range from zero to {@code size}, inclusive.
-   *
-   * @param start a user-supplied index identifying a starting position in an
-   *     array, list or string
-   * @param end a user-supplied index identifying a ending position in an array,
-   *     list or string
-   * @param size the size of that array, list or string
-   * @throws IndexOutOfBoundsException if either index is negative or is
-   *     greater than {@code size}, or if {@code end} is less than {@code start}
-   * @throws IllegalArgumentException if {@code size} is negative
-   */
-  public static void checkPositionIndexes(int start, int end, int size) {
-    // Carefully optimized for execution by hotspot (explanatory comment above)
-    if (start < 0 || end < start || end > size) {
-      throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
-    }
-  }
-
-  private static String badPositionIndexes(int start, int end, int size) {
-    if (start < 0 || start > size) {
-      return badPositionIndex(start, size, "start index");
-    }
-    if (end < 0 || end > size) {
-      return badPositionIndex(end, size, "end index");
-    }
-    // end < start
-    return format("end index (%s) must not be less than start index (%s)",
-      end, start);
-  }
-
-  /**
-   * Substitutes each {@code %s} in {@code template} with an argument. These
-   * are matched by position - the first {@code %s} gets {@code args[0]}, etc.
-   * If there are more arguments than placeholders, the unmatched arguments will
-   * be appended to the end of the formatted message in square braces.
-   *
-   * @param template a non-null string containing 0 or more {@code %s}
-   *     placeholders.
-   * @param args the arguments to be substituted into the message
-   *     template. Arguments are converted to strings using
-   *     {@link String#valueOf(Object)}. Arguments can be null.
-   */
-  static String format(String template,
-    @Nullable Object... args) {
-    template = String.valueOf(template); // null -> "null"
-
-    // start substituting the arguments into the '%s' placeholders
-    StringBuilder builder = new StringBuilder(
-      template.length() + 16 * args.length);
-    int templateStart = 0;
-    int i = 0;
-    while (i < args.length) {
-      int placeholderStart = template.indexOf("%s", templateStart);
-      if (placeholderStart == -1) {
-        break;
-      }
-      builder.append(template.substring(templateStart, placeholderStart));
-      builder.append(args[i++]);
-      templateStart = placeholderStart + 2;
-    }
-    builder.append(template.substring(templateStart));
-
-    // if we run out of placeholders, append the extra args in square braces
-    if (i < args.length) {
-      builder.append(" [");
-      builder.append(args[i++]);
-      while (i < args.length) {
-        builder.append(", ");
-        builder.append(args[i++]);
-      }
-      builder.append(']');
-    }
-
-    return builder.toString();
-  }
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/StringUtils.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/StringUtils.java
deleted file mode 100644 (file)
index ab279ae..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.internal;
-
-/**
- * Copied from commons lang
- */
-public class StringUtils {
-
-  public static final String EMPTY = "";
-
-  public static String trim(String str) {
-    return str == null ? null : str.trim();
-  }
-
-  public static String removeStart(String str, String remove) {
-    if (isEmpty(str) || isEmpty(remove)) {
-      return str;
-    }
-    if (str.startsWith(remove)) {
-      return str.substring(remove.length());
-    }
-    return str;
-  }
-
-  public static String removeEnd(String str, String remove) {
-    if (isEmpty(str) || isEmpty(remove)) {
-      return str;
-    }
-    if (str.endsWith(remove)) {
-      return str.substring(0, str.length() - remove.length());
-    }
-    return str;
-  }
-
-  public static boolean isEmpty(String str) {
-    return str == null || str.length() == 0;
-  }
-
-  public static boolean startsWithIgnoreCase(String str, String prefix) {
-    return startsWith(str, prefix, true);
-  }
-
-  private static boolean startsWith(String str, String prefix, boolean ignoreCase) {
-    if (str == null || prefix == null) {
-      return (str == null && prefix == null);
-    }
-    if (prefix.length() > str.length()) {
-      return false;
-    }
-    return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
-  }
-
-  public static String substring(String str, int start) {
-    if (str == null) {
-      return null;
-    }
-
-    // handle negatives, which means last n characters
-    if (start < 0) {
-      start = str.length() + start; // remember start is negative
-    }
-
-    if (start < 0) {
-      start = 0;
-    }
-    if (start > str.length()) {
-      return EMPTY;
-    }
-
-    return str.substring(start);
-  }
-
-  public static boolean isBlank(String str) {
-    int strLen;
-    if (str == null || (strLen = str.length()) == 0) {
-      return true;
-    }
-    for (int i = 0; i < strLen; i++) {
-      if ((Character.isWhitespace(str.charAt(i)) == false)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  public static boolean isNotBlank(String str) {
-    return !StringUtils.isBlank(str);
-  }
-
-  public static String removeEndIgnoreCase(String str, String remove) {
-    if (isEmpty(str) || isEmpty(remove)) {
-      return str;
-    }
-    if (endsWithIgnoreCase(str, remove)) {
-      return str.substring(0, str.length() - remove.length());
-    }
-    return str;
-  }
-
-  public static boolean endsWithIgnoreCase(String str, String suffix) {
-    return endsWith(str, suffix, true);
-  }
-
-  private static boolean endsWith(String str, String suffix, boolean ignoreCase) {
-    if (str == null || suffix == null) {
-      return (str == null && suffix == null);
-    }
-    if (suffix.length() > str.length()) {
-      return false;
-    }
-    int strOffset = str.length() - suffix.length();
-    return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length());
-  }
-
-  public static String lowerCase(String str) {
-    if (str == null) {
-      return null;
-    }
-    return str.toLowerCase();
-  }
-
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/WildcardPattern.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/WildcardPattern.java
deleted file mode 100644 (file)
index f179fd7..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.internal;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * Implementation of Ant-style matching patterns.
- * Contrary to other implementations (like AntPathMatcher from Spring Framework) it is based on {@link Pattern Java Regular Expressions}.
- * To increase performance it holds an internal cache of all processed patterns.
- * <p>
- * Following rules are applied:
- * <ul>
- * <li>? matches single character</li>
- * <li>* matches zero or more characters</li>
- * <li>** matches zero or more 'directories'</li>
- * </ul>
- * </p>
- * <p>
- * Some examples of patterns:
- * <ul>
- * <li><code>org/T?st.java</code> - matches <code>org/Test.java</code> and also <code>org/Tost.java</code></li>
- * <li><code>org/*.java</code> - matches all <code>.java</code> files in the <code>org</code> directory,
- * e.g. <code>org/Foo.java</code> or <code>org/Bar.java</code></li>
- * <li><code>org/**</code> - matches all files underneath the <code>org</code> directory,
- * e.g. <code>org/Foo.java</code> or <code>org/foo/bar.jsp</code></li>
- * <li><code>org/&#42;&#42;/Test.java</code> - matches all <code>Test.java</code> files underneath the <code>org</code> directory,
- * e.g. <code>org/Test.java</code> or <code>org/foo/Test.java</code> or <code>org/foo/bar/Test.java</code></li>
- * <li><code>org/&#42;&#42;/*.java</code> - matches all <code>.java</code> files underneath the <code>org</code> directory,
- * e.g. <code>org/Foo.java</code> or <code>org/foo/Bar.java</code> or <code>org/foo/bar/Baz.java</code></li>
- * </ul>
- * </p>
- * <p>
- * Another implementation, which is also based on Java Regular Expressions, can be found in
- * <a href="https://github.com/JetBrains/intellij-community/blob/idea/107.743/platform/util/src/com/intellij/openapi/util/io/FileUtil.java#L847">FileUtil</a>
- * from IntelliJ OpenAPI.
- * </p>
- * 
- */
-public class WildcardPattern {
-
-  private static final Map<String, WildcardPattern> CACHE = new HashMap<String, WildcardPattern>();
-  private static final String SPECIAL_CHARS = "()[]^$.{}+|";
-
-  private Pattern pattern;
-  private String stringRepresentation;
-
-  protected WildcardPattern(String pattern, String directorySeparator) {
-    this.stringRepresentation = pattern;
-    this.pattern = Pattern.compile(toRegexp(pattern, directorySeparator));
-  }
-
-  private static String toRegexp(String antPattern, String directorySeparator) {
-    final String escapedDirectorySeparator = '\\' + directorySeparator;
-
-    final StringBuilder sb = new StringBuilder(antPattern.length());
-
-    sb.append('^');
-
-    int i = antPattern.startsWith("/") || antPattern.startsWith("\\") ? 1 : 0;
-    while (i < antPattern.length()) {
-      final char ch = antPattern.charAt(i);
-
-      if (SPECIAL_CHARS.indexOf(ch) != -1) {
-        // Escape regexp-specific characters
-        sb.append('\\').append(ch);
-      } else if (ch == '*') {
-        if (i + 1 < antPattern.length() && antPattern.charAt(i + 1) == '*') {
-          // Double asterisk
-          // Zero or more directories
-          if (i + 2 < antPattern.length() && isSlash(antPattern.charAt(i + 2))) {
-            sb.append("(?:.*").append(escapedDirectorySeparator).append("|)");
-            i += 2;
-          } else {
-            sb.append(".*");
-            i += 1;
-          }
-        } else {
-          // Single asterisk
-          // Zero or more characters excluding directory separator
-          sb.append("[^").append(escapedDirectorySeparator).append("]*?");
-        }
-      } else if (ch == '?') {
-        // Any single character excluding directory separator
-        sb.append("[^").append(escapedDirectorySeparator).append("]");
-      } else if (isSlash(ch)) {
-        // Directory separator
-        sb.append(escapedDirectorySeparator);
-      } else {
-        // Single character
-        sb.append(ch);
-      }
-
-      i++;
-    }
-
-    sb.append('$');
-
-    return sb.toString();
-  }
-
-  private static boolean isSlash(char ch) {
-    return ch == '/' || ch == '\\';
-  }
-
-  /**
-   * Returns string representation of this pattern.
-   * 
-   * @since 2.5
-   */
-  @Override
-  public String toString() {
-    return stringRepresentation;
-  }
-
-  /**
-   * Returns true if specified value matches this pattern.
-   */
-  public boolean match(String value) {
-    value = StringUtils.removeStart(value, "/");
-    value = StringUtils.removeEnd(value, "/");
-    return pattern.matcher(value).matches();
-  }
-
-  /**
-   * Returns true if specified value matches one of specified patterns.
-   * 
-   * @since 2.4
-   */
-  public static boolean match(WildcardPattern[] patterns, String value) {
-    for (WildcardPattern pattern : patterns) {
-      if (pattern.match(value)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Creates pattern with "/" as a directory separator.
-   * 
-   * @see #create(String, String)
-   */
-  public static WildcardPattern create(String pattern) {
-    return create(pattern, "/");
-  }
-
-  /**
-   * Creates array of patterns with "/" as a directory separator.
-   * 
-   * @see #create(String, String)
-   */
-  public static WildcardPattern[] create(String[] patterns) {
-    if (patterns == null) {
-      return new WildcardPattern[0];
-    }
-    WildcardPattern[] exclusionPAtterns = new WildcardPattern[patterns.length];
-    for (int i = 0; i < patterns.length; i++) {
-      exclusionPAtterns[i] = create(patterns[i]);
-    }
-    return exclusionPAtterns;
-  }
-
-  /**
-   * Creates pattern with specified separator for directories.
-   * <p>
-   * This is used to match Java-classes, i.e. <code>org.foo.Bar</code> against <code>org/**</code>.
-   * <b>However usage of character other than "/" as a directory separator is misleading and should be avoided,
-   * so method {@link #create(String)} is preferred over this one.</b>
-   * </p>
-   * <p>
-   * Also note that no matter whether forward or backward slashes were used in the <code>antPattern</code>
-   * the returned pattern will use <code>directorySeparator</code>.
-   * Thus to match Windows-style path "dir\file.ext" against pattern "dir/file.ext" normalization should be performed.
-   * </p>
-   */
-  public static WildcardPattern create(String pattern, String directorySeparator) {
-    String key = pattern + directorySeparator;
-    WildcardPattern wildcardPattern = CACHE.get(key);
-    if (wildcardPattern == null) {
-      wildcardPattern = new WildcardPattern(pattern, directorySeparator);
-      CACHE.put(key, wildcardPattern);
-    }
-    return wildcardPattern;
-  }
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/internal/package-info.java
deleted file mode 100644 (file)
index 9870b99..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.batch.api.internal;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/languages/Language.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/languages/Language.java
deleted file mode 100644 (file)
index 7dd6c8b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.languages;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-public final class Language {
-
-  private final String key, name;
-  private final String[] fileSuffixes;
-
-  public Language(String key, String name, String... fileSuffixes) {
-    this.key = key;
-    this.name = name;
-    this.fileSuffixes = fileSuffixes;
-  }
-
-  /**
-   * For example "java".
-   */
-  public String key() {
-    return key;
-  }
-
-  /**
-   * For example "Java"
-   */
-  public String name() {
-    return name;
-  }
-
-  /**
-   * For example ["jav", "java"].
-   */
-  public Collection<String> fileSuffixes() {
-    return Arrays.asList(fileSuffixes);
-  }
-
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/languages/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/languages/package-info.java
deleted file mode 100644 (file)
index a36d1c1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.batch.api.languages;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/measures/Metric.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/measures/Metric.java
deleted file mode 100644 (file)
index 52dc17c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.measures;
-
-import java.io.Serializable;
-
-public interface Metric<G extends Serializable> {
-
-  Class<G> type();
-
-  String key();
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/measures/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/measures/package-info.java
deleted file mode 100644 (file)
index e684b54..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.batch.api.measures;
\ No newline at end of file
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/rules/QProfile.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/rules/QProfile.java
deleted file mode 100644 (file)
index 1d074e1..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.rules;
-
-public class QProfile {
-  private final String name, language;
-  private final Integer version;
-
-  public QProfile(String name, String language, Integer version) {
-    this.name = name;
-    this.language = language;
-    this.version = version;
-  }
-
-  public String name() {
-    return name;
-  }
-
-  public String language() {
-    return language;
-  }
-
-  public Integer version() {
-    return version;
-  }
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/rules/RuleKey.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/rules/RuleKey.java
deleted file mode 100644 (file)
index 3af1337..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.api.rules;
-
-import java.io.Serializable;
-
-/**
- * Key of a rule. Unique among all the rule repositories.
- *
- * @since 3.6
- */
-public class RuleKey implements Serializable {
-  private final String repository, rule;
-
-  protected RuleKey(String repositoryKey, String ruleKey) {
-    this.repository = repositoryKey;
-    this.rule = ruleKey;
-  }
-
-  /**
-   * Create a key. Parameters are NOT null.
-   */
-  public static RuleKey of(String repository, String rule) {
-    return new RuleKey(repository, rule);
-  }
-
-  /**
-   * Never null
-   */
-  public String repository() {
-    return repository;
-  }
-
-  /**
-   * Never null
-   */
-  public String rule() {
-    return rule;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    RuleKey ruleKey = (RuleKey) o;
-    if (!repository.equals(ruleKey.repository)) {
-      return false;
-    }
-    if (!rule.equals(ruleKey.rule)) {
-      return false;
-    }
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = repository.hashCode();
-    result = 31 * result + rule.hashCode();
-    return result;
-  }
-
-  /**
-   * Format is "repository:rule", for example "squid:AvoidCycle"
-   */
-  @Override
-  public String toString() {
-    return String.format("%s:%s", repository, rule);
-  }
-}
diff --git a/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/rules/package-info.java b/sonar-batch-plugin-api/src/main/java/org/sonar/batch/api/rules/package-info.java
deleted file mode 100644 (file)
index d91eb34..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.batch.api.rules;
\ No newline at end of file
index ab32231dbea537e6c9e8c6d90f7f4fcc064840ad..1e8c53d885353b919de995e42f41a48b107eb613 100644 (file)
@@ -25,6 +25,8 @@ import com.persistit.Exchange;
 import com.persistit.Persistit;
 import com.persistit.Value;
 import com.persistit.Volume;
+import com.persistit.encoding.CoderManager;
+import com.persistit.encoding.ValueCoder;
 import com.persistit.exception.PersistitException;
 import com.persistit.logging.Slf4jAdapter;
 import org.apache.commons.io.FileUtils;
@@ -78,6 +80,11 @@ public class Caches implements BatchComponent, Startable {
     }
   }
 
+  public void registerValueCoder(Class<?> clazz, ValueCoder coder) {
+    CoderManager cm = persistit.getCoderManager();
+    cm.registerValueCoder(clazz, coder);
+  }
+
   public <V extends Serializable> Cache<V> createCache(String cacheName) {
     Preconditions.checkState(volume != null && volume.isOpened(), "Caches are not initialized");
     Preconditions.checkState(!cacheNames.contains(cacheName), "Cache is already created: " + cacheName);
index e3732308cf53458e11d7f4d65a081d94778afbdb..a3d23bf4fdea0ca73d20f8524dd0fe7f22a2b19a 100644 (file)
@@ -22,8 +22,10 @@ package org.sonar.batch.scan.measure;
 import com.google.common.base.Preconditions;
 import org.sonar.api.BatchComponent;
 import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MetricFinder;
 import org.sonar.api.measures.RuleMeasure;
 import org.sonar.api.resources.Resource;
+import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
 import org.sonar.batch.index.Cache;
 import org.sonar.batch.index.Cache.Entry;
 import org.sonar.batch.index.Caches;
@@ -35,7 +37,8 @@ public class MeasureCache implements BatchComponent {
 
   private final Cache<Measure> cache;
 
-  public MeasureCache(Caches caches) {
+  public MeasureCache(Caches caches, MetricFinder metricFinder, TechnicalDebtModel techDebtModel) {
+    caches.registerValueCoder(Measure.class, new MeasureValueCoder(metricFinder, techDebtModel));
     cache = caches.createCache("measures");
   }
 
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureValueCoder.java
new file mode 100644 (file)
index 0000000..ccda40c
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.scan.measure;
+
+import com.persistit.Value;
+import com.persistit.encoding.CoderContext;
+import com.persistit.encoding.ValueCoder;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.measures.PersistenceMode;
+import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
+
+class MeasureValueCoder implements ValueCoder {
+
+  private final MetricFinder metricFinder;
+  private final TechnicalDebtModel techDebtModel;
+
+  public MeasureValueCoder(MetricFinder metricFinder, TechnicalDebtModel techDebtModel) {
+    this.metricFinder = metricFinder;
+    this.techDebtModel = techDebtModel;
+  }
+
+  public void put(Value value, Object object, CoderContext context) {
+    Measure<?> m = (Measure) object;
+    value.putString(m.getMetricKey());
+    value.put(m.getValue());
+    value.putString(m.getData());
+    value.putString(m.getDescription());
+    value.putString(m.getAlertStatus() != null ? m.getAlertStatus().name() : null);
+    value.putString(m.getAlertText());
+    value.put(m.getTendency());
+    value.putDate(m.getDate());
+    value.put(m.getVariation1());
+    value.put(m.getVariation2());
+    value.put(m.getVariation3());
+    value.put(m.getVariation4());
+    value.put(m.getVariation5());
+    value.putString(m.getUrl());
+    value.put(m.getCharacteristic() != null ? m.getCharacteristic().id() : null);
+    value.put(m.getRequirement() != null ? m.getRequirement().id() : null);
+    value.put(m.getPersonId() != null ? m.getPersonId().intValue() : null);
+    value.putString(m.getPersistenceMode() != null ? m.getPersistenceMode().name() : null);
+  }
+
+  public Object get(Value value, Class clazz, CoderContext context) {
+    Measure<?> m = new Measure();
+    String metricKey = value.getString();
+    m.setMetric(metricFinder.findByKey(metricKey));
+    m.setRawValue(value.isNull(true) ? null : value.getDouble());
+    m.setData(value.getString());
+    m.setDescription(value.getString());
+    m.setAlertStatus(value.isNull(true) ? null : Metric.Level.valueOf(value.getString()));
+    m.setAlertText(value.getString());
+    m.setTendency(value.isNull(true) ? null : value.getInt());
+    m.setDate(value.getDate());
+    m.setVariation1(value.isNull(true) ? null : value.getDouble());
+    m.setVariation2(value.isNull(true) ? null : value.getDouble());
+    m.setVariation3(value.isNull(true) ? null : value.getDouble());
+    m.setVariation4(value.isNull(true) ? null : value.getDouble());
+    m.setVariation5(value.isNull(true) ? null : value.getDouble());
+    m.setUrl(value.getString());
+    m.setCharacteristic(value.isNull(true) ? null : techDebtModel.characteristicById(value.getInt()));
+    m.setRequirement(value.isNull(true) ? null : techDebtModel.requirementsById(value.getInt()));
+    m.setPersonId(value.isNull(true) ? null : value.getInt());
+    m.setPersistenceMode(value.isNull(true) ? null : PersistenceMode.valueOf(value.getString()));
+    return m;
+  }
+}
index 2e086f16627cd59f542bddd9ed0a1fd1a6a40c2e..82653d849fc3ac609cad8fb30bc935927bfd61fe 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.batch.scan.measure;
 
+import org.apache.commons.lang.builder.EqualsBuilder;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -27,6 +28,8 @@ import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric.Level;
+import org.sonar.api.measures.MetricFinder;
 import org.sonar.api.measures.RuleMeasure;
 import org.sonar.api.resources.Directory;
 import org.sonar.api.resources.File;
@@ -34,6 +37,9 @@ import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rules.RulePriority;
+import org.sonar.api.technicaldebt.batch.Characteristic;
+import org.sonar.api.technicaldebt.batch.Requirement;
+import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
 import org.sonar.api.technicaldebt.batch.internal.DefaultCharacteristic;
 import org.sonar.batch.index.Cache.Entry;
 import org.sonar.batch.index.Caches;
@@ -43,6 +49,8 @@ import java.util.Date;
 import java.util.Iterator;
 
 import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class MeasureCacheTest {
 
@@ -54,10 +62,17 @@ public class MeasureCacheTest {
 
   Caches caches;
 
+  private MetricFinder metricFinder;
+
+  private TechnicalDebtModel techDebtModel;
+
   @Before
   public void start() throws Exception {
     caches = CachesTest.createCacheOnTemp(temp);
     caches.start();
+    metricFinder = mock(MetricFinder.class);
+    when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
+    techDebtModel = mock(TechnicalDebtModel.class);
   }
 
   @After
@@ -67,7 +82,7 @@ public class MeasureCacheTest {
 
   @Test
   public void should_add_measure() throws Exception {
-    MeasureCache cache = new MeasureCache(caches);
+    MeasureCache cache = new MeasureCache(caches, metricFinder, techDebtModel);
     Project p = new Project("struts");
 
     assertThat(cache.entries()).hasSize(0);
@@ -102,7 +117,7 @@ public class MeasureCacheTest {
    */
   @Test
   public void should_add_measure_with_big_data() throws Exception {
-    MeasureCache cache = new MeasureCache(caches);
+    MeasureCache cache = new MeasureCache(caches, metricFinder, techDebtModel);
     Project p = new Project("struts");
 
     assertThat(cache.entries()).hasSize(0);
@@ -142,7 +157,7 @@ public class MeasureCacheTest {
    */
   @Test
   public void should_add_measure_with_too_big_data_for_persistit_pre_patch() throws Exception {
-    MeasureCache cache = new MeasureCache(caches);
+    MeasureCache cache = new MeasureCache(caches, metricFinder, techDebtModel);
     Project p = new Project("struts");
 
     assertThat(cache.entries()).hasSize(0);
@@ -178,7 +193,7 @@ public class MeasureCacheTest {
 
   @Test
   public void should_add_measure_with_too_big_data_for_persistit() throws Exception {
-    MeasureCache cache = new MeasureCache(caches);
+    MeasureCache cache = new MeasureCache(caches, metricFinder, techDebtModel);
     Project p = new Project("struts");
 
     assertThat(cache.entries()).hasSize(0);
@@ -201,7 +216,7 @@ public class MeasureCacheTest {
 
   @Test
   public void should_add_measure_with_same_metric() throws Exception {
-    MeasureCache cache = new MeasureCache(caches);
+    MeasureCache cache = new MeasureCache(caches, metricFinder, techDebtModel);
     Project p = new Project("struts");
 
     assertThat(cache.entries()).hasSize(0);
@@ -223,7 +238,7 @@ public class MeasureCacheTest {
 
   @Test
   public void should_get_measures() throws Exception {
-    MeasureCache cache = new MeasureCache(caches);
+    MeasureCache cache = new MeasureCache(caches, metricFinder, techDebtModel);
     Project p = new Project("struts");
     Resource dir = new Directory("foo/bar").setEffectiveKey("struts:foo/bar");
     Resource file1 = new File("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt");
@@ -260,4 +275,46 @@ public class MeasureCacheTest {
     assertThat(cache.byResource(dir)).hasSize(1);
     assertThat(cache.byResource(dir).iterator().next()).isEqualTo(mDir);
   }
+
+  @Test
+  public void test_measure_coder() throws Exception {
+    MeasureCache cache = new MeasureCache(caches, metricFinder, techDebtModel);
+    Resource file1 = new File("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt");
+
+    Measure measure = new Measure(CoreMetrics.NCLOC, 1.786, 5);
+    cache.put(file1, measure);
+
+    Measure savedMeasure = cache.byResource(file1).iterator().next();
+
+    assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue();
+
+    measure = new Measure(CoreMetrics.NCLOC);
+    measure.setData("data");
+    measure.setAlertStatus(Level.ERROR);
+    measure.setAlertText("alert");
+    Characteristic c = mock(Characteristic.class);
+    when(c.id()).thenReturn(1);
+    when(techDebtModel.characteristicById(1)).thenReturn(c);
+    measure.setCharacteristic(c);
+    measure.setDate(new Date());
+    measure.setDescription("description");
+    measure.setPersistenceMode(null);
+    measure.setPersonId(3);
+    Requirement r = mock(Requirement.class);
+    when(r.id()).thenReturn(7);
+    when(techDebtModel.requirementsById(7)).thenReturn(r);
+    measure.setRequirement(r);
+    measure.setTendency(4);
+    measure.setUrl("http://foo");
+    measure.setVariation1(11.0);
+    measure.setVariation2(12.0);
+    measure.setVariation3(13.0);
+    measure.setVariation4(14.0);
+    measure.setVariation5(15.0);
+    cache.put(file1, measure);
+
+    savedMeasure = cache.byResource(file1).iterator().next();
+    assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue();
+
+  }
 }
index defb4eb4f690475ef7fc9a59dd5675f8699bafba..de072269330ec7d30f8810f869dab8a83896e190 100644 (file)
@@ -4,7 +4,7 @@
 
 <mapper namespace="org.sonar.core.source.db.SnapshotSourceMapper">
 
-  <select id="selectSnapshotSource" parameterType="int" resultType="string">
+  <select id="selectSnapshotSource" parameterType="long" resultType="string">
     SELECT data
     FROM snapshot_sources
     WHERE snapshot_id = #{sid}
index b6a90add399f9a62ac39ccefe015146ae6af7552..170b2c5531bc14df1955aa7a04712e07347374ee 100644 (file)
@@ -289,6 +289,14 @@ public class Measure<G extends Serializable> implements Serializable {
     return setValue(v, DEFAULT_PRECISION);
   }
 
+  /**
+   * For internal use
+   */
+  public Measure setRawValue(@Nullable Double v) {
+    this.value = v;
+    return this;
+  }
+
   /**
    * Sets the measure value as an int
    *