--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+
+package org.sonar.core.source;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.TreeMultimap;
+
+import java.util.List;
+
+public class HighlightingContext {
+
+ private static final String RULE_SEPARATOR = ";";
+ private static final String FIELD_SEPARATOR = ",";
+
+ private final Multimap<Integer, String> lowerBoundsDefinitions;
+ private final List<Integer> upperBoundsDefinitions;
+
+ private HighlightingContext() {
+ lowerBoundsDefinitions = TreeMultimap.create();
+ upperBoundsDefinitions = Lists.newArrayList();
+ }
+
+ public static HighlightingContext buildFrom(String serializedRules) {
+
+ HighlightingContext context = new HighlightingContext();
+
+ String[] rules = serializedRules.split(RULE_SEPARATOR);
+ for (int i = 0; i < rules.length; i++) {
+ String[] ruleFields = rules[i].split(FIELD_SEPARATOR);
+ context.lowerBoundsDefinitions.put(Integer.parseInt(ruleFields[0]), ruleFields[2]);
+ context.upperBoundsDefinitions.add(Integer.parseInt(ruleFields[1]));
+ }
+ return context;
+ }
+
+ public Multimap<Integer, String> getLowerBoundsDefinitions() {
+ return lowerBoundsDefinitions;
+ }
+
+ public List<Integer> getUpperBoundsDefinitions() {
+ return upperBoundsDefinitions;
+ }
+}
package org.sonar.core.source;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
import com.google.common.io.Closeables;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Collection;
-import java.util.List;
+import java.util.Collections;
/**
* @since 3.6
public static final char CR_END_OF_LINE = '\r';
public static final char LF_END_OF_LINE = '\n';
- public String wrapTextWithHtml(String text, SyntaxHighlightingRuleSet syntaxHighlighting) throws IOException {
+ public String wrapTextWithHtml(String text, HighlightingContext context) throws IOException {
- List<SyntaxHighlightingRule> highlightingRules = syntaxHighlighting.getSyntaxHighlightingRuleSet();
StringBuilder decoratedText = new StringBuilder();
BufferedReader stringBuffer = null;
try {
stringBuffer = new BufferedReader(new StringReader(text));
- CharactersReader context = new CharactersReader(stringBuffer);
+ CharactersReader charsReader = new CharactersReader(stringBuffer);
- while(context.readNextChar()) {
+ while (charsReader.readNextChar()) {
- if(shouldStartNewLine(context)) {
+ if (shouldStartNewLine(charsReader)) {
decoratedText.append(OPEN_TABLE_LINE);
- if(shouldReopenPendingTags(context)) {
- reopenCurrentSyntaxTags(context, decoratedText);
+ if (shouldReopenPendingTags(charsReader)) {
+ reopenCurrentSyntaxTags(charsReader, decoratedText);
}
}
- Collection<SyntaxHighlightingRule> tagsToClose =
- Collections2.filter(highlightingRules, new IndexRuleFilter(context.getCurrentIndex(), false));
- closeCompletedTags(context, tagsToClose, decoratedText);
+ int numberOfTagsToClose = getNumberOfTagsToClose(charsReader.getCurrentIndex(), context);
+ closeCompletedTags(charsReader, numberOfTagsToClose, decoratedText);
- if(shouldClosePendingTags(context)) {
- closeCurrentSyntaxTags(context, decoratedText);
+ if (shouldClosePendingTags(charsReader)) {
+ closeCurrentSyntaxTags(charsReader, decoratedText);
decoratedText.append(CLOSE_TABLE_LINE);
}
- Collection<SyntaxHighlightingRule> tagsToOpen =
- Collections2.filter(highlightingRules, new IndexRuleFilter(context.getCurrentIndex(), true));
- openNewTags(context, tagsToOpen, decoratedText);
+ Collection<String> tagsToOpen = getTagsToOpen(charsReader.getCurrentIndex(), context);
+ openNewTags(charsReader, tagsToOpen, decoratedText);
- decoratedText.append((char)context.getCurrentValue());
+ decoratedText.append((char) charsReader.getCurrentValue());
}
} catch (IOException exception) {
String errorMsg = "An exception occurred while highlighting the syntax of one of the project's files";
return decoratedText.toString();
}
+ private int getNumberOfTagsToClose(int currentIndex, HighlightingContext context) {
+ return Collections.frequency(context.getUpperBoundsDefinitions(), currentIndex);
+ }
+
+ private Collection<String> getTagsToOpen(int currentIndex, HighlightingContext context) {
+ return context.getLowerBoundsDefinitions().get(currentIndex);
+ }
+
public boolean shouldClosePendingTags(CharactersReader context) {
return context.getCurrentValue() == CR_END_OF_LINE
|| (context.getCurrentValue() == LF_END_OF_LINE && context.getPreviousValue() != CR_END_OF_LINE);
return context.getPreviousValue() == LF_END_OF_LINE || context.getCurrentIndex() == 0;
}
- private void closeCompletedTags(CharactersReader context, Collection<SyntaxHighlightingRule> rulesMatchingCurrentIndex,
+ private void closeCompletedTags(CharactersReader charactersReader, int numberOfTagsToClose,
StringBuilder decoratedText) {
- for (SyntaxHighlightingRule syntaxHighlightingRule : rulesMatchingCurrentIndex) {
- if(context.getCurrentIndex() == syntaxHighlightingRule.getEndPosition()) {
- injectClosingHtml(decoratedText);
- context.removeLastOpenTag();
- }
+ for (int i = 0; i < numberOfTagsToClose; i++) {
+ injectClosingHtml(decoratedText);
+ charactersReader.removeLastOpenTag();
}
}
- private void openNewTags(CharactersReader context, Collection<SyntaxHighlightingRule> rulesMatchingCurrentIndex,
+ private void openNewTags(CharactersReader charactersReader, Collection<String> tagsToOpen,
StringBuilder decoratedText) {
- for (SyntaxHighlightingRule syntaxHighlightingRule : rulesMatchingCurrentIndex) {
- if(context.getCurrentIndex() == syntaxHighlightingRule.getStartPosition()) {
- injectOpeningHtmlForRule(syntaxHighlightingRule.getTextType(), decoratedText);
- context.registerOpenTag(syntaxHighlightingRule.getTextType());
- }
+ for (String tagToOpen : tagsToOpen) {
+ injectOpeningHtmlForRule(tagToOpen, decoratedText);
+ charactersReader.registerOpenTag(tagToOpen);
}
}
- private void closeCurrentSyntaxTags(CharactersReader context, StringBuilder decoratedText) {
- for (int i = 0; i < context.getOpenTags().size(); i++) {
+ private void closeCurrentSyntaxTags(CharactersReader charactersReader, StringBuilder decoratedText) {
+ for (int i = 0; i < charactersReader.getOpenTags().size(); i++) {
injectClosingHtml(decoratedText);
}
}
- private void reopenCurrentSyntaxTags(CharactersReader context, StringBuilder decoratedText) {
- for (String tags : context.getOpenTags()) {
+ private void reopenCurrentSyntaxTags(CharactersReader charactersReader, StringBuilder decoratedText) {
+ for (String tags : charactersReader.getOpenTags()) {
injectOpeningHtmlForRule(tags, decoratedText);
}
}
private void injectClosingHtml(StringBuilder decoratedText) {
decoratedText.append("</span>");
}
-
- private class IndexRuleFilter implements Predicate<SyntaxHighlightingRule> {
-
- private final int characterIndex;
- private final boolean isNewCharRange;
-
- public IndexRuleFilter(int charIndex, boolean isNewCharRange) {
- this.characterIndex = charIndex;
- this.isNewCharRange = isNewCharRange;
- }
-
- @Override
- public boolean apply(@Nullable SyntaxHighlightingRule syntaxHighlightingRule) {
- if(syntaxHighlightingRule != null) {
- return (characterIndex == syntaxHighlightingRule.getStartPosition() && isNewCharRange)
- || (characterIndex == syntaxHighlightingRule.getEndPosition() && !isNewCharRange);
- }
- return false;
- }
- }
}
*/
public class SnapshotDataDto {
- private final long snapshotId;
- private final long resourceId;
- private final String data;
- private final String dataType;
-
- public SnapshotDataDto(long snapshotId, long resourceId, String data, String dataType) {
- this.snapshotId = snapshotId;
- this.resourceId = resourceId;
- this.data = data;
- this.dataType = dataType;
- }
+ private long id;
+ private long snapshotId;
+ private long resourceId;
+ private String data;
+ private String dataType;
public long getSnapshotId() {
return snapshotId;
public String getDataType() {
return dataType;
}
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public void setSnapshotId(long snapshotId) {
+ this.snapshotId = snapshotId;
+ }
+
+ public void setResourceId(long resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public void setDataType(String dataType) {
+ this.dataType = dataType;
+ }
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.core.source.jdbc;
+
+import javax.annotation.ParametersAreNonnullByDefault;
\ No newline at end of file
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.core.source;
+
+import javax.annotation.ParametersAreNonnullByDefault;
\ No newline at end of file
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.core.test;
+
+import javax.annotation.ParametersAreNonnullByDefault;
\ No newline at end of file
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+
+package org.sonar.core.source;
+
+import com.google.common.collect.Multimap;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class HighlightingContextTest {
+
+ private static final String SAMPLE_RULES = "0,8,k;0,52,cppd;54,67,a;69,75,k;106,130,cppd;114,130,k;";
+ private HighlightingContext highlightingContext;
+
+ @Before
+ public void setUpHighlightingContext() {
+ highlightingContext = HighlightingContext.buildFrom(SAMPLE_RULES);
+ }
+
+ @Test
+ public void should_extract_lower_bounds_from_serialized_rules() throws Exception {
+
+ Multimap<Integer, String> lowerBoundsDefinitions = highlightingContext.getLowerBoundsDefinitions();
+
+ assertThat(lowerBoundsDefinitions.containsEntry(0, "k"));
+ assertThat(lowerBoundsDefinitions.containsEntry(0, "cppd"));
+ assertThat(lowerBoundsDefinitions.containsEntry(54, "a"));
+ assertThat(lowerBoundsDefinitions.containsEntry(69, "k"));
+ assertThat(lowerBoundsDefinitions.containsEntry(106, "cppd"));
+ assertThat(lowerBoundsDefinitions.containsEntry(114, "k"));
+ }
+
+ @Test
+ public void should_extract_upper_bounds_from_serialized_rules() throws Exception {
+
+ List<Integer> upperBoundsDefinition = highlightingContext.getUpperBoundsDefinitions();
+ assertThat(upperBoundsDefinition).containsExactly(8, 52, 67, 75, 130, 130);
+ }
+}
String packageDeclaration = "package org.sonar.core.source;";
- SyntaxHighlightingRuleSet syntaxHighlighting = SyntaxHighlightingRuleSet.builder()
- .registerHighlightingRule(0, 7, "k").build();
+ HighlightingContext context = HighlightingContext.buildFrom("0,7,k;");
HtmlTextWrapper htmlTextWrapper = new HtmlTextWrapper();
- String htmlOutput = htmlTextWrapper.wrapTextWithHtml(packageDeclaration, syntaxHighlighting);
+ String htmlOutput = htmlTextWrapper.wrapTextWithHtml(packageDeclaration, context);
assertThat(htmlOutput).isEqualTo("<tr><td><span class=\"k\">package</span> org.sonar.core.source;");
}
+ secondCommentLine + LF_END_OF_LINE
+ thirdCommentLine + LF_END_OF_LINE;
- SyntaxHighlightingRuleSet syntaxHighlighting = SyntaxHighlightingRuleSet.builder()
- .registerHighlightingRule(0, 14, "cppd").build();
+ HighlightingContext context = HighlightingContext.buildFrom("0,14,cppd;");
HtmlTextWrapper htmlTextWrapper = new HtmlTextWrapper();
- String htmlOutput = htmlTextWrapper.wrapTextWithHtml(blockComment, syntaxHighlighting);
+ String htmlOutput = htmlTextWrapper.wrapTextWithHtml(blockComment, context);
assertThat(htmlOutput).isEqualTo(
"<tr><td><span class=\"cppd\">" + firstCommentLine + "</span></td></tr>" + LF_END_OF_LINE +
String classDeclaration = "public class MyClass implements MyInterface {\n";
- SyntaxHighlightingRuleSet syntaxHighlighting = SyntaxHighlightingRuleSet.builder()
- .registerHighlightingRule(0, 6, "k")
- .registerHighlightingRule(7, 12, "k")
- .registerHighlightingRule(21, 31, "k")
- .build();
+ HighlightingContext context = HighlightingContext.buildFrom("0,6,k;7,12,k;21,31,k;");
HtmlTextWrapper htmlTextWrapper = new HtmlTextWrapper();
- String htmlOutput = htmlTextWrapper.wrapTextWithHtml(classDeclaration, syntaxHighlighting);
+ String htmlOutput = htmlTextWrapper.wrapTextWithHtml(classDeclaration, context);
assertThat(htmlOutput).isEqualTo(
"<tr><td><span class=\"k\">public</span> <span class=\"k\">class</span> MyClass <span class=\"k\">implements</span> MyInterface {</td></tr>\n");
" * @throws IllegalArgumentException if no formula is associated to the metric" + LF_END_OF_LINE +
" */" + LF_END_OF_LINE;
- SyntaxHighlightingRuleSet syntaxHighlighting = SyntaxHighlightingRuleSet.builder()
- .registerHighlightingRule(0, 184, "cppd")
- .registerHighlightingRule(47, 53, "k")
- .build();
+ HighlightingContext context = HighlightingContext.buildFrom("0,184,cppd;47,53,k;");
HtmlTextWrapper htmlTextWrapper = new HtmlTextWrapper();
- String htmlOutput = htmlTextWrapper.wrapTextWithHtml(javaDocSample, syntaxHighlighting);
+ String htmlOutput = htmlTextWrapper.wrapTextWithHtml(javaDocSample, context);
assertThat(htmlOutput).isEqualTo(
"<tr><td><span class=\"cppd\">/**</span></td></tr>" + LF_END_OF_LINE +
" return metric;" + CR_END_OF_LINE + LF_END_OF_LINE +
"}" + CR_END_OF_LINE + LF_END_OF_LINE;
- SyntaxHighlightingRuleSet syntaxHighlighting = SyntaxHighlightingRuleSet.builder()
- .registerHighlightingRule(0, 52, "cppd")
- .registerHighlightingRule(54, 67, "a")
- .registerHighlightingRule(69, 75, "k")
- .registerHighlightingRule(106, 112, "k")
- .build();
+ HighlightingContext context = HighlightingContext.buildFrom("0,52,cppd;54,67,a;69,75,k;106,112,k;");
HtmlTextWrapper htmlTextWrapper = new HtmlTextWrapper();
- String htmlOutput = htmlTextWrapper.wrapTextWithHtml(crlfCodeSample, syntaxHighlighting);
+ String htmlOutput = htmlTextWrapper.wrapTextWithHtml(crlfCodeSample, context);
assertThat(htmlOutput).isEqualTo(
"<tr><td><span class=\"cppd\">/**</span></td></tr>" + CR_END_OF_LINE + LF_END_OF_LINE +
String data = "0,10,k;";
String dataType = "highlight_syntax";
- SnapshotDataDto dto = new SnapshotDataDto(11L, 1L, data, dataType);
+ SnapshotDataDto dto = new SnapshotDataDto();
+ dto.setResourceId(1L);
+ dto.setSnapshotId(11L);
+ dto.setData(data);
+ dto.setDataType(dataType);
dao.insert(dto);
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.api.scan.source;
+
+import javax.annotation.ParametersAreNonnullByDefault;
\ No newline at end of file