##### Coverage Report - org.owasp.dependencycheck.reporting.ReportGenerator

Classes in this File | Line Coverage | Branch Coverage | Complexity
ReportGenerator |
54% | 45/82
15% | 6/38
| 5.333333333333333;5.333
ReportGenerator$Format |
0% | 0/5
N/A | N/A
| 5.333333333333333;5.333

1 |  |
     /*
2 |  |
      * This file is part of dependency-check-core.
3 |  |
      *
4 |  |
      * Dependency-check-core is free software: you can redistribute it and/or modify it
5 |  |
      * under the terms of the GNU General Public License as published by the Free
6 |  |
      * Software Foundation, either version 3 of the License, or (at your option) any
7 |  |
      * later version.
8 |  |
      *
9 |  |
      * Dependency-check-core is distributed in the hope that it will be useful, but
10 |  |
      * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 |  |
      * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 |  |
      * details.
13 |  |
      *
14 |  |
      * You should have received a copy of the GNU General Public License along with
15 |  |
      * dependency-check-core. If not, see http://www.gnu.org/licenses/.
16 |  |
      *
17 |  |
      * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
18 |  |
      */
19 |  |
     package org.owasp.dependencycheck.reporting;
20 |  |
21 |  |
     import java.io.FileInputStream;
22 |  |
     import java.io.File;
23 |  |
     import java.io.FileNotFoundException;
24 |  |
     import java.io.FileOutputStream;
25 |  |
     import java.io.IOException;
26 |  |
     import java.io.InputStream;
27 |  |
     import java.io.InputStreamReader;
28 |  |
     import java.io.OutputStream;
29 |  |
     import java.io.OutputStreamWriter;
30 |  |
     import java.util.List;
31 |  |
     import java.util.logging.Level;
32 |  |
     import java.util.logging.Logger;
33 |  |
     import org.apache.velocity.app.VelocityEngine;
34 |  |
     import org.apache.velocity.context.Context;
35 |  |
     import org.apache.velocity.runtime.RuntimeConstants;
36 |  |
     import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
37 |  |
     import org.apache.velocity.tools.ToolManager;
38 |  |
     import org.apache.velocity.tools.config.EasyFactoryConfiguration;
39 |  |
     import org.owasp.dependencycheck.analyzer.Analyzer;
40 |  |
     import org.owasp.dependencycheck.dependency.Dependency;
41 |  |
42 |  |
     /**
43 |  |
      * The ReportGenerator is used to, as the name implies, generate reports.
44 |  |
      * Internally the generator uses the Velocity Templating Engine. The
45 |  |
      * ReportGenerator exposes a list of Dependencies to the template when
46 |  |
      * generating the report.
47 |  |
      *
48 |  |
      * @author Jeremy Long (jeremy.long@owasp.org)
49 |  |
      */
50 |  |
     public class ReportGenerator {
51 |  |
52 |  |
         /**
53 |  |
          * An enumeration of the report formats.
54 |  |
          */
55 | 0 |
         public enum Format {
56 |  |
57 |  |
             /**
58 |  |
              * Generate all reports.
59 |  |
              */
60 | 0 |
             ALL,
61 |  |
             /**
62 |  |
              * Generate XML report.
63 |  |
              */
64 | 0 |
             XML,
65 |  |
             /**
66 |  |
              * Generate HTML report.
67 |  |
              */
68 | 0 |
             HTML,
69 |  |
             /**
70 |  |
              * Generate HTML Vulnerability report.
71 |  |
              */
72 | 0 |
             VULN
73 |  |
         }
74 |  |
         /**
75 |  |
          * The Velocity Engine.
76 |  |
          */
77 |  |
         private final VelocityEngine engine;
78 |  |
         /**
79 |  |
          * The Velocity Engine Context.
80 |  |
          */
81 |  |
         private final Context context;
82 |  |
83 |  |
         /**
84 |  |
          * Constructs a new ReportGenerator.
85 |  |
          *
86 |  |
          * @param applicationName the application name being analyzed
87 |  |
          * @param dependencies the list of dependencies
88 |  |
          * @param analyzers the list of analyzers used.
89 |  |
          */
90 | 1 |
         public ReportGenerator(String applicationName, List<Dependency> dependencies, List<Analyzer> analyzers) {
91 | 1 |
             engine = createVelocityEngine();
92 | 1 |
             context = createContext();
93 |  |
94 | 1 |
             engine.init();
95 |  |
96 | 1 |
             context.put("applicationName", applicationName);
97 | 1 |
             context.put("dependencies", dependencies);
98 | 1 |
             context.put("analyzers", analyzers);
99 | 1 |
         }
100 |  |
101 |  |
         /**
102 |  |
          * Creates a new Velocity Engine.
103 |  |
          *
104 |  |
          * @return a velocity engine.
105 |  |
          */
106 |  |
         private VelocityEngine createVelocityEngine() {
107 | 1 |
             final VelocityEngine ve = new VelocityEngine();
108 | 1 |
             ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, VelocityLoggerRedirect.class.getName());
109 | 1 |
             ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
110 | 1 |
             ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
111 | 1 |
             return ve;
112 |  |
         }
