PageRenderTime 31ms CodeModel.GetById 14ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/testability-explorer/src/main/java/com/google/test/metric/report/SourceReportGenerator.java

http://testability-explorer.googlecode.com/
Java | 205 lines | 175 code | 15 blank | 15 comment | 14 complexity | ff243aa8f5dbf1dacd7886680710386d MD5 | raw file
  1/*
  2 * Copyright 2007 Google Inc.
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5 * use this file except in compliance with the License. You may obtain a copy of
  6 * the License at
  7 *
  8 * http://www.apache.org/licenses/LICENSE-2.0
  9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 13 * License for the specific language governing permissions and limitations under
 14 * the License.
 15 */
 16package com.google.test.metric.report;
 17
 18import java.io.File;
 19import java.io.FileOutputStream;
 20import java.io.IOException;
 21import java.io.InputStream;
 22import java.io.OutputStream;
 23import java.io.OutputStreamWriter;
 24import java.util.Date;
 25import java.util.HashMap;
 26import java.util.List;
 27import java.util.Map;
 28
 29import com.google.test.metric.ClassCost;
 30import com.google.test.metric.Cost;
 31import com.google.test.metric.CostModel;
 32import com.google.test.metric.MethodCost;
 33import com.google.test.metric.ViolationCost;
 34import com.google.test.metric.WeightedAverage;
 35import com.google.test.metric.report.Source.Line;
 36
 37import freemarker.ext.beans.BeanModel;
 38import freemarker.template.Configuration;
 39import freemarker.template.DefaultObjectWrapper;
 40import freemarker.template.SimpleNumber;
 41import freemarker.template.Template;
 42import freemarker.template.TemplateException;
 43import freemarker.template.TemplateMethodModelEx;
 44import freemarker.template.TemplateModel;
 45import freemarker.template.TemplateModelException;
 46
 47public class SourceReportGenerator implements ReportGenerator {
 48
 49  private class PrintCostMethod implements TemplateMethodModelEx {
 50    @SuppressWarnings("unchecked")
 51    public Object exec(List arguments) throws TemplateModelException {
 52      TemplateModel model = (TemplateModel) arguments.get(0);
 53      if (model instanceof SimpleNumber) {
 54        SimpleNumber number = (SimpleNumber) model;
 55        return "" + number;
 56      } else if (model instanceof BeanModel) {
 57        BeanModel arg0 = (BeanModel) model;
 58        Cost cost = (Cost) arg0.getAdaptedObject(Cost.class);
 59        return "Cost: " + costModel.computeOverall(cost) + " [" + cost + "]";
 60      } else {
 61        throw new IllegalStateException();
 62      }
 63    }
 64  }
 65
 66  private class OverallCostMethod implements TemplateMethodModelEx {
 67    @SuppressWarnings("unchecked")
 68    public Object exec(List arguments) throws TemplateModelException {
 69      TemplateModel model = (TemplateModel) arguments.get(0);
 70      if (model instanceof SimpleNumber) {
 71        SimpleNumber number = (SimpleNumber) model;
 72        return number;
 73      } else if (model instanceof BeanModel) {
 74        BeanModel arg0 = (BeanModel) model;
 75        Cost cost = (Cost) arg0.getAdaptedObject(Cost.class);
 76        return costModel.computeOverall(cost);
 77      } else {
 78        throw new IllegalStateException();
 79      }
 80    }
 81  }
 82
 83  private final String PREFIX = "com/google/test/metric/report/source/";
 84  private final SourceLoader sourceLoader;
 85  private final GradeCategories grades;
 86  private final File directory;
 87  private final Configuration cfg;
 88  private final Map<String, PackageReport> packageReports = new HashMap<String, PackageReport>();
 89  private final ProjectReport projectByClassReport;
 90  private final ProjectReport projectByPackageReport;
 91  private final CostModel costModel;
 92
 93  public SourceReportGenerator(GradeCategories grades, SourceLoader sourceLoader,
 94      File outputDirectory, CostModel costModel, Date currentTime,
 95      int worstCount, Configuration cfg) {
 96    this.grades = grades;
 97    this.sourceLoader = sourceLoader;
 98    this.directory = outputDirectory;
 99    this.costModel = costModel;
100    this.cfg = cfg;
101    cfg.setTemplateLoader(new ClassPathTemplateLoader(PREFIX));
102    cfg.setObjectWrapper(new DefaultObjectWrapper());
103    try {
104      cfg.setSharedVariable("maxExcellentCost", grades.getMaxExcellentCost());
105      cfg.setSharedVariable("maxAcceptableCost", grades.getMaxAcceptableCost());
106      cfg.setSharedVariable("currentTime", currentTime);
107      cfg.setSharedVariable("computeOverallCost", new OverallCostMethod());
108      cfg.setSharedVariable("printCost", new PrintCostMethod());
109    } catch (TemplateModelException e) {
110      throw new RuntimeException(e);
111    }
112    projectByClassReport = new ProjectReport("index", grades,
113        new WeightedAverage());
114    projectByClassReport.setMaxUnitCosts(worstCount);
115    projectByPackageReport = new ProjectReport("index", grades,
116        new WeightedAverage());
117  }
118
119  public void printHeader() {
120    directory.mkdirs();
121    writeCSS();
122  }
123
124  private void writeCSS() {
125    try {
126      InputStream is = getClass().getResourceAsStream("source/te.css");
127      OutputStream os = new FileOutputStream(new File(directory, "te.css"));
128      int size;
129      byte[] buf = new byte[2048];
130      while ((size = is.read(buf)) > 0) {
131        os.write(buf, 0, size);
132      }
133      os.close();
134      is.close();
135    } catch (IOException e) {
136      throw new RuntimeException(e);
137    }
138  }
139
140  public void printFooter() {
141    for (PackageReport packageReport : packageReports.values()) {
142      projectByPackageReport.addPackage(packageReport.getName(), packageReport
143          .getOverallCost());
144      write("Package.html", packageReport, "package_");
145    }
146    write("Project.html", new ProjectSummaryReport(projectByClassReport,
147        projectByPackageReport), new File(directory, "index.html"));
148  }
149
150  public void addClassCost(ClassCost classCost) {
151    ClassReport classReport = createClassReport(classCost);
152    write("Class.html", classReport, "class_");
153    String packageName = classCost.getPackageName();
154    PackageReport packageReport = packageReports.get(packageName);
155    if (packageReport == null) {
156      packageReport = new PackageReport(packageName, grades,
157          new WeightedAverage());
158      packageReports.put(packageName, packageReport);
159    }
160    packageReport.addClass(classCost.getClassName(), costModel
161        .computeClass(classCost));
162  }
163
164  public void write(String templateName, SummaryGraphReport<?> report,
165      String prefix) {
166    File file = new File(directory, prefix + report.getName() + ".html");
167    write(templateName, report, file);
168  }
169
170  public void write(String templateName, Object report, File file) {
171    try {
172      Template template = cfg.getTemplate(templateName);
173      FileOutputStream os = new FileOutputStream(file);
174      OutputStreamWriter out = new OutputStreamWriter(os);
175      template.process(report, out);
176      out.close();
177    } catch (IOException e) {
178      throw new RuntimeException(e);
179    } catch (TemplateException e) {
180      throw new RuntimeException(e);
181    }
182  }
183
184  ClassReport createClassReport(ClassCost classCost) {
185    Source source = sourceLoader.load(classCost.getClassName());
186    ClassReport classReport = new ClassReport(classCost.getClassName(), source,
187        grades, new WeightedAverage(
188            CostModel.WEIGHT_TO_EMPHASIZE_EXPENSIVE_METHODS));
189    for (MethodCost method : classCost.getMethods()) {
190      int overallCost = costModel.computeOverall(method.getTotalCost());
191      classReport.addMethod(method.getMethodName(), method
192          .getMethodLineNumber(), overallCost, method.getTotalCost(), method
193          .getCost());
194      Line line = source.getLine(method.getMethodLineNumber());
195      line.addMethodCost(method);
196      for (ViolationCost violation : method.getExplicitViolationCosts()) {
197        line = source.getLine(violation.getLocation().getLineNumber());
198        line.addCost(violation.getCost());
199      }
200    }
201    projectByClassReport.addClass(classCost.getClassName(), classReport
202        .getOverallCost());
203    return classReport;
204  }
205}