changeset 4:730c5549c0f9

2012-01-10 Pavel Tisnovsky <ptisnovs@redhat.com> * src/FileUtils.java: Added new helper class. * src/ReportGenerator.java: Updated to use HTML templates for test coverage report. * Makefile: Updated
author Pavel Tisnovsky <ptisnovs@redhat.com>
date Tue, 10 Jan 2012 14:08:47 +0100
parents 61f453c6b172
children 5ef74c026b81
files ChangeLog Makefile src/FileUtils.java src/ReportGenerator.java
diffstat 4 files changed, 407 insertions(+), 143 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Jan 09 14:57:59 2012 +0100
+++ b/ChangeLog	Tue Jan 10 14:08:47 2012 +0100
@@ -1,3 +1,12 @@
+2012-01-10  Pavel Tisnovsky  <ptisnovs@redhat.com>
+
+	* src/FileUtils.java:
+	Added new helper class.
+	* src/ReportGenerator.java:
+	Updated to use HTML templates for test coverage report.
+	* Makefile:
+	Updated
+
 2012-01-09  Pavel Tisnovsky  <ptisnovs@redhat.com>
 
 	* src/index.html:
--- a/Makefile	Mon Jan 09 14:57:59 2012 +0100
+++ b/Makefile	Tue Jan 10 14:08:47 2012 +0100
@@ -73,7 +73,8 @@
 	$(CLASSDIR)/PrintClassList.class \
 	$(CLASSDIR)/PrintPublicMethods.class \
 	$(CLASSDIR)/PrintTestCoverage.class \
-	$(CLASSDIR)/ReportGenerator.class
+	$(CLASSDIR)/ReportGenerator.class \
+	$(CLASSDIR)/FileUtils.class
 
 api_class_list:	$(REPORTDIR) $(REPORTDIR)/$(ALL_CLASS_LIST)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FileUtils.java	Tue Jan 10 14:08:47 2012 +0100
