001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2009 SonarSource SA 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 */ 020 package org.sonar.colorizer; 021 022 import org.apache.commons.io.IOUtils; 023 024 import java.io.IOException; 025 import java.io.InputStream; 026 027 public class HtmlDecorator extends Tokenizer { 028 029 private static final String CSS_PATH = "/sonar-colorizer.css"; 030 031 private HtmlOptions options; 032 private int lineId = 1; 033 private boolean checked = false; 034 private boolean beginOfLine = true; 035 private boolean endOfLine = false; 036 037 public HtmlDecorator(HtmlOptions options) { 038 super(null, null); 039 this.options = options; 040 this.lineId = options.getFirstLineId(); 041 } 042 043 @Override 044 public String getTagBeginOfFile() { 045 StringBuilder sb = new StringBuilder(); 046 if (options.isGenerateHtmlHeader()) { 047 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\">"); 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>"); 056 return sb.toString(); 057 } 058 059 @Override 060 public String getTagEndOfFile() { 061 StringBuilder sb = new StringBuilder(); 062 sb.append("</pre></td></tr></tbody></table>"); 063 if (options.isGenerateHtmlHeader()) { 064 sb.append("</body></html>"); 065 } 066 return sb.toString(); 067 } 068 069 @Override 070 public String getTagBefore() { 071 StringBuilder sb = new StringBuilder(); 072 if (beginOfLine) { 073 sb.append("<tr id=\""); 074 sb.append(lineId++); 075 sb.append("\"><td><pre>"); 076 } 077 return sb.toString(); 078 } 079 080 @Override 081 public String getTagAfter() { 082 if (endOfLine) { 083 return "</pre></td></tr>"; 084 } 085 return ""; 086 } 087 088 @Override 089 public boolean hasNextToken(CodeReader code) { 090 if (checked) { 091 checked = false; 092 return false; 093 } 094 int lastChar = code.lastChar(); 095 beginOfLine = (lastChar == -1 || lastChar == (int) '\n'); 096 097 int peek = code.peek(); 098 endOfLine = (peek == (int) '\n' || peek == -1); 099 100 checked = beginOfLine || endOfLine; 101 return checked; 102 } 103 104 @Override 105 public String nextToken(CodeReader code) { 106 return ""; 107 } 108 109 public static String getCss() { 110 InputStream input = null; 111 try { 112 input = HtmlRenderer.class.getResourceAsStream(CSS_PATH); 113 return IOUtils.toString(input); 114 115 } catch (IOException e) { 116 throw new ColorizerException("Sonar Colorizer CSS file not found: " + CSS_PATH, e); 117 118 } finally { 119 IOUtils.closeQuietly(input); 120 } 121 } 122 }