3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.api.batch.sensor.highlighting.internal;
22 import com.google.common.base.Preconditions;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.Iterator;
27 import java.util.List;
28 import org.sonar.api.batch.fs.InputFile;
29 import org.sonar.api.batch.fs.TextRange;
30 import org.sonar.api.batch.fs.internal.DefaultInputFile;
31 import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
32 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
33 import org.sonar.api.batch.sensor.internal.DefaultStorable;
34 import org.sonar.api.batch.sensor.internal.SensorStorage;
36 public class DefaultHighlighting extends DefaultStorable implements NewHighlighting {
38 private final List<SyntaxHighlightingRule> syntaxHighlightingRules;
39 private DefaultInputFile inputFile;
41 public DefaultHighlighting(SensorStorage storage) {
43 syntaxHighlightingRules = new ArrayList<>();
46 public List<SyntaxHighlightingRule> getSyntaxHighlightingRuleSet() {
47 return syntaxHighlightingRules;
50 private void checkOverlappingBoudaries() {
51 if (syntaxHighlightingRules.size() > 1) {
52 Iterator<SyntaxHighlightingRule> it = syntaxHighlightingRules.iterator();
53 SyntaxHighlightingRule previous = it.next();
54 while (it.hasNext()) {
55 SyntaxHighlightingRule current = it.next();
56 if (previous.range().end().compareTo(current.range().start()) > 0 && (previous.range().end().compareTo(current.range().end()) < 0)) {
57 String errorMsg = String.format("Cannot register highlighting rule for characters at %s as it " +
58 "overlaps at least one existing rule", current.range());
59 throw new IllegalStateException(errorMsg);
67 public DefaultHighlighting onFile(InputFile inputFile) {
68 Preconditions.checkNotNull(inputFile, "file can't be null");
69 this.inputFile = (DefaultInputFile) inputFile;
73 public InputFile inputFile() {
78 public DefaultHighlighting highlight(int startOffset, int endOffset, TypeOfText typeOfText) {
79 checkInputFileNotNull();
82 newRange = inputFile.newRange(startOffset, endOffset);
83 } catch (Exception e) {
84 throw new IllegalArgumentException("Unable to highlight file " + inputFile, e);
86 return highlight(newRange, typeOfText);
90 public DefaultHighlighting highlight(int startLine, int startLineOffset, int endLine, int endLineOffset, TypeOfText typeOfText) {
91 checkInputFileNotNull();
94 newRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset);
95 } catch (Exception e) {
96 throw new IllegalArgumentException("Unable to highlight file " + inputFile, e);
98 return highlight(newRange, typeOfText);
102 public DefaultHighlighting highlight(TextRange range, TypeOfText typeOfText) {
103 SyntaxHighlightingRule syntaxHighlightingRule = SyntaxHighlightingRule.create(range, typeOfText);
104 this.syntaxHighlightingRules.add(syntaxHighlightingRule);
109 protected void doSave() {
110 checkInputFileNotNull();
111 // Sort rules to avoid variation during consecutive runs
112 Collections.sort(syntaxHighlightingRules, new Comparator<SyntaxHighlightingRule>() {
114 public int compare(SyntaxHighlightingRule left, SyntaxHighlightingRule right) {
115 int result = left.range().start().compareTo(right.range().start());
117 result = right.range().end().compareTo(left.range().end());
122 checkOverlappingBoudaries();
126 private void checkInputFileNotNull() {
127 Preconditions.checkState(inputFile != null, "Call onFile() first");