@@ -0,0 +1,233 @@
+/*
+  Test coverage tool.
+
+   Copyright (C) 2012 Red Hat
+
+This tool is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This tool 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this tool; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Basic file utilities to avoid boring file handling.
+ *
+ * @author Pavel Tisnovsky
+ */
+class FileUtils
+{
+    /**
+     * Read content of given text file and return it as list of strings. No
+     * exception is thrown during reading.
+     * 
+     * @param fileName
+     *            name of file to be read
+     * @return list of string containing content of text file
+     */
+    static List<String> readTextFile(String fileName)
+    {
+        BufferedReader reader = null;
+        List<String> out = new LinkedList<String>();
+        try
+        {
+            // try to open file for reading
+            reader = new BufferedReader(new FileReader(fileName));
+            readAllLinesFromTextFile(reader, out);
+        }
+        catch (FileNotFoundException e)
+        {
+            // might happen - empty list is returned in this case
+            e.printStackTrace();
+        }
+        catch (IOException e)
+        {
+            // might happen - empty list is returned in this case
+            // make sure the list is empty
+            out.clear();
+            e.printStackTrace();
+        }
+        finally
+        {
+            closeBufferedReader(reader);
+        }
+        // return list containing content of text file
+        return out;
+    }
+
+    /**
+     * Write list of string to a file with given name. No exception is thrown
+     * during reading.
+     * 
+     * @param fileName
+     *            name of file to be read
+     * @param lines
+     *            of string containing content of text file
+     */
+    static void writeTextFile(String fileName, List<String> lines)
+    {
+        BufferedWriter fout = null;
+        try
+        {
+            fout = new BufferedWriter(new FileWriter(fileName));
+            // write all lines to a text file
+            writeAllLinesToTextFile(fout, lines);
+        }
+        catch (IOException e)
+        {
+            // might happen - empty list is returned in this case
+            e.printStackTrace();
+        }
+        finally
+        {
+            closeBufferedWriter(fout);
+        }
+    }
+
+    /**
+     * Write list of string to a file with given name. No exception is thrown
+     * during reading.
+     *
+     * @param reportDirectory
+     * @param string
+     * @param lines of string containing content of text file
+     */
+    static void writeTextFile(String reportDirectory, String string, List<String> lines)
+    {
+        writeTextFile(new File(reportDirectory, string), lines);
+    }
+
+    /**
+     * Write list of string to a file with given name. No exception is thrown
+     * during reading.
+     * 
+     * @param file
+     *            representing file name
+     * @param lines
+     *            of string containing content of text file
+     */
+    static void writeTextFile(File file, List<String> lines)
+    {
+        writeTextFile(file.getPath(), lines);
+    }
+
+    /**
+     * Try to close buffered reader.
+     *
+     * @param bufferedReader instance of buffered reader or null
+     */
+    private static void closeBufferedReader(BufferedReader bufferedReader)
+    {
+        // try to close the buffered reader
+        try
+        {
+            if (bufferedReader != null)
+            {
+                bufferedReader.close();
+            }
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Try to close buffered reader.
+     * 
+     * @param bufferedWriter
+     *            instance of buffered writer or null
+     */
+    private static void closeBufferedWriter(BufferedWriter bufferedWriter)
+    {
+        // try to close the buffered writer
+        try
+        {
+            if (bufferedWriter != null)
+            {
+                bufferedWriter.close();
+            }
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Read all lines from text file and add them to a list of strings.
+     * 
+     * @param bufferedReader
+     *            instance of buffered reader
+     * @param lines
+     *            list of string to be filled
+     * @throws IOException
+     *             thrown if an I/O error occurs
+     */
+    private static void readAllLinesFromTextFile(BufferedReader bufferedReader, List<String> lines) throws IOException
+    {
+        String line;
+        // read lines from a text file
+        while ((line = bufferedReader.readLine()) != null)
+        {
+            lines.add(line);
+        }
+    }
+
+    /**
+     * Write content of the list of strings to a file.
+     * 
+     * @param bufferedWriter
+     *            instance of buffered writer
+     * @param lines
+     *            list of string
+     * @throws IOException
+     *             thrown if an I/O error occurs
+     */
+    private static void writeAllLinesToTextFile(BufferedWriter bufferedWriter, List<String> lines) throws IOException
+    {
+        for (String line : lines)
+        {
+            bufferedWriter.write(line);
+            // new line character should be added after each string
+            bufferedWriter.write('\n');
+        }
+    }
+
+}
--- a/src/ReportGenerator.java	Mon Jan 09 14:57:59 2012 +0100
+++ b/src/ReportGenerator.java	Tue Jan 10 14:08:47 2012 +0100
@@ -43,6 +43,8 @@
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
 
@@ -56,131 +58,180 @@
  */
 public class ReportGenerator
 {
+    /**
+     * Read all classes from a file containing its list.
+     * 
+     * @param allClassListFileName
+     * @return
+     */
     private static Set<String> readAllClasses(String allClassListFileName)
     {
-        BufferedReader reader = null;
+        // read file content
+        List<String> fileContent = FileUtils.readTextFile(allClassListFileName);
+        // set of classes should be sorted
         Set<String> allClasses = new TreeSet<String>();
-        try
-        {
-            reader = new BufferedReader(new FileReader(allClassListFileName));
-            String line;
-            while ((line = reader.readLine()) != null)
-            {
-                allClasses.add(line);
-            }
-        }
-        catch (FileNotFoundException e)
-        {
-            e.printStackTrace();
-        }
-        catch (IOException e)
-        {
-            e.printStackTrace();
-        }
-        finally
-        {
-            try
-            {
-                if (reader != null)
-                {
-                    reader.close();
-                }
-            }
-            catch (IOException e)
-            {
-                e.printStackTrace();
-            }
-        }
+        allClasses.addAll(fileContent);
         return allClasses;
     }
 
-    private static Set<String> preparePackageNames(Set<String> allClasses)
-    {
-        Set<String> packages = new TreeSet<String>();
-        for (String className : allClasses)
-        {
-            String packageName = className.substring(0, className.lastIndexOf('.'));
-            if (!packageName.startsWith("com.") && !packageName.startsWith("sun"))
-            {
-                packages.add(packageName);
-            }
-        }
-        return packages;
-    }
-
+    /**
+     * Creates file "all_packages.html" which contains link to all checked
+     * packages. Structure of this file is based on template stored in
+     * "templates/all_packages_template.html".
+     * 
+     * @param reportDirectory
+     *            directory where report is generated
+     * @param allClasses
+     *            set of all classes
+     * @param packageNames
+     *            set of package names
+     */
     private static void printPackageListToFile(String reportDirectory, Set<String> allClasses, Set<String> packageNames)
     {
-        BufferedWriter fout = null;
-        try
+        List<String> template = FileUtils.readTextFile("templates/all_packages_template.html");
+        List<String> out = new LinkedList<String>();
+        for (String templateLine : template)
         {
-            fout = new BufferedWriter(new FileWriter(new File(reportDirectory, "all_packages.html")));
-            fout.write("<html>\n");
-            fout.write("<body>\n");
-            fout.write("<h1>Package list</h1>\n");
-            fout.write("<a target='ClassesListFrame' href='all_classes.html'>all classes</a><br /><br />\n");
-            for (String packageName : packageNames)
+            // replace text in template where needed
+            if ("${PACKAGE_LIST}".equals(templateLine))
+            {
+                addPackageList(packageNames, out);
+            }
+            else
             {
-                fout.write("<a target='ClassesListFrame' href='" + packageName + ".html'>" + packageName + "</a><br />\n");
+                out.add(templateLine);
             }
-            fout.write("</body>\n");
-            fout.write("</html>\n");
+        }
+        FileUtils.writeTextFile(reportDirectory, "all_packages.html", out);
+    }
+
+    /**
+     * Create file containing test coverage report for given package. Structure
+     * of this file is based on template stored in
+     * "templates/all_packages_template.html".
+     * 
+     * @param reportDirectory
+     *            directory where report is generated
+     * @param packageName
+     *            package for which the report is generated
+     * @param testedClasses
+     *            set of tested classes
+     */
+    private static void printReportForPackageToFile(String reportDirectory, String packageName, Set<String> testedClasses)
+    {
+        List<String> template = FileUtils.readTextFile("templates/package_template.html");
+        List<String> out = new LinkedList<String>();
+        for (String templateLine : template)
+        {
+            // replace text in template where needed
+            if ("${CLASS_LIST}".equals(templateLine))
+            {
+                addClassList(packageName, testedClasses, out);
+            }
+            else
+            {
+                out.add(templateLine);
+            }
         }
-        catch (IOException e)
+        FileUtils.writeTextFile(reportDirectory, packageName + ".html", out);
+    }
+
+    /**
+     * Create file containing test coverage report for all classes. Structure of
+     * this file is based on template stored in
+     * "templates/all_classes_template.html".
+     * 
+     * @param reportDirectory
+     *            directory where report is generated
+     * @param usedPackageNames
+     *            all checked package names
+     * @param testedClasses
+     *            set of tested classes
+     */
+    private static void printReportForAllClassesInOneFile(String reportDirectory, Set<String> usedPackageNames,
+                    Set<String> testedClasses)
+    {
+        List<String> template = FileUtils.readTextFile("templates/all_classes_template.html");
+        List<String> out = new LinkedList<String>();
+        for (String templateLine : template)
         {
-            e.printStackTrace();
-        }
-        finally
-        {
-            try
+            // replace text in template where needed
+            if ("${PACKAGE_AND_CLASS_LIST}".equals(templateLine))
+            {
+                addPackageAndClassList(usedPackageNames, testedClasses, out);
+            }
+            else
             {
-                if (fout != null)
-                {
-                    fout.close();
-                }
+                out.add(templateLine);
             }
-            catch (IOException e)
+        }
+        FileUtils.writeTextFile(reportDirectory, "all_classes.html", out);
+    }
+
+    /**
+     * Add list of all packages to a list of string which represents generated
+     * report.
+     * 
+     * @param packageNames
+     *            set of package names
+     * @param out
+     *            list of string which represents generated report
+     */
+    private static void addPackageList(Set<String> packageNames, List<String> out)
+    {
+        for (String packageName : packageNames)
+        {
+            out.add("<a target='ClassesListFrame' href='" + packageName + ".html'>" + packageName + "</a><br />");
+        }
+    }
+
+    /**
+     * Add list of all classes to a list of string which represents generated
+     * report.
+     * 
+     * @param packageName
+     *            package for which the report is generated
+     * @param testedClasses
+     *            set of tested classes
+     * @param out
+     *            list of string which represents generated report
+     */
+    private static void addClassList(String packageName, Set<String> testedClasses, List<String> out)
+    {
+        for (String className : testedClasses)
+        {
+            // list only classes from given package
+            if (className.startsWith(packageName))
             {
-                e.printStackTrace();
+                out.add("<a target='ResultsFrame' href='" + className + ".html'>" + className + "</a><br>");
             }
         }
     }
 
-    private static void createFileForPackage(String reportDirectory, String packageName, Set<String> testedClasses)
+    /**
+     * Add list of all packages and all its classes to a list of string which
+     * represents generated report.
+     * 
+     * @param usedPackageNames
+     *            all checked package names
+     * @param testedClasses
+     *            set of tested classes
+     * @param out
+     *            list of string which represents generated report
+     */
+    private static void addPackageAndClassList(Set<String> usedPackageNames, Set<String> testedClasses, List<String> out)
     {
-        BufferedWriter fout = null;
-        try
+        for (String packageName : usedPackageNames)
         {
-            fout = new BufferedWriter(new FileWriter(new File(reportDirectory, packageName + ".html")));
-            fout.write("<html>\n");
-            fout.write("<body>\n");
-            fout.write("<h1>Class list</h1>\n");
+            out.add("<h2>Package " + packageName + "</h2>");
             for (String className : testedClasses)
             {
                 if (className.startsWith(packageName))
                 {
-                    fout.write("<a target='ResultsFrame' href='" + className + ".html'>" + className + "</a><br>\n");
+                    out.add("<a target='ResultsFrame' href='" + className + ".html'>" + className + "</a><br />");
                 }
             }
-            fout.write("</body>\n");
-            fout.write("</html>\n");
-        }
-        catch (IOException e)
-        {
-            e.printStackTrace();
-        }
-        finally
-        {
-            try
-            {
-                if (fout != null)
-                {
-                    fout.close();
-                }
-            }
-            catch (IOException e)
-            {
-                e.printStackTrace();
-            }
+            out.add("<br />");
         }
     }
 
@@ -229,6 +280,20 @@
         }
     }
 
+    private static Set<String> preparePackageNames(Set<String> allClasses)
+    {
+        Set<String> packages = new TreeSet<String>();
+        for (String className : allClasses)
+        {
+            String packageName = className.substring(0, className.lastIndexOf('.'));
+            if (!packageName.startsWith("com.") && !packageName.startsWith("sun"))
+            {
+                packages.add(packageName);
+            }
+        }
+        return packages;
+    }
+
     private static String constructPrintedMethodName(String methodName)
     {
         String printedMethodName = methodName.replace("<", "&lt;").replace(">", "&gt;");
@@ -275,7 +340,7 @@
     {
         for (String packageName : usedPackageNames)
         {
-            createFileForPackage(reportDirectory, packageName, testedClasses);
+            printReportForPackageToFile(reportDirectory, packageName, testedClasses);
         }
     }
 
@@ -342,50 +407,6 @@
         return allMethods;
     }
 
-    private static void printReportForAllClassesInOneFile(String reportDirectory, Set<String> usedPackageNames,
-                    Set<String> testedClasses)
-    {
-        BufferedWriter fout = null;
-        try
-        {
-            fout = new BufferedWriter(new FileWriter(new File(reportDirectory, "all_classes.html")));
-            fout.write("<html>\n");
-            fout.write("<body>\n");
-            fout.write("<h1>Classes list</h1>");
-            for (String packageName : usedPackageNames)
-            {
-                fout.write("<h2>Package " + packageName + "</h2>\n");
-                for (String className : testedClasses)
-                {
-                    if (className.startsWith(packageName))
-                    {
-                        fout.write("<a target='ResultsFrame' href='" + className + ".html'>" + className + "</a><br>\n");
-                    }
-                }
-            }
-            fout.write("</body>\n");
-            fout.write("</html>\n");
-        }
-        catch (IOException e)
-        {
-            e.printStackTrace();
-        }
-        finally
-        {
-            try
-            {
-                if (fout != null)
-                {
-                    fout.close();
-                }
-            }
-            catch (IOException e)
-            {
-                e.printStackTrace();
-            }
-        }
-    }
-
     private static void prepareReport(String allClassListFileName, String testedClassListFileName,
                     String reportDirectory)
     {