]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5931 Cleanup highlighting API
authorJulien HENRY <julien.henry@sonarsource.com>
Fri, 20 Feb 2015 09:53:39 +0000 (10:53 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Fri, 20 Feb 2015 14:05:18 +0000 (15:05 +0100)
24 files changed:
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java
sonar-batch/src/main/java/org/sonar/batch/highlighting/DefaultHighlightingBuilder.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingData.java
sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilder.java
sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingDataValueCoder.java
sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingRule.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingRuleValueCoder.java
sonar-batch/src/main/java/org/sonar/batch/index/SourceDataFactory.java
sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java
sonar-batch/src/test/java/org/sonar/batch/highlighting/DefaultHighlightingBuilderTest.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilderTest.java
sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/HighlightingBuilder.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/NewHighlighting.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/SyntaxHighlightingRule.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/package-info.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java [new file with mode: 0644]

index 549a655573e7b678fe6bcb64b65c52cb74f57fe4..8daffb64026dbf70e7749e046dab1c1849d3c163 100644 (file)
@@ -26,7 +26,7 @@ import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.sensor.Sensor;
 import org.sonar.api.batch.sensor.SensorContext;
 import org.sonar.api.batch.sensor.SensorDescriptor;
-import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
+import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
@@ -54,7 +54,7 @@ public class SyntaxHighlightingSensor implements Sensor {
       try {
         List<String> lines = FileUtils.readLines(highlightingFile, context.fileSystem().encoding().name());
         int lineNumber = 0;
-        HighlightingBuilder highlightingBuilder = context.highlightingBuilder(inputFile);
+        NewHighlighting highlightingBuilder = context.newHighlighting().onFile(inputFile);
         for (String line : lines) {
           lineNumber++;
           if (StringUtils.isBlank(line) || line.startsWith("#")) {
@@ -62,14 +62,14 @@ public class SyntaxHighlightingSensor implements Sensor {
           }
           processLine(highlightingFile, lineNumber, highlightingBuilder, line);
         }
-        highlightingBuilder.done();
+        highlightingBuilder.save();
       } catch (IOException e) {
         throw new IllegalStateException(e);
       }
     }
   }
 
-  private void processLine(File highlightingFile, int lineNumber, HighlightingBuilder highlightingBuilder, String line) {
+  private void processLine(File highlightingFile, int lineNumber, NewHighlighting highlightingBuilder, String line) {
     try {
       Iterator<String> split = Splitter.on(":").split(line).iterator();
       int startOffset = Integer.parseInt(split.next());
index 559f6b37b0854491fb9c44bee6f2fac653b802b8..4bd8aa2da61a0125023a37a9e480a430dcec8bc4 100644 (file)
@@ -24,16 +24,18 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
+import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 
 import java.io.File;
 import java.io.IOException;
 
+import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -74,13 +76,14 @@ public class SyntaxHighlightingSensorTest {
     FileUtils.write(symbol, "1:4:k\n12:15:cppd\n\n#comment");
     DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
     fileSystem.add(inputFile);
-    HighlightingBuilder builder = mock(HighlightingBuilder.class);
-    when(context.highlightingBuilder(inputFile)).thenReturn(builder);
+    NewHighlighting builder = mock(NewHighlighting.class);
+    when(context.newHighlighting()).thenReturn(builder);
+    when(builder.onFile(any(InputFile.class))).thenReturn(builder);
 
     sensor.execute(context);
 
     verify(builder).highlight(1, 4, TypeOfText.KEYWORD);
     verify(builder).highlight(12, 15, TypeOfText.CPP_DOC);
-    verify(builder).done();
+    verify(builder).save();
   }
 }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/highlighting/DefaultHighlightingBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/highlighting/DefaultHighlightingBuilder.java
deleted file mode 100644 (file)
index 6682e32..0000000
+++ /dev/null
@@ -1,54 +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.highlighting;
-
-import org.sonar.api.batch.sensor.highlighting.TypeOfText;
-
-import com.google.common.base.Preconditions;
-import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
-import org.sonar.batch.index.ComponentDataCache;
-import org.sonar.core.source.SnapshotDataTypes;
-
-public class DefaultHighlightingBuilder implements HighlightingBuilder {
-
-  private final SyntaxHighlightingDataBuilder builder;
-  private String componentKey;
-  private ComponentDataCache cache;
-  private boolean done = false;
-
-  public DefaultHighlightingBuilder(String componentKey, ComponentDataCache cache) {
-    this.componentKey = componentKey;
-    this.cache = cache;
-    this.builder = new SyntaxHighlightingDataBuilder();
-  }
-
-  @Override
-  public HighlightingBuilder highlight(int startOffset, int endOffset, TypeOfText typeOfText) {
-    Preconditions.checkState(!done, "done() already called");
-    builder.registerHighlightingRule(startOffset, endOffset, typeOfText);
-    return this;
-  }
-
-  @Override
-  public void done() {
-    Preconditions.checkState(!done, "done() already called");
-    cache.setData(componentKey, SnapshotDataTypes.SYNTAX_HIGHLIGHTING, builder.build());
-  }
-}
index b1075a9ed192327887e3ab2fdae7a7b496bc663c..7b9b334e15a0f27d1e2e63309e1ba1a6fcafaf2f 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.batch.highlighting;
 
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 import org.sonar.batch.index.Data;
 
 import java.util.ArrayList;
index da5166a97535ae190c4886f779b15624cde6dac0..be0fa73a3e98cf951716893e232229a178fba344 100644 (file)
@@ -23,6 +23,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Ordering;
 import com.google.common.collect.Sets;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 
 import javax.annotation.Nullable;
 
index 621c1e5c2f535c12f099410a7f2a7299991797de..a748b499d57953a7a7c579107ae33cb17734711b 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.batch.highlighting;
 import com.persistit.Value;
 import com.persistit.encoding.CoderContext;
 import com.persistit.encoding.ValueCoder;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingRule.java b/sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingRule.java
deleted file mode 100644 (file)
index 8101628..0000000
+++ /dev/null
@@ -1,58 +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.highlighting;
-
-import org.sonar.api.batch.sensor.highlighting.TypeOfText;
-
-import java.io.Serializable;
-
-public class SyntaxHighlightingRule implements Serializable {
-
-  private final int startPosition;
-  private final int endPosition;
-  private final TypeOfText textType;
-
-  private SyntaxHighlightingRule(int startPosition, int endPosition, TypeOfText textType) {
-    this.startPosition = startPosition;
-    this.endPosition = endPosition;
-    this.textType = textType;
-  }
-
-  public static SyntaxHighlightingRule create(int startPosition, int endPosition, TypeOfText textType) {
-    return new SyntaxHighlightingRule(startPosition, endPosition, textType);
-  }
-
-  public int getStartPosition() {
-    return startPosition;
-  }
-
-  public int getEndPosition() {
-    return endPosition;
-  }
-
-  public TypeOfText getTextType() {
-    return textType;
-  }
-
-  @Override
-  public String toString() {
-    return "" + startPosition + "," + endPosition + "," + textType.cssClass();
-  }
-}
index 3d69f717c6b3085f43577b2fdba7f084df507a6f..8700c81f345a3494d15117edb47d2beb3f92f9aa 100644 (file)
  */
 package org.sonar.batch.highlighting;
 
-import org.sonar.api.batch.sensor.highlighting.TypeOfText;
-
 import com.persistit.Value;
 import com.persistit.encoding.CoderContext;
 import com.persistit.encoding.ValueCoder;
+import org.sonar.api.batch.sensor.highlighting.TypeOfText;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 
 class SyntaxHighlightingRuleValueCoder implements ValueCoder {
 
index 6d1cfc1e7f1a480f35e89e50e2f258657c5bbdf2..edea3a94051109ceff4b72a1e1547183181d458a 100644 (file)
@@ -26,6 +26,7 @@ import org.sonar.api.BatchComponent;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.duplication.Duplication;
 import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 import org.sonar.api.batch.sensor.symbol.Symbol;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
@@ -33,7 +34,6 @@ import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.batch.duplication.DuplicationCache;
 import org.sonar.batch.highlighting.SyntaxHighlightingData;
-import org.sonar.batch.highlighting.SyntaxHighlightingRule;
 import org.sonar.batch.scan.filesystem.InputFileMetadata;
 import org.sonar.batch.scan.measure.MeasureCache;
 import org.sonar.batch.source.CodeColorizers;
index edde3baad06a83bd7d9634d380a525f260eed351..8c07b72e5a698e9ba32d42a6deed5dd50c744e99 100644 (file)
@@ -29,6 +29,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency;
 import org.sonar.api.batch.sensor.duplication.Duplication;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.batch.sensor.symbol.Symbol;
 import org.sonar.api.issue.Issue;
@@ -37,7 +38,6 @@ import org.sonar.api.measures.Measure;
 import org.sonar.batch.dependency.DependencyCache;
 import org.sonar.batch.duplication.DuplicationCache;
 import org.sonar.batch.highlighting.SyntaxHighlightingData;
-import org.sonar.batch.highlighting.SyntaxHighlightingRule;
 import org.sonar.batch.index.Cache.Entry;
 import org.sonar.batch.index.ComponentDataCache;
 import org.sonar.batch.issue.IssueCache;
index e010b83fca20851d0bae6615f7a3bde5acabaafd..73a05a177b501f2caa850dbf1dad406e995a6b35 100644 (file)
@@ -29,7 +29,8 @@ import org.sonar.api.batch.sensor.dependency.NewDependency;
 import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency;
 import org.sonar.api.batch.sensor.duplication.NewDuplication;
 import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
-import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
+import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
+import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.NewIssue;
 import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
@@ -37,7 +38,6 @@ import org.sonar.api.batch.sensor.measure.NewMeasure;
 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
 import org.sonar.api.config.Settings;
-import org.sonar.batch.highlighting.DefaultHighlightingBuilder;
 import org.sonar.batch.index.ComponentDataCache;
 import org.sonar.batch.symbol.DefaultSymbolTableBuilder;
 
@@ -93,8 +93,8 @@ public class DefaultSensorContext implements SensorContext {
   }
 
   @Override
-  public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
-    return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
+  public NewHighlighting newHighlighting() {
+    return new DefaultHighlighting(sensorStorage);
   }
 
   @Override
index 170fd671daf71cded28f4202c6a1807d9461e65b..f91d3cdb25afd690b2ee6a23105ff8507b321a16 100644 (file)
  */
 package org.sonar.batch.sensor;
 
-import org.sonar.api.batch.sensor.internal.SensorStorage;
-
 import com.google.common.base.Preconditions;
 import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputDir;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputPath;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.sensor.duplication.Duplication;
 import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
+import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.Issue;
 import org.sonar.api.batch.sensor.issue.Issue.Severity;
 import org.sonar.api.batch.sensor.measure.Measure;
@@ -51,12 +52,14 @@ import org.sonar.api.resources.Resource;
 import org.sonar.api.resources.Scopes;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.batch.duplication.DuplicationCache;
+import org.sonar.batch.highlighting.SyntaxHighlightingData;
 import org.sonar.batch.index.BatchResource;
 import org.sonar.batch.index.ComponentDataCache;
 import org.sonar.batch.index.DefaultIndex;
 import org.sonar.batch.index.ResourceCache;
 import org.sonar.batch.sensor.coverage.CoverageExclusions;
 import org.sonar.core.component.ComponentKeys;
+import org.sonar.core.source.SnapshotDataTypes;
 
 public class DefaultSensorStorage implements SensorStorage {
 
@@ -68,6 +71,7 @@ public class DefaultSensorStorage implements SensorStorage {
   private final CoverageExclusions coverageExclusions;
   private final DuplicationCache duplicationCache;
   private final ResourceCache resourceCache;
+  private final ComponentDataCache componentDataCache;
 
   public DefaultSensorStorage(MetricFinder metricFinder, Project project,
     ResourcePerspectives perspectives,
@@ -77,6 +81,7 @@ public class DefaultSensorStorage implements SensorStorage {
     this.metricFinder = metricFinder;
     this.project = project;
     this.perspectives = perspectives;
+    this.componentDataCache = componentDataCache;
     this.sonarIndex = sonarIndex;
     this.coverageExclusions = coverageExclusions;
     this.duplicationCache = duplicationCache;
@@ -238,4 +243,10 @@ public class DefaultSensorStorage implements SensorStorage {
   public void store(Duplication duplication) {
     duplicationCache.put(duplication.originBlock().resourceKey(), (DefaultDuplication) duplication);
   }
+
+  @Override
+  public void store(DefaultHighlighting highlighting) {
+    String componentKey = ((DefaultInputFile) highlighting.inputFile()).key();
+    componentDataCache.setData(componentKey, SnapshotDataTypes.SYNTAX_HIGHLIGHTING, new SyntaxHighlightingData(highlighting.getSyntaxHighlightingRuleSet()));
+  }
 }
index 0fbedcaeb22bee5ecad8cf746b6d4cacf765238a..bef343b872a89dd81c0b2006842dcbd447a62e64 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.batch.source;
 
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
-
 import org.sonar.api.component.Component;
 import org.sonar.api.source.Highlightable;
 import org.sonar.batch.highlighting.SyntaxHighlightingDataBuilder;
@@ -29,9 +28,7 @@ import org.sonar.core.source.SnapshotDataTypes;
 
 /**
  * @since 3.6
- * @deprecated since 4.5 no more used in batch 2.0
  */
-@Deprecated
 public class DefaultHighlightable implements Highlightable {
 
   private final Component component;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/highlighting/DefaultHighlightingBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/highlighting/DefaultHighlightingBuilderTest.java
deleted file mode 100644 (file)
index d5875d5..0000000
+++ /dev/null
@@ -1,50 +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.highlighting;
-
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.sonar.api.batch.sensor.highlighting.TypeOfText;
-import org.sonar.batch.index.ComponentDataCache;
-import org.sonar.core.source.SnapshotDataTypes;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class DefaultHighlightingBuilderTest {
-
-  @Test
-  public void should_apply_registered_highlighting() throws Exception {
-
-    ComponentDataCache cache = mock(ComponentDataCache.class);
-
-    DefaultHighlightingBuilder highlightable = new DefaultHighlightingBuilder("myComponent", cache);
-    highlightable
-      .highlight(0, 10, TypeOfText.KEYWORD)
-      .highlight(20, 30, TypeOfText.CPP_DOC)
-      .done();
-
-    ArgumentCaptor<SyntaxHighlightingData> argCaptor = ArgumentCaptor.forClass(SyntaxHighlightingData.class);
-    verify(cache).setData(eq("myComponent"), eq(SnapshotDataTypes.SYNTAX_HIGHLIGHTING), argCaptor.capture());
-    assertThat(argCaptor.getValue().writeString()).isEqualTo("0,10,k;20,30,cppd");
-  }
-}
index 40a8d5164f12cd92d07b446d9c62d34f1eb88b4c..b4c4828b204428ce6635d87b04602eb056011030 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 
 import java.util.Collection;
 
index cf8e825e5cbd3040aba7d2c8fa21900df140a640..dcebfe2893e409e9687b1f47aaafaad94c4053ae 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.batch.highlighting;
 
 import com.google.common.collect.Lists;
 import org.junit.Test;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 
 import java.util.List;
 
index bd15a900398ad7fd031b42bf10b0ae1c3d9db044..b07a14560a232622644b4e9e90d4b0399b5a9db2 100644 (file)
@@ -26,7 +26,7 @@ import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.sensor.dependency.NewDependency;
 import org.sonar.api.batch.sensor.duplication.NewDuplication;
-import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
+import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
 import org.sonar.api.batch.sensor.issue.Issue;
 import org.sonar.api.batch.sensor.issue.NewIssue;
 import org.sonar.api.batch.sensor.measure.Measure;
@@ -79,9 +79,9 @@ public interface SensorContext {
   // ------------ HIGHLIGHTING ------------
 
   /**
-   * Builder to define highlighting of a file.
+   * Builder to define highlighting of a file. Don't forget to call {@link NewHighlighting#save()} once all elements are provided.
    */
-  HighlightingBuilder highlightingBuilder(InputFile inputFile);
+  NewHighlighting newHighlighting();
 
   // ------------ SYMBOL REFERENCES ------------
 
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/HighlightingBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/HighlightingBuilder.java
deleted file mode 100644 (file)
index aef7d53..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.api.batch.sensor.highlighting;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Experimental, do not use.
- * <p/>
- * This builder is used to define syntax highlighting (aka code coloration) on files.
- * @since 4.5
- */
-@Beta
-public interface HighlightingBuilder {
-
-  /**
-   * Call this method to indicate the type of text in a range.
-   * @param startOffset Starting position in file for this type of text. Beginning of a file starts with offset '0'.
-   * @param endOffset End position in file for this type of text.
-   * @param typeOfText see {@link TypeOfText} values.
-   */
-  HighlightingBuilder highlight(int startOffset, int endOffset, TypeOfText typeOfText);
-
-  /**
-   * Call this method only once when your are done with defining highlighting of the file.
-   * @throws IllegalStateException if you have defined overlapping highlighting
-   */
-  void done();
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/NewHighlighting.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/NewHighlighting.java
new file mode 100644 (file)
index 0000000..2066ce8
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.api.batch.sensor.highlighting;
+
+import org.sonar.api.batch.fs.InputFile;
+
+/**
+ * This builder is used to define syntax highlighting (aka code coloration) on files.
+ * @since 5.1
+ */
+public interface NewHighlighting {
+
+  /**
+   * The file the highlighting belongs to.
+   */
+  NewHighlighting onFile(InputFile inputFile);
+
+  /**
+   * Call this method to indicate the type of text in a range.
+   * @param startOffset Starting position in file for this type of text. Beginning of a file starts with offset '0'.
+   * @param endOffset End position in file for this type of text.
+   * @param typeOfText see {@link TypeOfText} values.
+   */
+  NewHighlighting highlight(int startOffset, int endOffset, TypeOfText typeOfText);
+
+  /**
+   * Call this method only once when your are done with defining highlighting of the file.
+   * @throws IllegalStateException if you have defined overlapping highlighting
+   */
+  void save();
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java
new file mode 100644 (file)
index 0000000..9849c05
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.api.batch.sensor.highlighting.internal;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Ordering;
+import com.google.common.collect.Sets;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
+import org.sonar.api.batch.sensor.highlighting.TypeOfText;
+import org.sonar.api.batch.sensor.internal.DefaultStorable;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
+
+import javax.annotation.Nullable;
+
+import java.util.Iterator;
+import java.util.Set;
+
+public class DefaultHighlighting extends DefaultStorable implements NewHighlighting {
+
+  private InputFile inputFile;
+  private Set<SyntaxHighlightingRule> syntaxHighlightingRuleSet;
+
+  public DefaultHighlighting() {
+    this(null);
+  }
+
+  public DefaultHighlighting(@Nullable SensorStorage storage) {
+    super(storage);
+    syntaxHighlightingRuleSet = Sets.newTreeSet(new Ordering<SyntaxHighlightingRule>() {
+      @Override
+      public int compare(@Nullable SyntaxHighlightingRule left,
+        @Nullable SyntaxHighlightingRule right) {
+        int result = left.getStartPosition() - right.getStartPosition();
+        if (result == 0) {
+          result = right.getEndPosition() - left.getEndPosition();
+        }
+        return result;
+      }
+    });
+  }
+
+  public Set<SyntaxHighlightingRule> getSyntaxHighlightingRuleSet() {
+    return syntaxHighlightingRuleSet;
+  }
+
+  private void checkOverlappingBoudaries() {
+    if (syntaxHighlightingRuleSet.size() > 1) {
+      Iterator<SyntaxHighlightingRule> it = syntaxHighlightingRuleSet.iterator();
+      SyntaxHighlightingRule previous = it.next();
+      while (it.hasNext()) {
+        SyntaxHighlightingRule current = it.next();
+        if (previous.getEndPosition() > current.getStartPosition() && !(previous.getEndPosition() >= current.getEndPosition())) {
+          String errorMsg = String.format("Cannot register highlighting rule for characters from %s to %s as it " +
+            "overlaps at least one existing rule", current.getStartPosition(), current.getEndPosition());
+          throw new IllegalStateException(errorMsg);
+        }
+        previous = current;
+      }
+    }
+  }
+
+  @Override
+  public DefaultHighlighting onFile(InputFile inputFile) {
+    Preconditions.checkNotNull(inputFile, "file can't be null");
+    this.inputFile = inputFile;
+    return this;
+  }
+
+  public InputFile inputFile() {
+    return inputFile;
+  }
+
+  @Override
+  public DefaultHighlighting highlight(int startOffset, int endOffset, TypeOfText typeOfText) {
+    Preconditions.checkState(inputFile != null, "Call onFile() first");
+    SyntaxHighlightingRule syntaxHighlightingRule = SyntaxHighlightingRule.create(startOffset, endOffset,
+      typeOfText);
+    this.syntaxHighlightingRuleSet.add(syntaxHighlightingRule);
+    return this;
+  }
+
+  @Override
+  protected void doSave() {
+    Preconditions.checkState(inputFile != null, "Call onFile() first");
+    checkOverlappingBoudaries();
+    storage.store(this);
+  }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/SyntaxHighlightingRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/SyntaxHighlightingRule.java
new file mode 100644 (file)
index 0000000..9989449
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.api.batch.sensor.highlighting.internal;
+
+import org.sonar.api.batch.sensor.highlighting.TypeOfText;
+
+import java.io.Serializable;
+
+public class SyntaxHighlightingRule implements Serializable {
+
+  private final int startPosition;
+  private final int endPosition;
+  private final TypeOfText textType;
+
+  private SyntaxHighlightingRule(int startPosition, int endPosition, TypeOfText textType) {
+    this.startPosition = startPosition;
+    this.endPosition = endPosition;
+    this.textType = textType;
+  }
+
+  public static SyntaxHighlightingRule create(int startPosition, int endPosition, TypeOfText textType) {
+    return new SyntaxHighlightingRule(startPosition, endPosition, textType);
+  }
+
+  public int getStartPosition() {
+    return startPosition;
+  }
+
+  public int getEndPosition() {
+    return endPosition;
+  }
+
+  public TypeOfText getTextType() {
+    return textType;
+  }
+
+  @Override
+  public String toString() {
+    return "" + startPosition + "," + endPosition + "," + textType.cssClass();
+  }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/package-info.java
new file mode 100644 (file)
index 0000000..964bc08
--- /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.api.batch.sensor.highlighting.internal;
index 69b79f7addfbc2609e0ddbd42bbbcd6dfdf5c34c..850d3e6cdc7288022f1d8fbff25de6407fa030fd 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.api.batch.sensor.internal;
 
 import org.sonar.api.batch.sensor.dependency.Dependency;
 import org.sonar.api.batch.sensor.duplication.Duplication;
+import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.issue.Issue;
 import org.sonar.api.batch.sensor.measure.Measure;
 
@@ -38,4 +39,6 @@ public interface SensorStorage {
 
   void store(Dependency dependency);
 
+  void store(DefaultHighlighting highlighting);
+
 }
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java
new file mode 100644 (file)
index 0000000..2770df6
--- /dev/null
@@ -0,0 +1,73 @@
+package org.sonar.api.batch.sensor.highlighting.internal;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
+
+import java.util.Collection;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonar.api.batch.sensor.highlighting.TypeOfText.COMMENT;
+import static org.sonar.api.batch.sensor.highlighting.TypeOfText.CPP_DOC;
+import static org.sonar.api.batch.sensor.highlighting.TypeOfText.KEYWORD;
+
+public class DefaultHighlightingTest {
+
+  private Collection<SyntaxHighlightingRule> highlightingRules;
+
+  @Rule
+  public ExpectedException throwable = ExpectedException.none();
+
+  @Before
+  public void setUpSampleRules() {
+
+    DefaultHighlighting highlightingDataBuilder = new DefaultHighlighting()
+      .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+      .highlight(0, 10, COMMENT)
+      .highlight(10, 12, KEYWORD)
+      .highlight(24, 38, KEYWORD)
+      .highlight(42, 50, KEYWORD)
+      .highlight(24, 65, CPP_DOC)
+      .highlight(12, 20, COMMENT);
+
+    highlightingRules = highlightingDataBuilder.getSyntaxHighlightingRuleSet();
+  }
+
+  @Test
+  public void should_register_highlighting_rule() throws Exception {
+    assertThat(highlightingRules).hasSize(6);
+  }
+
+  @Test
+  public void should_order_by_start_then_end_offset() throws Exception {
+    assertThat(highlightingRules).extracting("startPosition").containsOnly(0, 10, 12, 24, 24, 42);
+    assertThat(highlightingRules).extracting("endPosition").containsOnly(10, 12, 20, 38, 65, 50);
+    assertThat(highlightingRules).extracting("textType").containsOnly(COMMENT, KEYWORD, COMMENT, KEYWORD, CPP_DOC, KEYWORD);
+  }
+
+  @Test
+  public void should_suport_overlapping() throws Exception {
+    new DefaultHighlighting(mock(SensorStorage.class))
+      .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+      .highlight(0, 15, KEYWORD)
+      .highlight(8, 12, CPP_DOC)
+      .save();
+  }
+
+  @Test
+  public void should_prevent_boudaries_overlapping() throws Exception {
+    throwable.expect(IllegalStateException.class);
+    throwable.expectMessage("Cannot register highlighting rule for characters from 8 to 15 as it overlaps at least one existing rule");
+
+    new DefaultHighlighting(mock(SensorStorage.class))
+      .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+      .highlight(0, 10, KEYWORD)
+      .highlight(8, 15, KEYWORD)
+      .save();
+  }
+
+}