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;
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("#")) {
}
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());
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;
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();
}
}
+++ /dev/null
-/*
- * 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());
- }
-}
*/
package org.sonar.batch.highlighting;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
import org.sonar.batch.index.Data;
import java.util.ArrayList;
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;
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;
+++ /dev/null
-/*
- * 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();
- }
-}
*/
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 {
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;
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;
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;
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;
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;
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;
}
@Override
- public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
- return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
+ public NewHighlighting newHighlighting() {
+ return new DefaultHighlighting(sensorStorage);
}
@Override
*/
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;
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 {
private final CoverageExclusions coverageExclusions;
private final DuplicationCache duplicationCache;
private final ResourceCache resourceCache;
+ private final ComponentDataCache componentDataCache;
public DefaultSensorStorage(MetricFinder metricFinder, Project project,
ResourcePerspectives perspectives,
this.metricFinder = metricFinder;
this.project = project;
this.perspectives = perspectives;
+ this.componentDataCache = componentDataCache;
this.sonarIndex = sonarIndex;
this.coverageExclusions = coverageExclusions;
this.duplicationCache = duplicationCache;
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()));
+ }
}
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;
/**
* @since 3.6
- * @deprecated since 4.5 no more used in batch 2.0
*/
-@Deprecated
public class DefaultHighlightable implements Highlightable {
private final Component component;
+++ /dev/null
-/*
- * 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");
- }
-}
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;
import com.google.common.collect.Lists;
import org.junit.Test;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
import java.util.List;
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;
// ------------ 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 ------------
+++ /dev/null
-/*
- * 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();
-}
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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;
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;
void store(Dependency dependency);
+ void store(DefaultHighlighting highlighting);
+
}
--- /dev/null
+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();
+ }
+
+}