package org.sonar.plugins.core;
import com.google.common.collect.ImmutableList;
-import org.sonar.api.*;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.Properties;
+import org.sonar.api.Property;
+import org.sonar.api.PropertyType;
+import org.sonar.api.SonarPlugin;
import org.sonar.api.checks.NoSonarFilter;
import org.sonar.core.timemachine.Periods;
import org.sonar.plugins.core.charts.DistributionAreaChart;
import org.sonar.plugins.core.charts.DistributionBarChart;
-import org.sonar.plugins.core.colorizers.JavaColorizerFormat;
import org.sonar.plugins.core.dashboards.GlobalDefaultDashboard;
import org.sonar.plugins.core.dashboards.ProjectDefaultDashboard;
import org.sonar.plugins.core.dashboards.ProjectIssuesDashboard;
import org.sonar.plugins.core.dashboards.ProjectTimeMachineDashboard;
-import org.sonar.plugins.core.issue.*;
-import org.sonar.plugins.core.issue.notification.*;
+import org.sonar.plugins.core.issue.CountFalsePositivesDecorator;
+import org.sonar.plugins.core.issue.CountUnresolvedIssuesDecorator;
+import org.sonar.plugins.core.issue.InitialOpenIssuesSensor;
+import org.sonar.plugins.core.issue.InitialOpenIssuesStack;
+import org.sonar.plugins.core.issue.IssueHandlers;
+import org.sonar.plugins.core.issue.IssueTracking;
+import org.sonar.plugins.core.issue.IssueTrackingDecorator;
+import org.sonar.plugins.core.issue.notification.ChangesOnMyIssueNotificationDispatcher;
+import org.sonar.plugins.core.issue.notification.IssueChangesEmailTemplate;
+import org.sonar.plugins.core.issue.notification.NewFalsePositiveNotificationDispatcher;
+import org.sonar.plugins.core.issue.notification.NewIssuesEmailTemplate;
+import org.sonar.plugins.core.issue.notification.NewIssuesNotificationDispatcher;
+import org.sonar.plugins.core.issue.notification.SendIssueNotificationsPostJob;
import org.sonar.plugins.core.measurefilters.MyFavouritesFilter;
import org.sonar.plugins.core.measurefilters.ProjectFilter;
import org.sonar.plugins.core.notifications.alerts.NewAlerts;
import org.sonar.plugins.core.security.ApplyProjectRolesDecorator;
-import org.sonar.plugins.core.sensors.*;
-import org.sonar.plugins.core.timemachine.*;
-import org.sonar.plugins.core.widgets.*;
-import org.sonar.plugins.core.widgets.issues.*;
-import org.sonar.plugins.core.widgets.measures.*;
+import org.sonar.plugins.core.sensors.BranchCoverageDecorator;
+import org.sonar.plugins.core.sensors.CommentDensityDecorator;
+import org.sonar.plugins.core.sensors.CoverageDecorator;
+import org.sonar.plugins.core.sensors.CoverageMeasurementFilter;
+import org.sonar.plugins.core.sensors.DirectoriesDecorator;
+import org.sonar.plugins.core.sensors.FileHashSensor;
+import org.sonar.plugins.core.sensors.FilesDecorator;
+import org.sonar.plugins.core.sensors.ItBranchCoverageDecorator;
+import org.sonar.plugins.core.sensors.ItCoverageDecorator;
+import org.sonar.plugins.core.sensors.ItLineCoverageDecorator;
+import org.sonar.plugins.core.sensors.LineCoverageDecorator;
+import org.sonar.plugins.core.sensors.ManualMeasureDecorator;
+import org.sonar.plugins.core.sensors.OverallBranchCoverageDecorator;
+import org.sonar.plugins.core.sensors.OverallCoverageDecorator;
+import org.sonar.plugins.core.sensors.OverallLineCoverageDecorator;
+import org.sonar.plugins.core.sensors.ProjectLinksSensor;
+import org.sonar.plugins.core.sensors.UnitTestDecorator;
+import org.sonar.plugins.core.sensors.VersionEventsSensor;
+import org.sonar.plugins.core.timemachine.NewCoverageAggregator;
+import org.sonar.plugins.core.timemachine.NewCoverageFileAnalyzer;
+import org.sonar.plugins.core.timemachine.NewItCoverageFileAnalyzer;
+import org.sonar.plugins.core.timemachine.NewOverallCoverageFileAnalyzer;
+import org.sonar.plugins.core.timemachine.TendencyDecorator;
+import org.sonar.plugins.core.timemachine.TimeMachineConfigurationPersister;
+import org.sonar.plugins.core.timemachine.VariationDecorator;
+import org.sonar.plugins.core.widgets.AlertsWidget;
+import org.sonar.plugins.core.widgets.BubbleChartWidget;
+import org.sonar.plugins.core.widgets.ComplexityWidget;
+import org.sonar.plugins.core.widgets.CoverageWidget;
+import org.sonar.plugins.core.widgets.CustomMeasuresWidget;
+import org.sonar.plugins.core.widgets.DebtOverviewWidget;
+import org.sonar.plugins.core.widgets.DescriptionWidget;
+import org.sonar.plugins.core.widgets.DocumentationCommentsWidget;
+import org.sonar.plugins.core.widgets.DuplicationsWidget;
+import org.sonar.plugins.core.widgets.EventsWidget;
+import org.sonar.plugins.core.widgets.HotspotMetricWidget;
+import org.sonar.plugins.core.widgets.HotspotMostViolatedRulesWidget;
+import org.sonar.plugins.core.widgets.ItCoverageWidget;
+import org.sonar.plugins.core.widgets.ProjectFileCloudWidget;
+import org.sonar.plugins.core.widgets.SizeWidget;
+import org.sonar.plugins.core.widgets.TechnicalDebtPyramidWidget;
+import org.sonar.plugins.core.widgets.TimeMachineWidget;
+import org.sonar.plugins.core.widgets.TimelineWidget;
+import org.sonar.plugins.core.widgets.TreemapWidget;
+import org.sonar.plugins.core.widgets.WelcomeWidget;
+import org.sonar.plugins.core.widgets.issues.ActionPlansWidget;
+import org.sonar.plugins.core.widgets.issues.FalsePositiveIssuesWidget;
+import org.sonar.plugins.core.widgets.issues.IssueFilterWidget;
+import org.sonar.plugins.core.widgets.issues.IssuesWidget;
+import org.sonar.plugins.core.widgets.issues.MyUnresolvedIssuesWidget;
+import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesPerAssigneeWidget;
+import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesStatusesWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsBubbleChartWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsCloudWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsHistogramWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsPieChartWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsTreemapWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterListWidget;
import java.util.List;
DistributionBarChart.class,
DistributionAreaChart.class,
- // colorizers
- JavaColorizerFormat.class,
-
// issues
IssueTrackingDecorator.class,
IssueTracking.class,
+++ /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.plugins.core.colorizers;
-
-import org.sonar.api.web.CodeColorizerFormat;
-import org.sonar.colorizer.CodeColorizer;
-import org.sonar.colorizer.Tokenizer;
-
-import java.util.List;
-
-public class JavaColorizerFormat extends CodeColorizerFormat{
-
- public JavaColorizerFormat() {
- super("java");
- }
-
- @Override
- public List<Tokenizer> getTokenizers() {
- return CodeColorizer.Format.JAVA.getTokenizers();
- }
-}
+++ /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.
- */
-/**
- * Deprecated in 4.5.1. JFreechart charts are replaced by Javascript charts.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.plugins.core.colorizers;
-
-import javax.annotation.ParametersAreNonnullByDefault;
public String writeString() {
StringBuilder sb = new StringBuilder();
for (SyntaxHighlightingRule highlightingRule : syntaxHighlightingRuleSet) {
+ if (sb.length() > 0) {
+ sb.append(RULE_SEPARATOR);
+ }
sb.append(highlightingRule.getStartPosition())
.append(FIELD_SEPARATOR)
.append(highlightingRule.getEndPosition())
.append(FIELD_SEPARATOR)
- .append(highlightingRule.getTextType().cssClass())
- .append(RULE_SEPARATOR);
+ .append(highlightingRule.getTextType().cssClass());
}
return sb.toString();
import org.sonar.batch.highlighting.SyntaxHighlightingRule;
import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan.measure.MeasureCache;
+import org.sonar.batch.source.CodeColorizers;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.source.SnapshotDataTypes;
private final System2 system2;
private final ProjectTree projectTree;
private final ResourceCache resourceCache;
+ private CodeColorizers codeColorizers;
public SourcePersister(ResourcePersister resourcePersister, SnapshotSourceDao sourceDao, InputPathCache inputPathCache,
- MyBatis mybatis, MeasureCache measureCache, ComponentDataCache componentDataCache, ProjectTree projectTree, System2 system2, ResourceCache resourceCache) {
+ MyBatis mybatis, MeasureCache measureCache, ComponentDataCache componentDataCache, ProjectTree projectTree, System2 system2, ResourceCache resourceCache,
+ CodeColorizers codeColorizers) {
this.resourcePersister = resourcePersister;
this.sourceDao = sourceDao;
this.inputPathCache = inputPathCache;
this.projectTree = projectTree;
this.system2 = system2;
this.resourceCache = resourceCache;
+ this.codeColorizers = codeColorizers;
}
public void saveSource(Resource resource, String source, Date updatedAt) {
Map<Integer, String> authorsByLine = getLineMetric(file, CoreMetrics.SCM_AUTHORS_BY_LINE_KEY);
Map<Integer, String> revisionsByLine = getLineMetric(file, CoreMetrics.SCM_REVISIONS_BY_LINE_KEY);
Map<Integer, String> datesByLine = getLineMetric(file, CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY);
- SyntaxHighlightingData highlighting = componentDataCache.getData(file.key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING);
+ SyntaxHighlightingData highlighting = loadHighlighting(file);
String[] highlightingPerLine = computeHighlightingPerLine(file, highlighting);
ByteArrayOutputStream output = new ByteArrayOutputStream();
return StringUtils.defaultIfEmpty(new String(output.toByteArray(), UTF_8), null);
}
+ @CheckForNull
+ private SyntaxHighlightingData loadHighlighting(DefaultInputFile file) {
+ SyntaxHighlightingData highlighting = componentDataCache.getData(file.key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING);
+ if (highlighting == null) {
+ highlighting = codeColorizers.toSyntaxHighlighting(file.file(), file.encoding(), file.language());
+ }
+ return highlighting;
+ }
+
String[] computeHighlightingPerLine(DefaultInputFile file, @Nullable SyntaxHighlightingData highlighting) {
String[] result = new String[file.lines()];
if (highlighting == null) {
import org.sonar.batch.scan.maven.FakeMavenPluginExecutor;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
import org.sonar.batch.scan.measure.MeasureCache;
+import org.sonar.batch.source.CodeColorizers;
import org.sonar.batch.source.HighlightableBuilder;
import org.sonar.batch.source.SymbolizableBuilder;
import org.sonar.core.component.ScanGraph;
DuplicationPersister.class,
DefaultResourcePersister.class,
SourcePersister.class,
+ CodeColorizers.class,
DefaultNotificationManager.class,
MetricProvider.class,
ProjectConfigurator.class,
--- /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.source;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.web.CodeColorizerFormat;
+import org.sonar.batch.highlighting.SyntaxHighlightingData;
+import org.sonar.colorizer.Tokenizer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Central point for sonar-colorizer extensions
+ */
+public class CodeColorizers implements BatchComponent {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CodeColorizers.class);
+
+ private final Map<String, CodeColorizerFormat> byLang;
+
+ public CodeColorizers(List<CodeColorizerFormat> formats) {
+ byLang = new HashMap<String, CodeColorizerFormat>();
+ for (CodeColorizerFormat format : formats) {
+ byLang.put(format.getLanguageKey(), format);
+ }
+
+ LOG.debug("Code colorizer, supported languages: " + StringUtils.join(byLang.keySet(), ","));
+ }
+
+ /**
+ * Used when no plugin is defining some CodeColorizerFormat
+ */
+ public CodeColorizers() {
+ this(Lists.<CodeColorizerFormat>newArrayList());
+ }
+
+ public SyntaxHighlightingData toSyntaxHighlighting(File file, String encoding, String language) {
+ CodeColorizerFormat format = byLang.get(language);
+ List<Tokenizer> tokenizers;
+ if (format == null) {
+ tokenizers = null;
+ } else {
+ tokenizers = format.getTokenizers();
+ }
+ Reader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding));
+ return new HighlightingRenderer().render(reader, tokenizers);
+ } catch (Exception e) {
+ throw new IllegalStateException("Unable to read source file for colorization", e);
+ } finally {
+ IOUtils.closeQuietly(reader);
+ }
+ }
+}
--- /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.source;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.sensor.highlighting.TypeOfText;
+import org.sonar.batch.highlighting.SyntaxHighlightingData;
+import org.sonar.batch.highlighting.SyntaxHighlightingDataBuilder;
+import org.sonar.colorizer.HtmlCodeBuilder;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class HighlightingCodeBuilder extends HtmlCodeBuilder {
+
+ private static final Logger LOG = LoggerFactory.getLogger(HighlightingCodeBuilder.class);
+
+ private static final char BOM = '\uFEFF';
+
+ private SyntaxHighlightingDataBuilder highlightingBuilder = new SyntaxHighlightingDataBuilder();
+ private int currentOffset = 0;
+ private static final Pattern START_TAG_PATTERN = Pattern.compile("<span class=\"(.+)\">");
+ private static final Pattern END_TAG_PATTERN = Pattern.compile("</span>");
+ private int startOffset = -1;
+ private String cssClass;
+
+ @Override
+ public Appendable append(CharSequence csq) {
+ for (int i = 0; i < csq.length(); i++) {
+ append(csq.charAt(i));
+ }
+ return this;
+ }
+
+ @Override
+ public Appendable append(char c) {
+ if (c != BOM) {
+ currentOffset++;
+ }
+ return this;
+ }
+
+ @Override
+ public Appendable append(CharSequence csq, int start, int end) {
+ for (int i = start; i < end; i++) {
+ append(csq.charAt(i));
+ }
+ return this;
+ }
+
+ public void appendWithoutTransforming(String htmlTag) {
+ if (startOffset == -1) {
+ Matcher startMatcher = START_TAG_PATTERN.matcher(htmlTag);
+ if (startMatcher.matches()) {
+ startOffset = currentOffset;
+ cssClass = startMatcher.group(1);
+ } else {
+ LOG.warn("Expected to match highlighting start html tag but was: " + htmlTag);
+ }
+ } else {
+ Matcher endMatcher = END_TAG_PATTERN.matcher(htmlTag);
+ if (endMatcher.matches()) {
+ highlightingBuilder.registerHighlightingRule(startOffset, currentOffset, TypeOfText.forCssClass(cssClass));
+ startOffset = -1;
+ } else {
+ LOG.warn("Expected to match highlighting end html tag but was: " + htmlTag);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public StringBuilder getColorizedCode() {
+ throw new UnsupportedOperationException();
+ }
+
+ public SyntaxHighlightingData getHighlightingData() {
+ return highlightingBuilder.build();
+ }
+
+}
--- /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.source;
+
+import org.sonar.batch.highlighting.SyntaxHighlightingData;
+import org.sonar.channel.Channel;
+import org.sonar.channel.CodeReader;
+import org.sonar.colorizer.HtmlCodeBuilder;
+import org.sonar.colorizer.TokenizerDispatcher;
+
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+public class HighlightingRenderer {
+
+ public SyntaxHighlightingData render(Reader code, List<? extends Channel<HtmlCodeBuilder>> tokenizers) {
+ List<Channel<HtmlCodeBuilder>> allTokenizers = new ArrayList<Channel<HtmlCodeBuilder>>();
+ HighlightingCodeBuilder codeBuilder = new HighlightingCodeBuilder();
+
+ allTokenizers.addAll(tokenizers);
+
+ new TokenizerDispatcher(allTokenizers).colorize(new CodeReader(code), codeBuilder);
+
+ return codeBuilder.getHighlightingData();
+ }
+}
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;");
+ assertThat(argCaptor.getValue().writeString()).isEqualTo("0,10,k;20,30,cppd");
}
}
);
String serializedRules = new SyntaxHighlightingData(orderedHighlightingRules).writeString();
- assertThat(serializedRules).isEqualTo("0,10,cd;10,12,k;12,20,cd;24,38,k;24,65,cppd;42,50,k;");
+ assertThat(serializedRules).isEqualTo("0,10,cd;10,12,k;12,20,cd;24,38,k;24,65,cppd;42,50,k");
}
}
import org.sonar.batch.highlighting.SyntaxHighlightingDataBuilder;
import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan.measure.MeasureCache;
+import org.sonar.batch.source.CodeColorizers;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.source.SnapshotDataTypes;
import org.sonar.core.source.db.SnapshotSourceDao;
componentDataCache = mock(ComponentDataCache.class);
sourcePersister = new SourcePersister(resourcePersister, new SnapshotSourceDao(getMyBatis()), inputPathCache,
getMyBatis(), measureCache, componentDataCache, projectTree, system2,
- resourceCache);
+ resourceCache, mock(CodeColorizers.class));
Project project = new Project(PROJECT_KEY);
project.setUuid("projectUuid");
when(projectTree.getRootProject()).thenReturn(project);
--- /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.source;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.commons.io.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.web.CodeColorizerFormat;
+import org.sonar.batch.highlighting.SyntaxHighlightingData;
+import org.sonar.colorizer.CDocTokenizer;
+import org.sonar.colorizer.CppDocTokenizer;
+import org.sonar.colorizer.JavadocTokenizer;
+import org.sonar.colorizer.KeywordsTokenizer;
+import org.sonar.colorizer.StringTokenizer;
+import org.sonar.colorizer.Tokenizer;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class CodeColorizersTest {
+
+ private static final String HIGHLIGHTING = "0,4,cppd;5,11,cppd;12,15,cppd;16,19,k;29,37,k;65,69,k;85,93,cd;98,102,k;112,114,s;120,124,k";
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Test
+ public void testConvertToHighlighting() throws Exception {
+ CodeColorizers codeColorizers = new CodeColorizers(Arrays.<CodeColorizerFormat>asList(new JavaScriptColorizerFormat()));
+
+ File jsFile = new File(this.getClass().getResource("CodeColorizersTest/Person.js").toURI());
+
+ SyntaxHighlightingData syntaxHighlighting = codeColorizers.toSyntaxHighlighting(jsFile, "UTF-8", "js");
+
+ assertThat(syntaxHighlighting.writeString()).isEqualTo(HIGHLIGHTING);
+
+ }
+
+ @Test
+ public void testConvertToHighlightingIgnoreBOM() throws Exception {
+ CodeColorizers codeColorizers = new CodeColorizers(Arrays.<CodeColorizerFormat>asList(new JavaScriptColorizerFormat()));
+
+ File fileWithBom = temp.newFile();
+ FileUtils.write(fileWithBom, "\uFEFF");
+ File jsFile = new File(this.getClass().getResource("CodeColorizersTest/Person.js").toURI());
+ FileUtils.write(fileWithBom, FileUtils.readFileToString(jsFile), true);
+
+ SyntaxHighlightingData syntaxHighlighting = codeColorizers.toSyntaxHighlighting(fileWithBom, "UTF-8", "js");
+
+ assertThat(syntaxHighlighting.writeString()).isEqualTo(HIGHLIGHTING);
+
+ }
+
+ public static class JavaScriptColorizerFormat extends CodeColorizerFormat {
+
+ public JavaScriptColorizerFormat() {
+ super("js");
+ }
+
+ @Override
+ public List<Tokenizer> getTokenizers() {
+ return ImmutableList.<Tokenizer>of(
+ new StringTokenizer("<span class=\"s\">", "</span>"),
+ new CDocTokenizer("<span class=\"cd\">", "</span>"),
+ new JavadocTokenizer("<span class=\"cppd\">", "</span>"),
+ new CppDocTokenizer("<span class=\"cppd\">", "</span>"),
+ new KeywordsTokenizer("<span class=\"k\">", "</span>", "null",
+ "true",
+ "false",
+ "break",
+ "case",
+ "catch",
+ "class",
+ "continue",
+ "debugger",
+ "default",
+ "delete",
+ "do",
+ "extends",
+ "else",
+ "finally",
+ "for",
+ "function",
+ "if",
+ "import",
+ "in",
+ "instanceof",
+ "new",
+ "return",
+ "super",
+ "switch",
+ "this",
+ "throw",
+ "try",
+ "typeof",
+ "var",
+ "void",
+ "while",
+ "with",
+ "yield",
+ "const",
+ "enum",
+ "export"));
+ }
+
+ }
+
+}
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;");
+ assertThat(argCaptor.getValue().writeString()).isEqualTo("0,10,k;20,30,cppd");
}
}
--- /dev/null
+/**
+ * Doc
+ */
+var Person = function(first, last, middle) {
+ this.first = first; // First
+ this.middle = '';
+ this.last = 1;
+};
*/
package org.sonar.api.web;
-import java.util.List;
-
import com.google.common.base.Objects;
import org.sonar.api.ServerExtension;
+import org.sonar.api.source.Highlightable;
+import org.sonar.api.task.TaskExtension;
import org.sonar.colorizer.Tokenizer;
+import java.util.List;
+
/**
- * Extend the library sonar-colorizer to support new languages. By default only Java sources are colorized in Sonar.
+ * Extend the library sonar-colorizer to support new languages.
*
* @since 1.12
+ * @deprecated since 5.1 use {@link Highlightable} API
*/
-public abstract class CodeColorizerFormat implements ServerExtension {
+public abstract class CodeColorizerFormat implements ServerExtension, TaskExtension {
private String languageKey;
if (this == o) {
return true;
}
- if ( !(o instanceof CodeColorizerFormat)) {
+ if (!(o instanceof CodeColorizerFormat)) {
return false;
}