113 |  |
114 |  |
         /**
115 |  |
          * Creates a new Velocity Context initialized with escape and date tools.
116 |  |
          *
117 |  |
          * @return a Velocity Context.
118 |  |
          */
119 |  |
         @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RV_RETURN_VALUE_IGNORED_INFERRED",
120 |  |
                 justification = "No plan to fix this style issue")
121 |  |
         private Context createContext() {
122 | 1 |
             final ToolManager manager = new ToolManager();
123 | 1 |
             final Context c = manager.createContext();
124 | 1 |
             final EasyFactoryConfiguration config = new EasyFactoryConfiguration();
125 | 1 |
             config.addDefaultTools();
126 | 1 |
             config.toolbox("application").tool("esc", "org.apache.velocity.tools.generic.EscapeTool").tool("org.apache.velocity.tools.generic.DateTool");
127 | 1 |
             manager.configure(config);
128 | 1 |
             return c;
129 |  |
         }
130 |  |
131 |  |
         /**
132 |  |
          * Generates the Dependency Reports for the identified dependencies.
133 |  |
          *
134 |  |
          * @param outputDir the path where the reports should be written
135 |  |
          * @param format the format the report should be written in
136 |  |
          * @throws IOException is thrown when the template file does not exist
137 |  |
          * @throws Exception is thrown if there is an error writing out the reports.
138 |  |
          */
139 |  |
         public void generateReports(String outputDir, Format format) throws IOException, Exception {
140 | 0 |
             if (format == Format.XML || format == Format.ALL) {
141 | 0 |
                 generateReport("XmlReport", outputDir + File.separator + "DependencyCheck-Report.xml");
142 |  |
             }
143 | 0 |
             if (format == Format.HTML || format == Format.ALL) {
144 | 0 |
                 generateReport("HtmlReport", outputDir + File.separator + "DependencyCheck-Report.html");
145 |  |
             }
146 | 0 |
             if (format == Format.VULN || format == Format.ALL) {
147 | 0 |
                 generateReport("VulnerabilityReport", outputDir + File.separator + "DependencyCheck-Vulnerability.html");
148 |  |
             }
149 | 0 |
         }
150 |  |
151 |  |
         /**
152 |  |
          * Generates the Dependency Reports for the identified dependencies.
153 |  |
          *
154 |  |
          * @param outputDir the path where the reports should be written
155 |  |
          * @param outputFormat the format the report should be written in (XML,
156 |  |
          * HTML, ALL)
157 |  |
          * @throws IOException is thrown when the template file does not exist
158 |  |
          * @throws Exception is thrown if there is an error writing out the reports.
159 |  |
          */
160 |  |
         public void generateReports(String outputDir, String outputFormat) throws IOException, Exception {
161 | 0 |
             final String format = outputFormat.toUpperCase();
162 | 0 |
             if (format.matches("^(XML|HTML|VULN|ALL)$")) {
163 | 0 |
                 if ("XML".equalsIgnoreCase(format)) {
164 | 0 |
                     generateReports(outputDir, Format.XML);
165 |  |
                 }
166 | 0 |
                 if ("HTML".equalsIgnoreCase(format)) {
167 | 0 |
                     generateReports(outputDir, Format.HTML);
168 |  |
                 }
169 | 0 |
                 if ("VULN".equalsIgnoreCase(format)) {
170 | 0 |
                     generateReports(outputDir, Format.VULN);
171 |  |
                 }
172 | 0 |
                 if ("ALL".equalsIgnoreCase(format)) {
173 | 0 |
                     generateReports(outputDir, Format.ALL);
174 |  |
                 }
175 |  |
             }
176 | 0 |
         }
