diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-06 14:08:06 +0000 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-06 14:08:06 +0000 |
commit | aeadc1f9129274949daaa57738c7c4550bdfbc7b (patch) | |
tree | 08dadf5ef7474fc41d1d48f74648f1ba8b55f34d /sonar-colorizer/src/main | |
download | sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.tar.gz sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.zip |
SONAR-236 remove deprecated code from checkstyle plugin + display default value of rule parameters in Q profile console
Diffstat (limited to 'sonar-colorizer/src/main')
27 files changed, 1621 insertions, 0 deletions
diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/CDocTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/CDocTokenizer.java new file mode 100644 index 00000000000..ce146f9ec74 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/CDocTokenizer.java @@ -0,0 +1,28 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +public class CDocTokenizer extends InlineDocTokenizer { + + public CDocTokenizer(String tagBefore, String tagAfter) { + super("//", tagBefore, tagAfter); + } + +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/CaseInsensitiveKeywordsTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/CaseInsensitiveKeywordsTokenizer.java new file mode 100644 index 00000000000..e54470b977d --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/CaseInsensitiveKeywordsTokenizer.java @@ -0,0 +1,41 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.Set; + +public class CaseInsensitiveKeywordsTokenizer extends KeywordsTokenizer { + + public CaseInsensitiveKeywordsTokenizer(String tagBefore, String tagAfter, Set<String> keywords) { + super(tagBefore, tagAfter, keywords); + setCaseInsensitive(true); + } + + public CaseInsensitiveKeywordsTokenizer(String tagBefore, String tagAfter, String... keywords) { + super(tagBefore, tagAfter, keywords); + setCaseInsensitive(true); + } + + public KeywordsTokenizer clone() { + KeywordsTokenizer clone = (KeywordsTokenizer) super.clone(); + clone.setCaseInsensitive(true); + return clone; + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/CodeColorizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/CodeColorizer.java new file mode 100644 index 00000000000..a348fa81cff --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/CodeColorizer.java @@ -0,0 +1,71 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.io.Reader; +import java.util.List; + +public class CodeColorizer { + + private List<Tokenizer> tokenizers = null; + + public CodeColorizer(List<Tokenizer> tokenizers) { + this.tokenizers = tokenizers; + } + + public CodeColorizer(Format format) { + this.tokenizers = format.getTokenizers(); + } + + public String toHtml(Reader code) { + return toHtml(code, null); + } + + public String toHtml(Reader code, HtmlOptions options) { + HtmlOptions opts = (options == null ? HtmlOptions.DEFAULT : options); + return new HtmlRenderer(opts).render(code, tokenizers); + } + + public static String javaToHtml(Reader code, HtmlOptions options) { + return new CodeColorizer(Format.JAVA).toHtml(code, options); + } + + public static String groovyToHtml(Reader code, HtmlOptions options) { + return new CodeColorizer(Format.GROOVY).toHtml(code, options); + } + + public static String getCss() { + return HtmlDecorator.getCss(); + } + + public enum Format { + JAVA(JavaTokenizers.forHtml()), GROOVY(GroovyTokenizers.forHtml()); + + private List<Tokenizer> tokenizers; + + Format(List<Tokenizer> tokenizers) { + this.tokenizers = tokenizers; + } + + public List<Tokenizer> getTokenizers() { + return tokenizers; + } + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/CppDocTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/CppDocTokenizer.java new file mode 100644 index 00000000000..d965b6c652f --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/CppDocTokenizer.java @@ -0,0 +1,31 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +public class CppDocTokenizer extends MultilinesDocTokenizer { + + public CppDocTokenizer(String tagBefore, String tagAfter) { + super("/*", "*/", tagBefore, tagAfter); + } + + public CppDocTokenizer() { + this("", ""); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/GroovyKeywords.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/GroovyKeywords.java new file mode 100644 index 00000000000..bc97ba94267 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/GroovyKeywords.java @@ -0,0 +1,45 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public final class GroovyKeywords { + + private static final Set<String> KEYWORDS = new HashSet<String>(); + + private static final String[] GROOVY_KEYWORDS = new String[] { "as", "assert", "break", "case", "catch", "class", "continue", "def", + "default", "do" + , "else", "extends", "finally", "for", "if", "in", "implements", "import", "instanceof", "interface", "new", "package", + "property", "return", "switch", "throw", "throws", "try", "while" }; + + static { + Collections.addAll(KEYWORDS, GROOVY_KEYWORDS); + } + + private GroovyKeywords() { + } + + public static Set<String> get() { + return Collections.unmodifiableSet(KEYWORDS); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/GroovyTokenizers.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/GroovyTokenizers.java new file mode 100644 index 00000000000..4e86ed7eec0 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/GroovyTokenizers.java @@ -0,0 +1,37 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public final class GroovyTokenizers { + + private GroovyTokenizers() { + } + + public static List<Tokenizer> forHtml() { + return Collections.unmodifiableList(Arrays.asList(new JavaAnnotationTokenizer("<span class=\"a\">", "</span>"), new LiteralTokenizer( + "<span class=\"s\">", "</span>"), new CDocTokenizer("<span class=\"cd\">", "</span>"), new CppDocTokenizer("<span class=\"cppd\">", + "</span>"), new JavadocTokenizer("<span class=\"j\">", "</span>"), new JavaConstantTokenizer("<span class=\"c\">", "</span>"), + new KeywordsTokenizer("<span class=\"k\">", "</span>", GroovyKeywords.get()))); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlCodeBuilder.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlCodeBuilder.java new file mode 100644 index 00000000000..ea530abc037 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlCodeBuilder.java @@ -0,0 +1,104 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.HashMap; +import java.util.Map; + +public class HtmlCodeBuilder implements Appendable { + + private StringBuilder colorizedCode = new StringBuilder(); + private Map variables = new HashMap(); // stateful data + + public Appendable append(CharSequence csq) { + for (int i = 0; i < csq.length(); i++) { + append(csq.charAt(i)); + } + return this; + } + + public Appendable append(char c) { + if (c == '<') { + colorizedCode.append("<"); + } else if (c == '>') { + colorizedCode.append(">"); + } else { + colorizedCode.append(c); + } + return this; + } + + 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) { + colorizedCode.append(htmlTag); + } + + public String toString() { + return colorizedCode.toString(); + } + + public StringBuilder getColorizedCode() { + return colorizedCode; + } + + /** + * Save a stateful variable. + * + * @param key + * can NOT be null + * @param value + * can be null + */ + public void setVariable(Object key, Object value) { + variables.put(key, value); + } + + /** + * Get a stateful variable. Return null if not found. + */ + public Object getVariable(Object key) { + return variables.get(key); + } + + /** + * Get a stateful variable. Return the default value if not found. + */ + public Object getVariable(Object key, Object defaultValue) { + Object result = variables.get(key); + if (result == null) { + result = defaultValue; + } + return result; + } + + /** + * All stateful variables + */ + public Map getVariables() { + return variables; + } + +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlDecorator.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlDecorator.java new file mode 100644 index 00000000000..2d65143c106 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlDecorator.java @@ -0,0 +1,124 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.IOUtils; +import org.sonar.channel.CodeReader; + +public class HtmlDecorator extends Tokenizer { + + private static final String CSS_PATH = "/sonar-colorizer.css"; + + private HtmlOptions options; + private int lineId = 1; + private boolean checked = false; + private boolean beginOfLine = true; + private boolean endOfLine = false; + + public HtmlDecorator(HtmlOptions options) { + this.options = options; + this.lineId = options.getFirstLineId(); + } + + public String getTagBeginOfFile() { + StringBuilder sb = new StringBuilder(); + if (options.isGenerateHtmlHeader()) { + sb.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" " + + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html><head><style type=\"text/css\">"); + sb.append(getCss()); + sb.append("</style></head><body>"); + } + sb.append("<table class=\"code\" id=\""); + if (options.getTableId() != null) { + sb.append(options.getTableId()); + } + sb.append("\"><tbody>"); + return sb.toString(); + } + + public String getTagEndOfFile() { + StringBuilder sb = new StringBuilder(); + sb.append("</pre></td></tr></tbody></table>"); + if (options.isGenerateHtmlHeader()) { + sb.append("</body></html>"); + } + return sb.toString(); + } + + public String getTagBefore() { + StringBuilder sb = new StringBuilder(); + if (beginOfLine) { + sb.append("<tr id=\""); + sb.append(lineId++); + sb.append("\"><td><pre>"); + } + return sb.toString(); + } + + public String getTagAfter() { + if (endOfLine) { + return "</pre></td></tr>"; + } + return ""; + } + + private boolean hasNextToken(CodeReader code) { + if (checked) { + checked = false; + return false; + } + int lastChar = code.lastChar(); + beginOfLine = (lastChar == -1 || lastChar == (int) '\n'); + + int peek = code.peek(); + endOfLine = (peek == (int) '\n' || peek == -1); + + checked = beginOfLine || endOfLine; + return checked; + } + + @Override + public boolean consume(CodeReader code, HtmlCodeBuilder codeBuilder) { + if (hasNextToken(code)) { + codeBuilder.appendWithoutTransforming(getTagBefore()); + codeBuilder.appendWithoutTransforming(getTagAfter()); + return true; + } else { + return false; + } + } + + public static String getCss() { + InputStream input = null; + try { + input = HtmlRenderer.class.getResourceAsStream(CSS_PATH); + return IOUtils.toString(input); + + } catch (IOException e) { + throw new SynhtaxHighlightingException("Sonar Colorizer CSS file not found: " + CSS_PATH, e); + + } finally { + IOUtils.closeQuietly(input); + } + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlOptions.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlOptions.java new file mode 100644 index 00000000000..f26a710e80b --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlOptions.java @@ -0,0 +1,120 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +public class HtmlOptions { + public static final HtmlOptions DEFAULT = new HtmlOptions(true, null, true); + public static final OnlySyntaxHtmlOptions ONLY_SYNTAX = new OnlySyntaxHtmlOptions(); + + private boolean generateTable = true; + private boolean generateHtmlHeader = true; + private String tableId = null; + private int firstLineId = 1; + + public HtmlOptions() { + } + + public HtmlOptions(boolean generateTable, String tableId, boolean generateHtmlHeader) { + this.generateTable = generateTable; + this.generateHtmlHeader = generateHtmlHeader; + this.tableId = tableId; + } + + public boolean isGenerateTable() { + return generateTable; + } + + public HtmlOptions setGenerateTable(boolean b) { + this.generateTable = b; + return this; + } + + /** + * Used only if isGenerateTable() is true + */ + public boolean isGenerateHtmlHeader() { + return generateHtmlHeader; + } + + /** + * Defines if the HTML header, including CSS, must be generated. + */ + public HtmlOptions setGenerateHtmlHeader(boolean b) { + this.generateHtmlHeader = b; + return this; + } + + public String getTableId() { + return tableId; + } + + /** + * Used only if isGenerateTable() is true. This field is optional. + */ + public HtmlOptions setTableId(String id) { + this.tableId = id; + return this; + } + + /** + * Used only if isGenerateTable() is true. Default value is 1. + */ + public int getFirstLineId() { + return firstLineId; + } + + public HtmlOptions setFirstLineId(int i) { + this.firstLineId = i; + return this; + } +} + +class OnlySyntaxHtmlOptions extends HtmlOptions { + + @Override + public boolean isGenerateTable() { + return false; + } + + @Override + public boolean isGenerateHtmlHeader() { + return false; + } + + @Override + public String getTableId() { + return null; + } + + @Override + public HtmlOptions setGenerateHtmlHeader(boolean b) { + throw new IllegalStateException(); + } + + @Override + public HtmlOptions setGenerateTable(boolean b) { + throw new IllegalStateException(); + } + + @Override + public HtmlOptions setTableId(String id) { + throw new IllegalStateException(); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlRenderer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlRenderer.java new file mode 100644 index 00000000000..5f11b867584 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/HtmlRenderer.java @@ -0,0 +1,64 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; + +import org.sonar.channel.Channel; +import org.sonar.channel.CodeReader; + +public class HtmlRenderer extends Renderer { + + private HtmlOptions options = null; + + public HtmlRenderer(HtmlOptions options) { + this.options = options; + } + + public HtmlRenderer() { + this(HtmlOptions.DEFAULT); + } + + public String render(Reader code, List<? extends Channel<HtmlCodeBuilder>> tokenizers) { + try { + List<Channel<HtmlCodeBuilder>> allTokenizers = new ArrayList<Channel<HtmlCodeBuilder>>(); + HtmlCodeBuilder codeBuilder = new HtmlCodeBuilder(); + HtmlDecorator htmlDecorator = new HtmlDecorator(options); + + // optimization + if (options != null && options.isGenerateTable()) { + codeBuilder.appendWithoutTransforming(htmlDecorator.getTagBeginOfFile()); + allTokenizers.add(htmlDecorator); + } + allTokenizers.addAll(tokenizers); + + new TokenizerDispatcher(allTokenizers).colorize(new CodeReader(code), codeBuilder); + // optimization + if (options != null && options.isGenerateTable()) { + codeBuilder.appendWithoutTransforming(htmlDecorator.getTagEndOfFile()); + } + return codeBuilder.toString(); + } catch (Exception e) { + throw new SynhtaxHighlightingException("Can not render code", e); + } + } +}
\ No newline at end of file diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/InlineDocTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/InlineDocTokenizer.java new file mode 100644 index 00000000000..ad12bf829c3 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/InlineDocTokenizer.java @@ -0,0 +1,56 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.Arrays; + +import org.sonar.channel.CodeReader; +import org.sonar.channel.EndMatcher; + +public abstract class InlineDocTokenizer extends Tokenizer { + + private final String tagBefore; + private final String tagAfter; + + private final char[] startToken; + + public InlineDocTokenizer(String startToken, String tagBefore, String tagAfter) { + this.tagBefore = tagBefore; + this.tagAfter = tagAfter; + this.startToken = startToken.toCharArray(); + } + + public boolean consume(CodeReader code, HtmlCodeBuilder codeBuilder) { + if (code.peek() == startToken[0] && Arrays.equals(code.peek(startToken.length), startToken)) { + codeBuilder.appendWithoutTransforming(tagBefore); + code.popTo(new EndMatcher() { + + public boolean match(int endFlag) { + return endFlag == '\r' || endFlag == '\n'; + } + }, codeBuilder); + codeBuilder.appendWithoutTransforming(tagAfter); + return true; + } else { + return false; + } + } + +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaAnnotationTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaAnnotationTokenizer.java new file mode 100644 index 00000000000..346855eed46 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaAnnotationTokenizer.java @@ -0,0 +1,54 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import org.sonar.channel.CodeReader; +import org.sonar.channel.EndMatcher; + +public class JavaAnnotationTokenizer extends Tokenizer { + + private final String tagBefore; + private final String tagAfter; + + public JavaAnnotationTokenizer(String tagBefore, String tagAfter) { + this.tagBefore = tagBefore; + this.tagAfter = tagAfter; + } + + private static final EndMatcher endTokenMatcher = new EndMatcher() { + + public boolean match(int endFlag) { + return !Character.isJavaIdentifierPart(endFlag); + } + }; + + @Override + public boolean consume(CodeReader code, HtmlCodeBuilder codeBuilder) { + if (code.peek() == '@') { + codeBuilder.appendWithoutTransforming(tagBefore); + code.popTo(endTokenMatcher, codeBuilder); + codeBuilder.appendWithoutTransforming(tagAfter); + return true; + } else { + return false; + } + } + +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaConstantTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaConstantTokenizer.java new file mode 100644 index 00000000000..17fd02cf151 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaConstantTokenizer.java @@ -0,0 +1,80 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import org.sonar.channel.CodeReader; +import org.sonar.channel.EndMatcher; + +/** + * Detect Java constant + */ +public class JavaConstantTokenizer extends Tokenizer { + + private final String tagBefore; + private final String tagAfter; + private final static int DOT = '.'; + + public JavaConstantTokenizer(String tagBefore, String tagAfter) { + this.tagBefore = tagBefore; + this.tagAfter = tagAfter; + } + + private boolean hasNextToken(CodeReader code) { + int lastChar = code.lastChar(); + if (isJavaConstantStart(code.peek()) && !Character.isJavaIdentifierPart(lastChar) && !Character.isJavaIdentifierStart(lastChar) + && lastChar != DOT) { + String constant = code.peekTo(endTokenMatcher); + int nextCharAfterConstant = code.peek(constant.length() + 1)[constant.length()]; + if (nextCharAfterConstant != 0 && Character.isJavaIdentifierPart(nextCharAfterConstant)) { + return false; + } + return true; + } + return false; + } + + @Override + public boolean consume(CodeReader code, HtmlCodeBuilder codeBuilder) { + if (hasNextToken(code)) { + codeBuilder.appendWithoutTransforming(tagBefore); + code.popTo(endTokenMatcher, codeBuilder); + codeBuilder.appendWithoutTransforming(tagAfter); + return true; + } else { + return false; + } + } + + private boolean isJavaConstantStart(int character) { + return Character.isUpperCase(character); + } + + private boolean isJavaConstantPart(int character) { + return Character.isUpperCase(character) || character == '_' || character == '-' || Character.isDigit(character); + } + + private EndMatcher endTokenMatcher = new EndMatcher() { + + public boolean match(int endFlag) { + return !isJavaConstantPart(endFlag); + } + }; + +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaKeywords.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaKeywords.java new file mode 100644 index 00000000000..b3ce2bbfed1 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaKeywords.java @@ -0,0 +1,48 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public final class JavaKeywords { + + private static final Set<String> KEYWORDS = new HashSet<String>(); + + private static final String[] JAVA_KEYWORDS = new String[] { "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", + "class", "const", "continue", "default", + "do", "double", "else", "enum", "extends", "false", "final", "finally", "float", "for", + "goto", "if", "implements", "import", "instanceof", + "int", "interface", "long", "native", "new", "null", "package", "private", + "protected", "public", "return", "short", "static", "strictfp", + "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while"}; + + static { + Collections.addAll(KEYWORDS, JAVA_KEYWORDS); + } + + private JavaKeywords() { + } + + public static Set<String> get() { + return Collections.unmodifiableSet(KEYWORDS); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaTokenizers.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaTokenizers.java new file mode 100644 index 00000000000..e5bc1b5af1c --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavaTokenizers.java @@ -0,0 +1,37 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public final class JavaTokenizers { + + private JavaTokenizers() { + } + + public static List<Tokenizer> forHtml() { + return Collections.unmodifiableList(Arrays.asList(new JavaAnnotationTokenizer("<span class=\"a\">", "</span>"), new LiteralTokenizer( + "<span class=\"s\">", "</span>"), new CDocTokenizer("<span class=\"cd\">", "</span>"), new JavadocTokenizer("<span class=\"j\">", + "</span>"), new CppDocTokenizer("<span class=\"cppd\">", "</span>"), new JavaConstantTokenizer("<span class=\"c\">", "</span>"), + new KeywordsTokenizer("<span class=\"k\">", "</span>", JavaKeywords.get()))); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/JavadocTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavadocTokenizer.java new file mode 100644 index 00000000000..ccf39096475 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/JavadocTokenizer.java @@ -0,0 +1,31 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +public class JavadocTokenizer extends MultilinesDocTokenizer { + + public JavadocTokenizer(String tagBefore, String tagAfter) { + super("/**", "*/", tagBefore, tagAfter); + } + + public JavadocTokenizer() { + this("", ""); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/KeywordsTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/KeywordsTokenizer.java new file mode 100644 index 00000000000..9d4dd3239d7 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/KeywordsTokenizer.java @@ -0,0 +1,95 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.sonar.channel.CodeReader; + +/** + * Detect case-sensitive keywords + */ +public class KeywordsTokenizer extends NotThreadSafeTokenizer { + + private final String tagBefore; + private final String tagAfter; + private boolean caseInsensitive = false; + private Matcher matcher; + private final StringBuilder tmpBuilder = new StringBuilder(); + private final static String defaultRegex = "[a-zA-Z_][a-zA-Z0-9_]*+"; + + private Set<String> keywords = new HashSet<String>(); + + public KeywordsTokenizer(String tagBefore, String tagAfter, Set<String> keywords) { + this(tagBefore, tagAfter, keywords, defaultRegex); + } + + public KeywordsTokenizer(String tagBefore, String tagAfter, Set<String> keywords, String regex) { + this.tagBefore = tagBefore; + this.tagAfter = tagAfter; + this.keywords = keywords; + this.matcher = Pattern.compile(regex).matcher(""); + } + + public KeywordsTokenizer(String tagBefore, String tagAfter, String... keywords) { + this.tagBefore = tagBefore; + this.tagAfter = tagAfter; + Collections.addAll(this.keywords, keywords); + this.matcher = Pattern.compile(defaultRegex).matcher(""); + } + + public boolean consume(CodeReader code, HtmlCodeBuilder codeBuilder) { + if (code.popTo(matcher, tmpBuilder) > 0) { + if (isKeyword(tmpBuilder.toString())) { + codeBuilder.appendWithoutTransforming(tagBefore); + codeBuilder.append(tmpBuilder); + codeBuilder.appendWithoutTransforming(tagAfter); + } else { + codeBuilder.append(tmpBuilder); + } + tmpBuilder.delete(0, tmpBuilder.length()); + return true; + } + return false; + } + + private boolean isKeyword(String word) { + if ( !caseInsensitive && keywords.contains(word)) { + return true; + } else if (caseInsensitive && keywords.contains(word.toUpperCase())) { + return true; + } + return false; + } + + public void setCaseInsensitive(boolean caseInsensitive) { + this.caseInsensitive = caseInsensitive; + } + + public KeywordsTokenizer clone() { + KeywordsTokenizer clone = new KeywordsTokenizer(tagBefore, tagAfter, keywords, matcher.pattern().pattern()); + clone.caseInsensitive = caseInsensitive; + return clone; + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/LiteralTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/LiteralTokenizer.java new file mode 100644 index 00000000000..2c0c6c93468 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/LiteralTokenizer.java @@ -0,0 +1,81 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import org.sonar.channel.CodeReader; +import org.sonar.channel.EndMatcher; + +public class LiteralTokenizer extends Tokenizer { + + private final String tagBefore; + private final String tagAfter; + + public LiteralTokenizer(String tagBefore, String tagAfter) { + this.tagBefore = tagBefore; + this.tagAfter = tagAfter; + } + + public LiteralTokenizer() { + this("", ""); + } + + @Override + public boolean consume(CodeReader code, HtmlCodeBuilder codeBuilder) { + if (code.peek() == '\'' || code.peek() == '\"') { + codeBuilder.appendWithoutTransforming(tagBefore); + int firstChar = code.peek(); + code.popTo(new EndCommentMatcher(firstChar, code), codeBuilder); + codeBuilder.appendWithoutTransforming(tagAfter); + return true; + } else { + return false; + } + } + + private static class EndCommentMatcher implements EndMatcher { + + private final int firstChar; + private final CodeReader code; + private StringBuilder literalValue; + + public EndCommentMatcher(int firstChar, CodeReader code) { + this.firstChar = firstChar; + this.code = code; + literalValue = new StringBuilder(); + } + + public boolean match(int endFlag) { + literalValue.append((char) endFlag); + return (code.lastChar() == firstChar && evenNumberOfBackSlashBeforeDelimiter() && literalValue.length() > 1); + } + + private boolean evenNumberOfBackSlashBeforeDelimiter() { + int numberOfBackSlashChar = 0; + for (int index = literalValue.length() - 3; index >= 0; index--) { + if (literalValue.charAt(index) == '\\') { + numberOfBackSlashChar++; + } else { + break; + } + } + return numberOfBackSlashChar % 2 == 0; + } + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/MultilinesDocTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/MultilinesDocTokenizer.java new file mode 100644 index 00000000000..8fb767d623f --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/MultilinesDocTokenizer.java @@ -0,0 +1,117 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.Arrays; + +import org.sonar.channel.CodeReader; +import org.sonar.channel.EndMatcher; + +public class MultilinesDocTokenizer extends Tokenizer { + + private static final String COMMENT_STARTED_ON_PREVIOUS_LINE = "COMMENT_STARTED_ON_PREVIOUS_LINE"; + private static final String COMMENT_TOKENIZER = "MULTILINE_COMMENT_TOKENIZER"; + private final char[] startToken; + private final char[] endToken; + private final String tagBefore; + private final String tagAfter; + + /** + * @deprecated endToken is hardcoded to star-slash, whatever the startToken ! + */ + @Deprecated + public MultilinesDocTokenizer(String startToken, String tagBefore, String tagAfter) { + this(startToken, "*/", tagBefore, tagAfter); + } + + public MultilinesDocTokenizer(String startToken, String endToken, String tagBefore, String tagAfter) { + this.tagBefore = tagBefore; + this.tagAfter = tagAfter; + this.startToken = startToken.toCharArray(); + this.endToken = endToken.toCharArray(); + } + + public boolean hasNextToken(CodeReader code, HtmlCodeBuilder codeBuilder) { + return code.peek() != '\n' + && code.peek() != '\r' + && (isCommentStartedOnPreviousLine(codeBuilder) || (code.peek() == startToken[0] && Arrays.equals(code.peek(startToken.length), + startToken))); + } + + public boolean consume(CodeReader code, HtmlCodeBuilder codeBuilder) { + if (hasNextToken(code, codeBuilder)) { + codeBuilder.appendWithoutTransforming(tagBefore); + code.popTo(new MultilineEndTokenMatcher(codeBuilder), codeBuilder); + codeBuilder.appendWithoutTransforming(tagAfter); + return true; + } else { + return false; + } + } + + private class MultilineEndTokenMatcher implements EndMatcher { + + private final HtmlCodeBuilder code; + private final StringBuilder colorizedCode; + private int commentSize = 0; + + public MultilineEndTokenMatcher(HtmlCodeBuilder code) { + this.code = code; + this.colorizedCode = code.getColorizedCode(); + } + + public boolean match(int endFlag) { + commentSize++; + if (commentSize >= endToken.length + startToken.length || (commentSize >= endToken.length && isCommentStartedOnPreviousLine(code))) { + boolean matches = true; + for (int i = 1; i <= endToken.length; i++) { + if (colorizedCode.charAt(colorizedCode.length() - i) != endToken[endToken.length - i]) { + matches = false; + break; + } + } + if (matches) { + setCommentStartedOnPreviousLine(code, Boolean.FALSE); + return true; + } + } + + if (endFlag == '\r' || endFlag == '\n') { + setCommentStartedOnPreviousLine(code, Boolean.TRUE); + return true; + } + return false; + } + } + + private boolean isCommentStartedOnPreviousLine(HtmlCodeBuilder codeBuilder) { + Boolean b = (Boolean) codeBuilder.getVariable(COMMENT_STARTED_ON_PREVIOUS_LINE, Boolean.FALSE); + return (b == Boolean.TRUE) && (getTokenizerId().equals(codeBuilder.getVariable(COMMENT_TOKENIZER))); + } + + private void setCommentStartedOnPreviousLine(HtmlCodeBuilder codeBuilder, Boolean b) { + codeBuilder.setVariable(COMMENT_STARTED_ON_PREVIOUS_LINE, b); + codeBuilder.setVariable(COMMENT_TOKENIZER, b ? getTokenizerId() : null); + } + + private String getTokenizerId() { + return getClass().getSimpleName(); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/NotThreadSafeTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/NotThreadSafeTokenizer.java new file mode 100644 index 00000000000..94eb919dcc7 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/NotThreadSafeTokenizer.java @@ -0,0 +1,30 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +/** + * A thread safe Tokenizer. Before each use by the CodeColorizer, the method clone() is automatically + * called to clone the current instance. + * + */ +public abstract class NotThreadSafeTokenizer extends Tokenizer implements Cloneable { + + public abstract NotThreadSafeTokenizer clone(); +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/RegexpTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/RegexpTokenizer.java new file mode 100644 index 00000000000..d0cb456e0c0 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/RegexpTokenizer.java @@ -0,0 +1,63 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.sonar.channel.CodeReader; + +public class RegexpTokenizer extends NotThreadSafeTokenizer{ + + private final String tagBefore; + private final String tagAfter; + private final Matcher matcher; + private final StringBuilder tmpBuilder = new StringBuilder(); + + /** + * @param tagBefore + * Html tag to add before the token + * @param tagAfter + * Html tag to add after the token + * @param regexp + * Regular expression which must be used to match token + */ + public RegexpTokenizer(String tagBefore, String tagAfter, String regexp) { + this.tagBefore = tagBefore; + this.tagAfter = tagAfter; + this.matcher = Pattern.compile(regexp).matcher(""); + } + + @Override + public boolean consume(CodeReader code, HtmlCodeBuilder codeBuilder) { + if (code.popTo(matcher, tmpBuilder) > 0) { + codeBuilder.appendWithoutTransforming(tagBefore); + codeBuilder.append(tmpBuilder); + codeBuilder.appendWithoutTransforming(tagAfter); + tmpBuilder.delete(0, tmpBuilder.length()); + return true; + } + return false; + } + + public RegexpTokenizer clone() { + return new RegexpTokenizer(tagBefore, tagAfter, matcher.pattern().pattern()); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/Renderer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/Renderer.java new file mode 100644 index 00000000000..eaf572caecc --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/Renderer.java @@ -0,0 +1,31 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.io.Reader; +import java.util.List; + +import org.sonar.channel.Channel; + +public abstract class Renderer { + + public abstract String render(Reader code, List<? extends Channel<HtmlCodeBuilder>> tokenizers); + +}
\ No newline at end of file diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/StringTokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/StringTokenizer.java new file mode 100644 index 00000000000..7830575ea3f --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/StringTokenizer.java @@ -0,0 +1,40 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import org.sonar.channel.CodeReader; + +public class StringTokenizer extends Tokenizer { + + private final LiteralTokenizer tokenizer; + + public StringTokenizer(String tagBefore, String tagAfter) { + tokenizer = new LiteralTokenizer(tagBefore, tagAfter); + } + + public StringTokenizer() { + tokenizer = new LiteralTokenizer("", ""); + } + + @Override + public boolean consume(CodeReader code, HtmlCodeBuilder output) { + return tokenizer.consume(code, output); + } +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/SynhtaxHighlightingException.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/SynhtaxHighlightingException.java new file mode 100644 index 00000000000..e7cdfa79639 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/SynhtaxHighlightingException.java @@ -0,0 +1,36 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +public class SynhtaxHighlightingException extends RuntimeException { + + public SynhtaxHighlightingException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + + public SynhtaxHighlightingException(String arg0) { + super(arg0); + } + + public SynhtaxHighlightingException(Throwable arg0) { + super(arg0); + } + +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/Tokenizer.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/Tokenizer.java new file mode 100644 index 00000000000..ee01df95b5b --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/Tokenizer.java @@ -0,0 +1,31 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import org.sonar.channel.Channel; + +/** + * A token highlighter is in charge to optionally consume the next characters (token) of a CodeReader + * and to add the highlighted token to an HtmlCodeBuilder. + * + * IMPORTANT: a Tokenizer must be THREAD-SAFE otherwise see NotThreadSafeTokenizer + */ +public abstract class Tokenizer extends Channel<HtmlCodeBuilder> { +} diff --git a/sonar-colorizer/src/main/java/org/sonar/colorizer/TokenizerDispatcher.java b/sonar-colorizer/src/main/java/org/sonar/colorizer/TokenizerDispatcher.java new file mode 100644 index 00000000000..60c2b3be737 --- /dev/null +++ b/sonar-colorizer/src/main/java/org/sonar/colorizer/TokenizerDispatcher.java @@ -0,0 +1,65 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.colorizer; + +import java.util.List; + +import org.sonar.channel.Channel; +import org.sonar.channel.CodeReader; + +public class TokenizerDispatcher { + + private Channel[] tokenizers; + + public TokenizerDispatcher(Channel<HtmlCodeBuilder>... tokenizers) { + this.tokenizers = tokenizers; + } + + public TokenizerDispatcher(List<Channel<HtmlCodeBuilder>> tokenizers) { + this.tokenizers = tokenizers.toArray(new Channel[0]); // NOSONAR performance is not an issue here + } + + public final String colorize(String code) { + HtmlCodeBuilder colorizedCode = new HtmlCodeBuilder(); + colorize(new CodeReader(code), colorizedCode); + return colorizedCode.toString(); + } + + public final void colorize(CodeReader code, HtmlCodeBuilder colorizedCode) { + cloneNotThreadSafeTokenizers(); + nextChar: while (code.peek() != -1) { + for (Channel<HtmlCodeBuilder> codeTokenizer : tokenizers) { + if (codeTokenizer.consume(code, colorizedCode)) { + continue nextChar; + } + } + colorizedCode.append((char) code.pop()); + } + code.close(); + } + + private void cloneNotThreadSafeTokenizers() { + for (int i = 0; i < tokenizers.length; i++) { + if (tokenizers[i] instanceof NotThreadSafeTokenizer) { + tokenizers[i] = ((NotThreadSafeTokenizer) tokenizers[i]).clone(); + } + } + } +} diff --git a/sonar-colorizer/src/main/resources/sonar-colorizer.css b/sonar-colorizer/src/main/resources/sonar-colorizer.css new file mode 100644 index 00000000000..5e6807df539 --- /dev/null +++ b/sonar-colorizer/src/main/resources/sonar-colorizer.css @@ -0,0 +1,61 @@ +.code { + font-size: 12px; +} + +.code pre { + font-family: Monospace; + margin: 0; + padding: 0 5px; + color: #111; + margin: 0; +} + +/* for example java annotations */ +.code .a { + color: #808000; +} + +/* constants */ +.code .c { + color: #660E80; + font-style: italic; + font-weight: bold; +} + +/* javadoc */ +.code .j { + color: #666666; + font-style: normal; +} + +/* classic comment */ +.code .cd { + color: #666666; + font-style: italic; +} + +/* C++ doc */ +.code .cppd { + color: #666666; + font-style: italic; +} + +/* keyword */ +.code .k { + color: #000080; + font-weight: bold; +} + +/* string */ +.code .s { + color: #008000; + font-weight: bold; +} + +/* keyword light*/ +.code .h { + color: #000080; + font-weight: normal; +} + + |