001/*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019 */
020package org.sonar.colorizer;
021
022import org.apache.commons.io.IOUtils;
023import org.sonar.channel.CodeReader;
024
025import java.io.IOException;
026import java.io.InputStream;
027
028public class HtmlDecorator extends Tokenizer {
029
030  private static final String CSS_PATH = "/sonar-colorizer.css";
031
032  private HtmlOptions options;
033  private int lineId;
034
035  private static final int LF = '\n';
036  private static final int CR = '\r';
037
038  public HtmlDecorator(HtmlOptions options) {
039    this.options = options;
040    this.lineId = options.getFirstLineId();
041  }
042
043  public String getTagBeginOfFile() {
044    StringBuilder sb = new StringBuilder();
045    if (options.isGenerateHtmlHeader()) {
046      sb.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
047          + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html><head><style type=\"text/css\">");
048      sb.append(getCss());
049      sb.append("</style></head><body>");
050    }
051    sb.append("<table class=\"code\" id=\"");
052    if (options.getTableId() != null) {
053      sb.append(options.getTableId());
054    }
055    sb.append("\"><tbody><tr id=\"").append(lineId++).append("\"><td><pre>");
056    return sb.toString();
057  }
058
059  public String getTagEndOfFile() {
060    StringBuilder sb = new StringBuilder();
061    sb.append("</pre></td></tr></tbody></table>");
062    if (options.isGenerateHtmlHeader()) {
063      sb.append("</body></html>");
064    }
065    return sb.toString();
066  }
067
068  public String getTagBefore() {
069    return "<tr id=\"" + lineId++ + "\"><td><pre>";
070  }
071
072  public String getTagAfter() {
073    return "</pre></td></tr>";
074  }
075
076  @Override
077  public boolean consume(CodeReader code, HtmlCodeBuilder codeBuilder) {
078    int lineNumber = code.getLinePosition();
079    if (code.peek() == LF || code.peek() == CR) {
080      code.pop();
081      if (lineNumber != code.getLinePosition()) {
082        codeBuilder.appendWithoutTransforming(getTagAfter());
083        codeBuilder.appendWithoutTransforming(getTagBefore());
084      }
085      return true;
086    }
087    return false;
088  }
089
090  public static String getCss() {
091    InputStream input = null;
092    try {
093      input = HtmlRenderer.class.getResourceAsStream(CSS_PATH);
094      return IOUtils.toString(input);
095
096    } catch (IOException e) {
097      throw new SynhtaxHighlightingException("Sonar Colorizer CSS file not found: " + CSS_PATH, e);
098
099    } finally {
100      IOUtils.closeQuietly(input);
101    }
102  }
103}