177 |  |
178 |  |
         /**
179 |  |
          * Generates a report from a given Velocity Template. The template name
180 |  |
          * provided can be the name of a template contained in the jar file, such as
181 |  |
          * 'XmlReport' or 'HtmlReport', or the template name can be the path to a
182 |  |
          * template file.
183 |  |
          *
184 |  |
          * @param templateName the name of the template to load.
185 |  |
          * @param outFileName the filename and path to write the report to.
186 |  |
          * @throws IOException is thrown when the template file does not exist.
187 |  |
          * @throws Exception is thrown when an exception occurs.
188 |  |
          */
189 |  |
         protected void generateReport(String templateName, String outFileName) throws IOException, Exception {
190 | 1 |
             InputStream input = null;
191 | 1 |
             String templatePath = null;
192 | 1 |
             final File f = new File(templateName);
193 | 1 |
             if (f.exists() && f.isFile()) {
194 |  |
                 try {
195 | 0 |
                     templatePath = templateName;
196 | 0 |
                     input = new FileInputStream(f);
197 | 0 |
                 } catch (FileNotFoundException ex) {
198 | 0 |
                     final String msg = "Unable to generate the report, the report template file could not be found.";
199 | 0 |
                     Logger.getLogger(ReportGenerator.class.getName()).log(Level.SEVERE, msg);
200 | 0 |
                     Logger.getLogger(ReportGenerator.class.getName()).log(Level.FINE, null, ex);
201 | 0 |
                 }
202 |  |
             } else {
203 | 1 |
                 templatePath = "templates/" + templateName + ".vsl";
204 | 1 |
                 input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
205 |  |
             }
206 | 1 |
             if (input == null) {
207 | 0 |
                 throw new IOException("Template file doesn't exist");
208 |  |
             }
209 |  |
210 | 1 |
             final InputStreamReader reader = new InputStreamReader(input, "UTF-8");
211 | 1 |
             OutputStreamWriter writer = null;
212 | 1 |
             OutputStream outputStream = null;
213 |  |
214 |  |
             try {
215 | 1 |
                 final File outDir = new File(outFileName).getParentFile();
216 | 1 |
                 if (!outDir.exists()) {
217 | 0 |
                     final boolean created = outDir.mkdirs();
218 | 0 |
                     if (!created) {
219 | 0 |
                         throw new Exception("Unable to create directory '" + outDir.getAbsolutePath() + "'.");
220 |  |
                     }
221 |  |
                 }
222 |  |
223 | 1 |
                 outputStream = new FileOutputStream(outFileName);
224 | 1 |
                 writer = new OutputStreamWriter(outputStream, "UTF-8");
225 |  |
226 | 1 |
                 if (!engine.evaluate(context, writer, templatePath, reader)) {
227 | 0 |
                     throw new Exception("Failed to convert the template into html.");
228 |  |
                 }
229 | 1 |
                 writer.flush();
230 |  |
             } finally {
231 | 1 |
                 if (writer != null) {
232 |  |
                     try {
233 | 1 |
                         writer.close();
234 | 0 |
                     } catch (Exception ex) {
235 | 0 |
                         Logger.getLogger(ReportGenerator.class.getName()).log(Level.FINEST, null, ex);
236 | 1 |
                     }
237 |  |
                 }
238 | 1 |
                 if (outputStream != null) {
239 |  |
                     try {
240 | 1 |
                         outputStream.close();
241 | 0 |
                     } catch (Exception ex) {
242 | 0 |
                         Logger.getLogger(ReportGenerator.class.getName()).log(Level.FINEST, null, ex);
243 | 1 |
                     }
244 |  |
                 }
245 |  |
                 try {
246 | 1 |
                     reader.close();
247 | 0 |
                 } catch (Exception ex) {
248 | 0 |
                     Logger.getLogger(ReportGenerator.class.getName()).log(Level.FINEST, null, ex);
249 | 1 |
                 }
250 | 0 |
             }
251 | 1 |
         }
252 |  |
     }