Project Report: fawkez

Packagesummary org.jcoderz.phoenix.report

org.jcoderz.phoenix.report.JcSummaryReportAntTask

LineHitsNoteSource
1  /*
2   * $Id: JcSummaryReportAntTask.java 1336 2009-03-28 22:04:07Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.phoenix.report;
34  
35  import java.awt.Color;
36  import java.awt.Dimension;
37  import java.io.BufferedReader;
38  import java.io.File;
39  import java.io.FileOutputStream;
40  import java.io.FileReader;
41  import java.io.FilenameFilter;
42  import java.io.IOException;
43  import java.io.PrintWriter;
44  import java.util.ArrayList;
45  import java.util.Collections;
46  import java.util.HashMap;
47  import java.util.Iterator;
48  import java.util.List;
49  import java.util.Map;
50  import java.util.Set;
51  import java.util.StringTokenizer;
52  import java.util.TreeSet;
53  
54  import javax.xml.parsers.DocumentBuilderFactory;
55  import javax.xml.parsers.ParserConfigurationException;
56  
57  import net.sourceforge.chart2d.Chart2DProperties;
58  import net.sourceforge.chart2d.Dataset;
59  import net.sourceforge.chart2d.GraphChart2DProperties;
60  import net.sourceforge.chart2d.GraphProperties;
61  import net.sourceforge.chart2d.LBChart2D;
62  import net.sourceforge.chart2d.LegendProperties;
63  import net.sourceforge.chart2d.MultiColorsProperties;
64  import net.sourceforge.chart2d.Object2DProperties;
65  
66  import org.apache.tools.ant.BuildException;
67  import org.apache.tools.ant.Task;
68  import org.jcoderz.commons.util.FileUtils;
69  import org.jcoderz.commons.util.IoUtil;
70  import org.w3c.dom.Document;
71  import org.w3c.dom.NamedNodeMap;
72  import org.w3c.dom.Node;
73  import org.xml.sax.SAXException;
74  
75  /**
76   * This is the Ant task for the Jcoderz Summary Report.
77   * This task uses a summary database file to create progress diagrams
78   * showing the historical changes of the number of findings.
79   *
80 (1) * TODO: Separate into Command Line tool and Ant Task so that the
81   *       java.awt.headless property can be set by the Ant Task.
82   * <ol>
83   *   <li>Read the summary db file or create a new one if none exists.</li>
84   *   <li>Check whether new folders have been created in the basedir.</li>
85   *   <li>Update the summary db file with the information from new folders.</li>
86   *   <li>Generate the diagrams based on the summary information.</li>
87   * </ol>
88   *
89   * @author Michael Rumpf
90   */
910 public class JcSummaryReportAntTask
92     extends Task
93  {
94     /** The number of columns in the CSV file. */
95     private static final int COLUMN_COUNT = 12;
960    private static final String[] MONTHS = new String[] {"January", "February",
97           "March", "April", "Mai", "June", "July", "August", "September",
98           "October", "November", "December"};
99     private static final int YEAR_LEN = 4;
100     private static final int MONTH_LEN = 2;
101     private static final int DAY_LEN = 2;
102  
103     private static final int ROW_ERROR = 0;
104     private static final int ROW_CPD = 1;
105     private static final int ROW_WARNING = 2;
106     private static final int ROW_DESIGN = 3;
107     private static final int ROW_COVERAGE = 4;
108     private static final int ROW_CODESTYLE = 5;
109     private static final int ROW_INFO = 6;
110     private static final int ROW_FILTERED = 7;
111  
112     private static final int ROW_LOC = 0;
113  
114     private static final int ROW_QUALITY = 0;
115  
116     private static final int LARGE_IMAGE_WIDTH = 800;
117     private static final int LARGE_IMAGE_HEIGHT = 600;
118     private static final int SMALL_IMAGE_WIDTH = 300;
119     private static final int SMALL_IMAGE_HEIGHT = 234;
1200    private static final Dimension LARGE_SIZE
121           = new Dimension(LARGE_IMAGE_WIDTH, LARGE_IMAGE_HEIGHT);
1220    private static final Dimension SMALL_SIZE
123           = new Dimension(SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT);
124  
1250    private String mName = null;
1260    private File mDestDir = null;
1270    private File mBaseDir = null;
1280    private File mSummaryDbFile = null;
129  
130     /**
131      * Sets the name of the summary report.
132      *
133      * @param name the report name.
134      */
135     public void setName (String name)
136     {
1370       mName = name;
1380    }
139  
140  
141     /**
142      * Sets the destination of the report.
143      *
144      * @param dest the report destination.
145      */
146     public void setDest (String dest)
147     {
1480       mDestDir = new File(dest);
1490       if (!mDestDir.exists())
150        {
1510(2)         mDestDir.mkdirs();
152        }
1530    }
154  
155  
156     /**
157      * Sets the base directory of the reports.
158      *
159      * @param base the base directory.
160      */
161     public void setBaseDir (String base)
162     {
1630       mBaseDir = new File(base);
1640       if (!mBaseDir.exists())
165        {
1660(3)         mBaseDir.mkdirs();
167        }
1680    }
169  
170  
171     /**
172      * Sets the historic database file.
173      *
174      * @param summary the historic database file.
175      */
176     public void setSummary (String summary)
177     {
1780       mSummaryDbFile = new File(summary);
1790    }
180  
181  
182     /**
183      * This method is called by Ant for executing this task.
184      *
185      * @throws BuildException whenver a problem occurs.
186      */
187     public void execute ()
188        throws BuildException
189     {
190        try
191        {
192           // Always show this line
1930          log("Executing JcSummaryReportAntTask...");
194  
1950          if (mSummaryDbFile == null)
196           {
1970             throw new BuildException("Summary database must be specified!");
198           }
199  
2000          if (mDestDir == null)
201           {
2020             throw new BuildException("Destination folder must be specified!");
203           }
2040          if (mDestDir.exists())
205           {
2060             if (!mDestDir.isDirectory())
207              {
2080                throw new BuildException("The destination directory '" + mDestDir
209                       + "' must be folder!");
210              }
211           }
212           else
213           {
2140(4)            mDestDir.mkdirs();
215           }
216  
2170          if (mBaseDir == null)
218           {
2190             throw new BuildException("The base directory must be specified!");
220           }
2210          if (!mBaseDir.exists() || !mBaseDir.isDirectory())
222           {
2230             throw new BuildException("The base directory '"
224                    + mBaseDir + "' must exists and must be a folder!");
225           }
226  
227  
228           // Stores a mapping between a timestamp and a Summary instance. This
229           // reads all lines in the summary db file and checks for new folders
2300          final Map summaryMap = readSummaryDb(mSummaryDbFile, mBaseDir);
231           // Write the summary file
2320          writeSummaryDb(mSummaryDbFile, summaryMap);
233  
234           // Create a complex map hierarchy: year -> month -> day -> List
235           // The leaf list is a list of reports that might have been created
236           // on one day.
2370          final Map ymd2SummaryMap = createSummaryDbMap(summaryMap);
238  
2390          createFindingsChart(ymd2SummaryMap, summaryMap, "Findings");
2400          createQualityChart(ymd2SummaryMap, summaryMap, "Quality");
2410          createLocChart(ymd2SummaryMap, summaryMap, "LOC");
242  
2430          renderHtmlView(ymd2SummaryMap, summaryMap);
244        }
2450       catch (IOException ex)
246        {
2470          throw new BuildException("An unexpected IO exception occured!", ex);
2480       }
2490    }
250  
251  
252     /**
253      * Writes the summary database file.
254      *
255      * @param summaryDbFile the summary database file.
256      */
257     private void writeSummaryDb (File summaryDbFile, Map summaryMap)
258     {
259        try
260        {
2610          log("Writing summary file " + summaryDbFile);
2620(5)         summaryDbFile.createNewFile();
2630          final FileOutputStream fos = new FileOutputStream(summaryDbFile);
2640          final PrintWriter pw = new PrintWriter(fos);
2650          pw.println("Timestamp;Error;Warning;Info;"
266                 + "Coverage;Loc;CodeLoc;Filtered;Codestyle;Design;Cpd;Quality");
267  
268           // Sort the keySet before writing the CSV file
2690          final Set keySet = summaryMap.keySet();
2700(6)         final List keyList = new ArrayList(keySet);
2710(7)(8)         Collections.sort(keyList);
2720          final Iterator iter = keyList.iterator();
2730          while (iter.hasNext())
274           {
2750             final Long ts = (Long) iter.next();
2760             final Summary sum = (Summary) summaryMap.get(ts);
2770             pw.print(sum.getTimestamp() + ";");
2780             pw.print(sum.getError() + ";");
2790             pw.print(sum.getWarning() + ";");
2800             pw.print(sum.getInfo() + ";");
2810             pw.print(sum.getCoverage() + ";");
2820             pw.print(sum.getLoc() + ";");
2830             pw.print(sum.getCodeLoc() + ";");
2840             pw.print(sum.getFiltered() + ";");
2850             pw.print(sum.getCodestyle() + ";");
2860             pw.print(sum.getDesign() + ";");
2870             pw.print(sum.getCpd() + ";");
2880             pw.println(FileSummary.calculateQuality(sum.getLoc(),
289                    sum.getInfo(), sum.getWarning(), sum.getError(),
290                    sum.getCoverage(), sum.getFiltered(),
291                    sum.getCodestyle(), sum.getDesign(), sum.getCpd()));
2920          }
2930          fos.flush();
2940          IoUtil.close(pw);
2950          IoUtil.close(fos);
296        }
2970       catch (IOException ex)
298        {
2990          throw new BuildException("Could not write summary database '"
300                 + summaryDbFile + "'!");
3010       }
3020    }
303  
304  
305     /**
306      * This method creates a mapping between timestamp (e.g. 20061122103015)
307      * and the summary information.
308      *
309      * @param summaryDbFile the summary file.
310      * @param baseDir the basedir with the report folders.
311      * @return The map of timestamps and summary instances.
312      */
313     private Map readSummaryDb (File summaryDbFile, File baseDir)
314     {
3150       final Map files = new HashMap();
3160       if (summaryDbFile.exists())
317        {
3180          log("Reading summary database...");
3190          FileReader fr = null;
3200          BufferedReader br = null;
321           try
322           {
3230             fr = new FileReader(summaryDbFile);
3240             br = new BufferedReader(fr);
3250             String line = br.readLine();
3260             while (line != null)
327              {
3280                if (line.indexOf("Error") == -1
329                       && line.indexOf("Warning") == -1
330                       && line.indexOf("Info") == -1
331                       && line.indexOf("Coverage") == -1)
332                 {
3330                   final Summary sum = createSummary(line, baseDir);
3340                   log("Summary information from database: " + sum);
3350                   if (sum != null)
336                    {
3370(9)(10)                    files.put(new Long(sum.getTimestamp()), sum);
338                    }
339                 }
3400                line = br.readLine();
341              }
342           }
3430          catch (IOException ex)
344           {
3450             throw new BuildException("An IO exception occured while reading '"
346                    + summaryDbFile + "'!", ex);
347           }
348           finally
349           {
3500(11)            FileUtils.safeClose(br);
3510(12)            FileUtils.safeClose(fr);
3520          }
353        }
354  
355        // Now check whether more folders can be found
3560       final String[] folders = baseDir.list(new JcoderReportFilter());
3570       for (int i = 0; i < folders.length; i++)
358        {
3590          if (!files.containsKey(Long.valueOf(folders[i])))
360           {
3610             log("New report sub-folder found: " + folders[i]);
3620             final File folder = new File(baseDir, folders[i]);
3630             Long ts = null;
364              try
365              {
3660                ts = Long.valueOf(folders[i]);
367              }
3680             catch (NumberFormatException ex)
369              {
3700                log("The folder '" + folders[i]
371                     + "' is not a timestamp folder!");
3720             }
3730             final Summary sum = readSummaryXml(findSummaryXml(folder), ts);
3740(13)            files.put(new Long(sum.getTimestamp()), sum);
3750          }
376           else
377           {
3780             log("Report sub-folder '" + folders[i] + "' already in database!");
379           }
380        }
3810       return files;
382     }
383  
384     private static File findSummaryXml(File folder)
385     {
3860        File result = null;
3870        if (folder.isFile() && "summary.xml".equals(folder.getName()))
388         {
3890            result = folder;
390         }
3910        else if (folder.isDirectory())
392         {
3930            for (File file : folder.listFiles())
394             {
3950                result = findSummaryXml(file);
3960                if (result != null)
397                 {
3980                    break;
399                 }
400             }
401         }
4020        return result;
403     }
404  
405  
406     private Summary readSummaryXml (File summaryXml, Long folderTimestamp)
407     {
4080       Summary sum = null;
409        try
410        {
4110          final DocumentBuilderFactory factory =
412                 DocumentBuilderFactory.newInstance();
4130          final Document doc = factory.newDocumentBuilder().parse(summaryXml);
414           // There is only one root node
4150          final Node root = doc.getDocumentElement();
4160          final NamedNodeMap attrs = root.getAttributes();
417           // Ignore the timestamp as the external script might choose another
418           // timestamp for the folder than the jcoderz-report has chosen
419           // for the XML file.
420           long ts;
4210          if (folderTimestamp == null)
422           {
4230              ts = Long.parseLong(
424                       attrs.getNamedItem("timestamp").getNodeValue().trim());
425           }
426           else
427           {
4280              ts = folderTimestamp.longValue();
429           }
430  
4310          final int filtered = Integer.parseInt(
432              attrs.getNamedItem("filtered").getNodeValue().trim());
4330          final int coverage = Integer.parseInt(
434              attrs.getNamedItem("coverage").getNodeValue().trim());
4350          final int info = Integer.parseInt(
436              attrs.getNamedItem("info").getNodeValue().trim());
4370          final int codestyle = Integer.parseInt(
438              attrs.getNamedItem("code-style").getNodeValue().trim());
4390          final int design = Integer.parseInt(
440              attrs.getNamedItem("design").getNodeValue().trim());
4410          final int warning = Integer.parseInt(
442              attrs.getNamedItem("warning").getNodeValue().trim());
4430          final int cpd = Integer.parseInt(
444              attrs.getNamedItem("cpd").getNodeValue().trim());
4450          final int error = Integer.parseInt(
446                 attrs.getNamedItem("error").getNodeValue().trim());
4470          final int loc = Integer.parseInt(
448                 attrs.getNamedItem("loc").getNodeValue().trim());
4490          final int codeloc = Integer.parseInt(
450                 attrs.getNamedItem("codeLoc").getNodeValue().trim());
4510          final double quality = Double.parseDouble(
452                 attrs.getNamedItem("quality").getNodeValue());
4530          sum = new Summary(ts, error, warning, info, coverage, loc, codeloc,
454               filtered, codestyle, design, cpd, quality, summaryXml);
455        }
4560       catch (ParserConfigurationException ex)
457        {
4580(14)         throw new BuildException("A parser configuration error occured!", ex);
459        }
4600       catch (SAXException ex)
461        {
4620          throw new BuildException("A SAX exception occured while parsing '"
463                 + summaryXml + "'!", ex);
464        }
4650       catch (IOException ex)
466        {
4670          throw new BuildException("An IO exception occured while parsing '"
468                 + summaryXml + "'!", ex);
4690       }
470  
4710       return sum;
472     }
473  
474  
475     private void storeInMap (Map files, long timestamp, Summary sum)
476     {
4770       log("Storing summmary: " + sum);
4780(15)      final Long ts = new Long(timestamp);
4790       final String tsStr = ts.toString();
4800       final Integer y = Integer.valueOf(tsStr.substring(0, 4));
4810       final Integer m = Integer.valueOf(tsStr.substring(4, 6));
4820       final Integer d = Integer.valueOf(tsStr.substring(6, 8));
4830       if (!files.containsKey(y))
484        {
4850          log("Adding hash map for year " + y);
4860(16)         files.put(y, new HashMap());
487        }
4880       final Map year = (Map) files.get(y);
4890       if (!year.containsKey(m))
490        {
4910          log("Adding hash map for month " + m);
4920(17)         year.put(m, new HashMap());
493        }
4940       final Map month = (Map) year.get(m);
4950       if (!month.containsKey(d))
496        {
4970          log("Adding report list for day " + d);
4980(18)         month.put(d, new ArrayList());
499        }
5000       final List reports = (List) month.get(d);
5010(19)      reports.add(sum);
5020    }
503  
504  
505     private Map createSummaryDbMap (Map ts2SumMap)
506     {
5070       final Map files = new HashMap();
5080       final Iterator iter = ts2SumMap.keySet().iterator();
5090       while (iter.hasNext())
510        {
5110          final Long ts = (Long) iter.next();
5120(20)         final Summary sum = (Summary) ts2SumMap.get(ts);
5130          storeInMap(files, ts.longValue(), sum);
5140       }
5150       return files;
516     }
517  
518  
519     private Summary createSummary (String sum, File baseDir)
520     {
5210       final StringTokenizer strtok = new StringTokenizer(sum, ";");
5220       if (strtok.countTokens() != COLUMN_COUNT)
523        {
5240          throw new BuildException(
525                 "Number of columns in summary database file '"
526                 + strtok.countTokens()
527                 + "' does not match the expected number of '"
528                 + COLUMN_COUNT + "'!");
529        }
5300       Summary summary = null;
5310       final long timestamp = Long.parseLong(strtok.nextToken());
5320(21)      final int error = Integer.parseInt(strtok.nextToken());
5330(22)      final int warning = Integer.parseInt(strtok.nextToken());
5340(23)      final int info = Integer.parseInt(strtok.nextToken());
5350(24)      final int coverage = Integer.parseInt(strtok.nextToken());
5360(25)      final int loc = Integer.parseInt(strtok.nextToken());
5370(26)      final int codeloc = Integer.parseInt(strtok.nextToken());
5380(27)      final int filtered = Integer.parseInt(strtok.nextToken());
5390(28)      final int codestyle = Integer.parseInt(strtok.nextToken());
5400(29)      final int design = Integer.parseInt(strtok.nextToken());
5410(30)      final int cpd = Integer.parseInt(strtok.nextToken());
5420(31)      final double quality = Double.parseDouble(strtok.nextToken());
5430       final File summaryFile = new File(baseDir, String.valueOf(timestamp)
544              + File.separator + "summary.xml");
5450       if (summaryFile.exists() && summaryFile.isFile())
546        {
5470          summary = new Summary(timestamp, error, warning, info, coverage, loc,
548              codeloc, filtered, codestyle, design, cpd,
549              quality, summaryFile);
550        }
551        else
552        {
5530          log("Summary file does not exist: " + summaryFile);
554        }
5550       return summary;
556     }
557  
558  
559     /**
560      * Creates the quality chart.
561      * The output is a "quality.png" and a "quality_small.png" image.
562      *
563      * @throws IOException if the image can not be written.
564      */
565     private void createQualityChart (Map ymd2SummaryMap, Map summaryMap,
566         String title)
567           throws IOException
568     {
5690(32)      final Set labels = new TreeSet(summaryMap.keySet());
5700       if (labels.size() == 0)
571        {
5720(33)         throw new RuntimeException("No reports found for chart!");
573        }
574  
5750(34)(35)      final String[] legendLabels = {"Quality"};
576  
577        // Configure dataset
5780       final Dataset dataset = new Dataset(legendLabels.length,
579           summaryMap.size(), 1);
5800       final List labelsAxisLabels = new ArrayList();
5810       final List sortedKeyList = new ArrayList();
5820(36)      sortedKeyList.addAll(summaryMap.keySet());
5830(37)(38)      Collections.sort(sortedKeyList);
5840       final Iterator iter = sortedKeyList.iterator();
5850       int i = 0;
5860       while (iter.hasNext())
587        {
5880          final Long ts = (Long) iter.next();
5890(39)         labelsAxisLabels.add(ts.toString());
5900          final Summary sum = (Summary) summaryMap.get(ts);
591  
5920          dataset.set(ROW_QUALITY, i, 0, (float) sum.getQuality());
5930          i++;
5940       }
595  
5960       final GraphChart2DProperties graphChart2DProps
597              = createGraphChart2DProperties(labelsAxisLabels, title);
5980       final MultiColorsProperties multiColorsProps
599              = createMultiColorsProperties(new Color[] {Color.GREEN});
6000       createChart(title, legendLabels, dataset, graphChart2DProps,
601            multiColorsProps);
6020    }
603  
604  
605     /**
606      * Creates the lines-of-code chart.
607      * The output is a "loc.png" and a "loc_small.png" image.
608      *
609      * @throws IOException if the image can not be written.
610      */
611     private void createLocChart (Map ymd2SummaryMap, Map summaryMap,
612         String title)
613           throws IOException
614     {
6150(40)      final Set labels = new TreeSet(summaryMap.keySet());
6160       if (labels.size() == 0)
617        {
6180(41)         throw new RuntimeException("No reports found for chart!");
619        }
620  
6210(42)(43)      final String[] legendLabels = {"Loc"};
622  
623        // Configure dataset
6240       final Dataset dataset = new Dataset(legendLabels.length,
625           summaryMap.size(), 1);
6260       final List labelsAxisLabels = new ArrayList();
6270       final List sortedKeyList = new ArrayList();
6280(44)      sortedKeyList.addAll(summaryMap.keySet());
6290(45)(46)      Collections.sort(sortedKeyList);
6300       final Iterator iter = sortedKeyList.iterator();
6310       int i = 0;
6320       while (iter.hasNext())
633        {
6340          final Long ts = (Long) iter.next();
6350(47)         labelsAxisLabels.add(ts.toString());
6360          final Summary sum = (Summary) summaryMap.get(ts);
637  
6380          dataset.set(ROW_LOC, i, 0, sum.getLoc());
6390          i++;
6400       }
641  
6420       final GraphChart2DProperties graphChart2DProps
643              = createGraphChart2DProperties(labelsAxisLabels, title);
6440       final MultiColorsProperties multiColorsProps
645              = createMultiColorsProperties(
646                  new Color[] {new Color(115, 117, 255)});
6470       createChart(title, legendLabels, dataset, graphChart2DProps,
648            multiColorsProps);
6490    }
650  
651  
652     /**
653      * Creates the findings chart.
654      * The output is a "findings.png" and a "findings_small.png" image.
655      *
656      * @throws IOException if the image can not be written.
657      */
658     private void createFindingsChart (Map ymd2SummaryMap, Map summaryMap,
659         String title)
660           throws IOException
661     {
6620(48)     final Set labels = new TreeSet(summaryMap.keySet());
6630      if (labels.size() == 0)
664       {
6650(49)        throw new RuntimeException("No reports found for chart!");
666       }
667  
6680(50)     final String[] legendLabels = {"Error", "Warning", "Info", "Coverage",
669 (51)         "Filtered", "Codestyle", "Design", "Cpd"};
670  
671       // Configure dataset
6720      final Dataset dataset = new Dataset(legendLabels.length,
673          summaryMap.size(), 1);
6740      final List labelsAxisLabels = new ArrayList();
6750      final List sortedKeyList = new ArrayList();
6760(52)     sortedKeyList.addAll(summaryMap.keySet());
6770(53)(54)     Collections.sort(sortedKeyList);
6780      final Iterator iter = sortedKeyList.iterator();
6790      int i = 0;
6800      while (iter.hasNext())
681       {
6820         final Long ts = (Long) iter.next();
6830(55)        labelsAxisLabels.add(ts.toString());
6840         final Summary sum = (Summary) summaryMap.get(ts);
685  
6860         dataset.set(ROW_ERROR, i, 0, sum.getError());
6870         dataset.set(ROW_CPD, i, 0, sum.getCpd());
6880         dataset.set(ROW_WARNING, i, 0, sum.getWarning());
6890         dataset.set(ROW_DESIGN, i, 0, sum.getDesign());
6900         dataset.set(ROW_COVERAGE, i, 0, sum.getCoverage());
6910         dataset.set(ROW_CODESTYLE, i, 0, sum.getCodestyle());
6920         dataset.set(ROW_INFO, i, 0, sum.getInfo());
6930         dataset.set(ROW_FILTERED, i, 0, sum.getFiltered());
6940         i++;
6950      }
696  
6970      final GraphChart2DProperties graphChart2DProps
698             = createGraphChart2DProperties(labelsAxisLabels, title);
6990      final MultiColorsProperties multiColorsProps
700             = createMultiColorsProperties(new Color[] {
701                new Color(255, 65, 66),
702                new Color(214, 243, 214),
703                new Color(255, 162, 66),
704                new Color(255, 243, 66),
705                new Color(255, 255, 231),
706                new Color(255, 243, 132),
707                new Color(214, 211, 255),
708                new Color(247, 247, 247)
709                });
7100      createChart(title, legendLabels, dataset, graphChart2DProps,
711               multiColorsProps);
7120    }
713  
714  
715     private void createChart (final String title, final String[] legendLabels,
716             final Dataset dataset,
717             final GraphChart2DProperties graphChart2DProps,
718             final MultiColorsProperties multiColorsProps) throws IOException
719     {
720        // Configure chart
7210       final LBChart2D chart2D = new LBChart2D();
7220       chart2D.setObject2DProperties(createObject2DProps());
7230       chart2D.setChart2DProperties(createChart2DProperties());
7240       chart2D.setLegendProperties(createLegendProperties(legendLabels));
725  
7260       chart2D.setGraphChart2DProperties(graphChart2DProps);
7270       chart2D.addGraphProperties(createGraphProperties());
7280       chart2D.addDataset(dataset);
7290       chart2D.addMultiColorsProperties(multiColorsProps);
730  
7310       chart2D.setMaximumSize(LARGE_SIZE);
7320       chart2D.setPreferredSize(LARGE_SIZE);
733  
7340(56)(57)      final String titleSmall = title.toLowerCase();
7350       if (chart2D.validate(false))
736        {
7370          java.io.File file = new java.io.File(mDestDir, titleSmall + ".png");
7380          javax.imageio.ImageIO.write(chart2D.getImage(), "PNG", file);
7390          chart2D.setMaximumSize(SMALL_SIZE);
7400          chart2D.setPreferredSize(SMALL_SIZE);
7410          chart2D.pack();
7420          file = new java.io.File(mDestDir, titleSmall + "_small.png");
7430          javax.imageio.ImageIO.write(chart2D.getImage(), "PNG", file);
7440       }
745        else
746        {
7470          chart2D.validate(true);
748        }
7490    }
750  
751  
752     private MultiColorsProperties createMultiColorsProperties (Color[] colors)
753     {
754        // Configure graph component colors
7550       final MultiColorsProperties multiColorsProps
756            = new MultiColorsProperties();
7570       multiColorsProps.setColorsCustomize(true);
7580       multiColorsProps.setColorsCustom(colors);
7590       return multiColorsProps;
760     }
761  
762  
763     private Object2DProperties createObject2DProps ()
764     {
7650       final Object2DProperties object2DProps = new Object2DProperties();
7660       object2DProps.setObjectBackgroundLightSource(Object2DProperties.NONE);
7670       object2DProps.setObjectBackgroundColor(Color.LIGHT_GRAY);
7680       return object2DProps;
769     }
770  
771  
772     private GraphProperties createGraphProperties ()
773     {
774        // Configure graph properties
7750       final GraphProperties graphProps = new GraphProperties();
7760       graphProps.setGraphBarsExistence(false);
7770       graphProps.setGraphLinesExistence(true);
7780       graphProps.setGraphLinesThicknessModel(1);
7790       return graphProps;
780     }
781  
782  
783     private Chart2DProperties createChart2DProperties ()
784     {
785        // Configure chart properties
7860       final Chart2DProperties chart2DProps = new Chart2DProperties();
7870       chart2DProps.setChartDataLabelsPrecision(0);
7880       return chart2DProps;
789     }
790  
791  
792     private LegendProperties createLegendProperties (String[] legendLabels)
793     {
794        // Configure legend properties
7950       final LegendProperties legendProps = new LegendProperties();
7960       legendProps.setLegendLabelsTexts(legendLabels);
7970       return legendProps;
798     }
799  
800  
801     private GraphChart2DProperties createGraphChart2DProperties (
802             List labelsAxisLabels, String title)
803     {
804        // Configure graph chart properties
8050       final GraphChart2DProperties graphChart2DProps =
806              new GraphChart2DProperties();
8070       final String[] labelsTexts = new String[labelsAxisLabels.size()];
8080       graphChart2DProps.setLabelsAxisLabelsTexts((String[])
809 (58)            labelsAxisLabels.toArray(labelsTexts));
810        // The name of the Y-Axis
8110       graphChart2DProps.setNumbersAxisTitleText(title);
8120       graphChart2DProps.setLabelsAxisTicksAlignment(
813              GraphChart2DProperties.CENTERED);
8140       return graphChart2DProps;
815     }
816  
817  
818     private void renderHtmlView (Map summaryDbMap, Map ts2BaseFolder)
819     {
820        try
821        {
8220          final FileOutputStream fos = new FileOutputStream(
823                 new File(mDestDir, "index.html"));
8240          final PrintWriter pw = new PrintWriter(fos);
8250          pw.println("<html><head>\n<title>");
8260          pw.println(mName);
8270          pw.println("</title>");
8280          pw.println("<style type=\"text/css\">");
8290          pw.println("<!--");
830  
8310          pw.println("body { font-family: verdana, tahoma; }");
8320          pw.println("img { border:none; }");
8330          pw.println("a { text-decoration: none; }");
8340          pw.println("a:hover { text-decoration: underline; }");
835  
8360          pw.println(".bold { font-weight: bold; }");
8370          pw.println("table { border-collapse: collapse; "
838                + "border: 1px solid black; text-align: right; }");
8390          pw.println("table td { padding: 5px; border-collapse: collapse; "
840                + "border: 1px solid black; font-size: small; vertical-align: "
841                + "top; }");
8420          pw.println("td.month { padding: 10px; border: 1px solid black; "
843                + "margin: 1em; background-color: #eeeeee; text-align: left; "
844                + "font-size: large; }");
8450          pw.println("td.day_odd { background: #aaaaaa; }");
8460          pw.println("td.day_even { background: #cccccc; }");
8470          pw.println("td.quality_odd { background:#88b888; }");
8480          pw.println("td.quality_even { background:#88e888; }");
8490          pw.println("td.loc_odd { background:#7777cf; }");
8500          pw.println("td.loc_even { background:#7777ff; }");
8510          pw.println("td.filtered_odd { background:#e0e0e0; }");
8520          pw.println("td.filtered_even { background:#f7f7f7; }");
8530          pw.println("td.ok_odd { background:#e0e0e0; }");
8540          pw.println("td.ok_even { background:#ffffff; }");
8550          pw.println("td.info_odd { background:#b0b0e0; }");
8560          pw.println("td.info_even { background:#d0d0ff; }");
8570          pw.println("td.codestyle_odd { background:#e0e070; }");
8580          pw.println("td.codestyle_even { background:#fff080; }");
8590          pw.println("td.coverage_odd { background:#e0e0c0; }");
8600          pw.println("td.coverage_even { background:#ffffe0; }");
8610          pw.println("td.design_odd { background:#e0d020; }");
8620          pw.println("td.design_even { background:#fff040; }");
8630          pw.println("td.warning_odd { background:#e08020; }");
8640          pw.println("td.warning_even { background:#ffa040; }");
8650          pw.println("td.cpd_odd { background: #c0e0c0; }");
8660          pw.println("td.cpd_even { background:#d0f0d0; }");
8670          pw.println("td.error_odd { background:#e08080; }");
8680          pw.println("td.error_even { background:#ff4040; }");
869  
8700          pw.println("-->");
8710          pw.println("</style>");
8720          pw.println("<body>");
873  
8740          pw.println("<table>");
875  
8760          pw.println("<tr>");
8770          pw.println("<td colspan=\"4\">");
8780(59)         pw.println("<a href=\"findings.png\"><img src=\"findings_small.png\"></a>");
8790          pw.println("</td><td colspan=\"4\">");
8800(60)         pw.println("<a href=\"quality.png\"><img src=\"quality_small.png\"></a>");
8810          pw.println("</td><td colspan=\"3\">");
8820          pw.println("<a href=\"loc.png\"><img src=\"loc_small.png\"></a>");
8830          pw.println("</td>");
8840          pw.println("</tr>");
885  
886  
8870          final Map yearMap = summaryDbMap;
8880          final List sortedYearList = new ArrayList();
8890(61)         sortedYearList.addAll(yearMap.keySet());
8900(62)(63)         Collections.sort(sortedYearList);
8910          Collections.reverse(sortedYearList);
8920          final Iterator yearIter = sortedYearList.iterator();
8930          while (yearIter.hasNext())
894           {
8950             final Integer year = (Integer) yearIter.next();
8960             log("Rendering detail tables for year " + year);
897  
8980             final Map monthMap = (Map) summaryDbMap.get(year);
8990             final List sortedMonthList = new ArrayList();
9000(64)            sortedMonthList.addAll(monthMap.keySet());
9010(65)(66)            Collections.sort(sortedMonthList);
9020             Collections.reverse(sortedMonthList);
9030             final Iterator monthIter = sortedMonthList.iterator();
9040             while (monthIter.hasNext())
905              {
9060                final Integer month = (Integer) monthIter.next();
9070                log("Rendering detail table for month " + month);
908  
9090                pw.println("<tr><td class=\"month bold\" colspan=\"11\">"
910                     + MONTHS[month.intValue() - 1]
911                     + " " + year + "</td></tr>");
9120                pw.println("<tr>");
9130                pw.println(" <td class=\"day_even bold\">Date</td>");
9140                pw.println(" <td class=\"quality_even bold\">Quality</td>");
9150                pw.println(" <td class=\"loc_even bold\">Loc</td>");
9160                pw.println(" <td class=\"error_even bold\">Error</td>");
9170                pw.println(" <td class=\"cpd_even bold\">Cpd</td>");
9180                pw.println(" <td class=\"warning_even bold\">Warning</td>");
9190                pw.println(" <td class=\"design_even bold\">Design</td>");
9200                pw.println(" <td class=\"coverage_even bold\">Coverage</td>");
9210                pw.println(" <td class=\"codestyle_even bold\">Codestyle</td>");
9220                pw.println(" <td class=\"info_even bold\">Info</td>");
9230                pw.println(" <td class=\"filtered_even bold\">Filtered</td>");
9240                pw.println("</tr>");
925  
9260                int i = 0;
9270                final Map dayMap = (Map) monthMap.get(month);
9280                final List sortedDayList = new ArrayList();
9290(67)               sortedDayList.addAll(dayMap.keySet());
9300(68)(69)               Collections.sort(sortedDayList);
9310                Collections.reverse(sortedDayList);
9320                final Iterator dayIter = sortedDayList.iterator();
9330                while (dayIter.hasNext())
934                 {
9350                   final Integer day = (Integer) dayIter.next();
9360                   final List reportsList = (List) dayMap.get(day);
937  
9380                   final Iterator reportsIter = reportsList.iterator();
9390                   while (reportsIter.hasNext())
940                    {
9410                      pw.println("<tr>");
942  
9430                      final Summary sum = (Summary) reportsIter.next();
9440                      String suffix = "odd";
9450                      if ((i & 1) == 0)
946                       {
9470                         suffix = "even";
948                       }
949  
9500                      pw.println(wrapTimestamp(sum, suffix));
951  
9520                      pw.println(wrapValue(sum.getQuality(), "quality", suffix));
9530                      pw.println(wrapValue(sum.getLoc(), "loc", suffix));
954  
9550(70)                     pw.println(wrapValue(sum, sum.getError(), "error", suffix));
9560                      pw.println(wrapValue(sum, sum.getCpd(), "cpd", suffix));
9570(71)                     pw.println(wrapValue(sum, sum.getWarning(), "warning", suffix));
9580(72)                     pw.println(wrapValue(sum, sum.getDesign(), "design", suffix));
9590(73)                     pw.println(wrapValue(sum, sum.getCoverage(), "coverage", suffix));
9600(74)                     pw.println(wrapValue(sum, sum.getCodestyle(), "codestyle", suffix));
9610                      pw.println(wrapValue(sum, sum.getInfo(), "info", suffix));
9620(75)                     pw.println(wrapValue(sum, sum.getFiltered(), "filtered", suffix));
963  
9640                      pw.println("</tr>");
965  
9660                      i++;
9670                   }
9680                }
9690             }
9700          }
971  
9720          pw.println("</table>");
9730          pw.println("</body>");
9740          pw.println("</html>");
9750          pw.close();
9760          fos.flush();
9770          fos.close();
978        }
9790       catch (IOException ex)
980        {
9810(76)         throw new BuildException("An IO exception occured!", ex);
9820       }
9830    }
984  
985  
986     private String wrapTimestamp (Summary sum, String oddeven)
987     {
9880       final StringBuilder sb = new StringBuilder();
9890       sb.append("<td class=\"day_");
9900       sb.append(oddeven);
9910       sb.append("\">");
9920       if (sum.getSummaryXml() != null)
993        {
9940          sb.append("<a href=\"");
9950          sb.append(sum.getTimestamp());
9960          sb.append("/index.html\">");
997        }
9980       sb.append(extractDay(sum.getTimestamp()));
9990       sb.append(".");
10000       sb.append(extractMonth(sum.getTimestamp()));
10010       sb.append(".");
10020       sb.append(extractYear(sum.getTimestamp()));
10030       if (sum.getSummaryXml() != null)
1004        {
10050          sb.append("</a>");
1006        }
10070       return sb.toString();
1008     }
1009  
1010  
1011     private String wrapValue (Summary sum, int value, String severity,
1012         String oddeven)
1013     {
10140       final StringBuilder sb = new StringBuilder();
10150       sb.append("<td class=\"");
10160       sb.append(severity);
10170       sb.append("_");
10180       sb.append(oddeven);
10190       sb.append("\">");
10200       if (sum.getSummaryXml() != null)
1021        {
10220(77)         sb.append("<a href=\"" + sum.getTimestamp()
1023                 + "/findings.html");
10240          sb.append("#");
10250          sb.append(severity);
10260          sb.append("\">");
1027        }
10280       sb.append(value);
10290       if (sum.getSummaryXml() != null)
1030        {
10310          sb.append("</a>");
1032        }
10330       sb.append("</td>");
10340       return sb.toString();
1035     }
1036  
1037  
1038     private String wrapValue (int value, String severity, String oddeven)
1039     {
10400       final StringBuilder sb = new StringBuilder();
10410       sb.append("<td class=\"");
10420       sb.append(severity);
10430       sb.append("_");
10440       sb.append(oddeven);
10450       sb.append("\">");
10460       sb.append(value);
10470       sb.append("</td>");
10480       return sb.toString();
1049     }
1050  
1051  
1052     private String wrapValue (double value, String severity, String oddeven)
1053     {
10540       final StringBuilder sb = new StringBuilder();
10550       sb.append("<td class=\"");
10560       sb.append(severity);
10570       sb.append("_");
10580       sb.append(oddeven);
10590       sb.append("\">");
10600       sb.append(value);
10610       sb.append("%");
10620       sb.append("</td>");
10630       return sb.toString();
1064     }
1065  
1066  
1067     private String extractDay (long timestamp)
1068     {
10690       final String ts = String.valueOf(timestamp);
10700       return ts.substring(YEAR_LEN + MONTH_LEN, YEAR_LEN + MONTH_LEN + DAY_LEN);
1071     }
1072  
1073  
1074     private String extractMonth (long timestamp)
1075     {
10760       final String ts = String.valueOf(timestamp);
10770       return ts.substring(YEAR_LEN, YEAR_LEN + MONTH_LEN);
1078     }
1079  
1080  
1081     private String extractYear (long timestamp)
1082     {
10830       final String ts = String.valueOf(timestamp);
10840       return ts.substring(0, YEAR_LEN);
1085     }
1086  
1087  
1088     /**
1089      * Class holds data from the summary database file.
1090      *
1091      * @author Michael Rumpf
1092      */
1093     private static final class Summary
1094     {
1095        private final long mTimestamp;
1096        private final int mError;
1097        private final int mFiltered;
1098        private final int mDesign;
1099        private final int mCodestyle;
1100        private final int mCpd;
1101        private final int mWarning;
1102        private final int mInfo;
1103        private final int mCoverage;
1104        private final int mLoc;
1105        /** Lines of code reported by coverage test. */
1106        private final int mCodeLoc;
1107        private final double mQuality;
1108        private final File mSummaryXml;
1109  
1110        public Summary (long timestamp, int error,
1111            int warning, int info, int coverage, int loc, int codeloc,
1112            int filtered, int codestyle, int design, int cpd, double quality)
11130       {
11140          mFiltered = filtered;
11150          mCodestyle = codestyle;
11160          mDesign = design;
11170          mCpd = cpd;
11180          mTimestamp = timestamp;
11190          mError = error;
11200          mWarning = warning;
11210          mInfo = info;
11220          mCoverage = coverage;
11230          mLoc = loc;
11240          mCodeLoc = codeloc;
11250          mQuality = quality;
11260          mSummaryXml = null;
11270       }
1128  
1129        public Summary (long timestamp, int error,
1130            int warning, int info, int coverage, int loc, int codeloc,
1131            int filtered, int codestyle, int design, int cpd,
1132            double quality, File summaryXml)
11330       {
11340          mFiltered = filtered;
11350          mCodestyle = codestyle;
11360          mDesign = design;
11370          mCpd = cpd;
11380          mTimestamp = timestamp;
11390          mError = error;
11400          mWarning = warning;
11410          mInfo = info;
11420          mCoverage = coverage;
11430          mLoc = loc;
11440          mCodeLoc = codeloc;
11450          mQuality = quality;
11460          mSummaryXml = summaryXml;
11470       }
1148  
1149        public long getTimestamp ()
1150        {
11510          return mTimestamp;
1152        }
1153  
1154        public int getError ()
1155        {
11560          return mError;
1157        }
1158  
1159        public int getWarning ()
1160        {
11610          return mWarning;
1162        }
1163  
1164        public int getInfo ()
1165        {
11660          return mInfo;
1167        }
1168  
1169        public int getCoverage ()
1170        {
11710          return mCoverage;
1172        }
1173  
1174        public int getFiltered ()
1175        {
11760          return mFiltered;
1177        }
1178  
1179        public int getCodestyle ()
1180        {
11810          return mCodestyle;
1182        }
1183  
1184        public int getDesign ()
1185        {
11860          return mDesign;
1187        }
1188  
1189        public int getCpd ()
1190        {
11910          return mCpd;
1192        }
1193  
1194        public int getLoc ()
1195        {
11960          return mLoc;
1197        }
1198  
1199        public int getCodeLoc ()
1200        {
12010          return mCodeLoc;
1202        }
1203  
1204        public double getQuality ()
1205        {
12060          return mQuality;
1207        }
1208  
1209        public File getSummaryXml ()
1210        {
12110          return mSummaryXml;
1212        }
1213  
1214        public int hashCode ()
1215        {
1216           // MAXINT = 4294967296
1217           // ts 20061122001122
1218           // value to extract mmddHHMMSS from YYYY
12190          final long div = 10000000000L;
12200          final int mul = 1000000;
1221           // max 1231235959
12220          final long rest = mTimestamp % div;
1223           // year 2006
12240          final long year = mTimestamp / div;
1225           // hash 2006000000 + 1231235959 = 3237235959 (Overflow in year 3063)
12260          return (int) (year * mul + rest);
1227        }
1228  
1229        public boolean equals (Object sum)
1230        {
12310(78)         boolean result = false;
12320          if (sum != null)
1233           {
12340             if (sum == this)
1235              {
12360                result = true;
1237              }
1238              else
1239              {
12400                result = hashCode() == sum.hashCode();
1241              }
1242           }
12430          return result;
1244        }
1245  
1246        public String toString ()
1247        {
12480          return "[" + mTimestamp + ", " + mError + ", "
1249               + mWarning + ", " + mInfo + ", " + mCoverage + ", " + mLoc
1250               + ", " + mCodeLoc + ", " + mFiltered + ", " + mCodestyle + ", "
1251               + mDesign + ", " + mCpd + ", " + mQuality + ", "
1252               + mSummaryXml + "]";
1253        }
1254     }
1255  
1256  
1257     /**
1258      * Filter for folders that contain a 'summary.xml' file.
1259      *
1260      * @author Michael Rumpf
1261      */
12620    public static class JcoderReportFilter
1263        implements FilenameFilter
1264     {
1265        /**
1266         * Only accept folder that contain a 'summary.xml' file.
1267         *
1268         * @param dir the directory where the file is located.
1269         * @param name the name of the file.
1270         */
1271        public boolean accept (File dir, String name)
1272        {
12730          boolean result = false;
1274           try
1275           {
12760              Long.parseLong(name);
12770              final File folder = new File(dir, name);
12780              if (folder.exists() && folder.isDirectory())
1279               {
12800                 final File summaryXml = findSummaryXml(folder);
12810                 result = summaryXml != null
1282                      && summaryXml.exists() && summaryXml.isFile();
1283               }
1284           }
12850          catch (NumberFormatException ex)
1286           {
1287               // result is false;
12880          }
12890          return result;
1290        }
1291     }
1292  }

Findings in this File

c (79) Got an exception - java.lang.RuntimeException: Unable to get class information for @throws tag 'BuildException'.
i (1) 80 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
w (2) 151 : 0 org.jcoderz.phoenix.report.JcSummaryReportAntTask.setDest(String) ignores exceptional return value of java.io.File.mkdirs()
w (3) 166 : 0 org.jcoderz.phoenix.report.JcSummaryReportAntTask.setBaseDir(String) ignores exceptional return value of java.io.File.mkdirs()
w (4) 214 : 0 org.jcoderz.phoenix.report.JcSummaryReportAntTask.execute() ignores exceptional return value of java.io.File.mkdirs()
w (5) 262 : 0 org.jcoderz.phoenix.report.JcSummaryReportAntTask.writeSummaryDb(File, Map) ignores exceptional return value of java.io.File.createNewFile()
d (6) 270 : 31 [unchecked] unchecked call to ArrayList(java.util.Collection<? extends E>) as a member of the raw type java.util.ArrayList
d (7) 271 : 27 [unchecked] unchecked conversion found : java.util.List required: java.util.List<T>
d (8) 271 : 26 [unchecked] unchecked method invocation: <T>sort(java.util.List<T>) in java.util.Collections is applied to (java.util.List)
w (9) 337 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.readSummaryDb(File, File) invokes inefficient new Long(long) constructor; use Long.valueOf(long) instead
d (10) 337 : 30 [unchecked] unchecked call to put(K,V) as a member of the raw type java.util.Map
d (11) 350 : 22 [deprecation] safeClose(java.io.Reader) in org.jcoderz.commons.util.FileUtils has been deprecated
d (12) 351 : 22 [deprecation] safeClose(java.io.Reader) in org.jcoderz.commons.util.FileUtils has been deprecated
d (13) 374 : 22 [unchecked] unchecked call to put(K,V) as a member of the raw type java.util.Map
i (14) 458 : 0 method org.jcoderz.phoenix.report.JcSummaryReportAntTask.readSummaryXml(File, Long) throws exception with static message string
w (15) 478 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.storeInMap(Map, long, JcSummaryReportAntTask$Summary) invokes inefficient new Long(long) constructor; use Long.valueOf(long) instead
d (16) 486 : 19 [unchecked] unchecked call to put(K,V) as a member of the raw type java.util.Map
d (17) 492 : 18 [unchecked] unchecked call to put(K,V) as a member of the raw type java.util.Map
d (18) 498 : 19 [unchecked] unchecked call to put(K,V) as a member of the raw type java.util.Map
d (19) 501 : 18 [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
w (20) 512 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummaryDbMap(Map) makes inefficient use of keySet iterator instead of entrySet iterator
w (21) 532 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (22) 533 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (23) 534 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (24) 535 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (25) 536 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (26) 537 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (27) 538 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (28) 539 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (29) 540 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (30) 541 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
w (31) 542 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createSummary(String, File) assigns a variable in a larger scope then is needed
d (32) 569 : 26 [unchecked] unchecked call to TreeSet(java.util.Collection<? extends E>) as a member of the raw type java.util.TreeSet
i (33) 572 : 0 method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createQualityChart(Map, Map, String) throws exception with static message string
i (34) 575 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createQualityChart(Map, Map, String) creates array using constants
c (35) 575 : 0 Copied and pasted code. 113 equal tokens (18 lines) found in 3 locations. See also: org.jcoderz.phoenix.report.JcSummaryReportAntTask:621 org.jcoderz.phoenix.report.JcSummaryReportAntTask:669
d (36) 582 : 27 [unchecked] unchecked call to addAll(java.util.Collection<? extends E>) as a member of the raw type java.util.List
d (37) 583 : 24 [unchecked] unchecked conversion found : java.util.List required: java.util.List<T>
d (38) 583 : 23 [unchecked] unchecked method invocation: <T>sort(java.util.List<T>) in java.util.Collections is applied to (java.util.List)
d (39) 589 : 30 [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
d (40) 615 : 26 [unchecked] unchecked call to TreeSet(java.util.Collection<? extends E>) as a member of the raw type java.util.TreeSet
i (41) 618 : 0 method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createLocChart(Map, Map, String) throws exception with static message string
i (42) 621 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createLocChart(Map, Map, String) creates array using constants
c (43) 621 : 0 Copied and pasted code. 113 equal tokens (18 lines) found in 3 locations. See also: org.jcoderz.phoenix.report.JcSummaryReportAntTask:575 org.jcoderz.phoenix.report.JcSummaryReportAntTask:669
d (44) 628 : 27 [unchecked] unchecked call to addAll(java.util.Collection<? extends E>) as a member of the raw type java.util.List
d (45) 629 : 24 [unchecked] unchecked conversion found : java.util.List required: java.util.List<T>
d (46) 629 : 23 [unchecked] unchecked method invocation: <T>sort(java.util.List<T>) in java.util.Collections is applied to (java.util.List)
d (47) 635 : 30 [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
d (48) 662 : 25 [unchecked] unchecked call to TreeSet(java.util.Collection<? extends E>) as a member of the raw type java.util.TreeSet
i (49) 665 : 0 method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createFindingsChart(Map, Map, String) throws exception with static message string
w (50) 668 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createFindingsChart(Map, Map, String) creates array using constants
c (51) 669 : 0 Copied and pasted code. 113 equal tokens (18 lines) found in 3 locations. See also: org.jcoderz.phoenix.report.JcSummaryReportAntTask:575 org.jcoderz.phoenix.report.JcSummaryReportAntTask:621
d (52) 676 : 26 [unchecked] unchecked call to addAll(java.util.Collection<? extends E>) as a member of the raw type java.util.List
d (53) 677 : 23 [unchecked] unchecked conversion found : java.util.List required: java.util.List<T>
d (54) 677 : 22 [unchecked] unchecked method invocation: <T>sort(java.util.List<T>) in java.util.Collections is applied to (java.util.List)
d (55) 683 : 29 [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
w (56) 734 : 0 Method org.jcoderz.phoenix.report.JcSummaryReportAntTask.createChart(String, String[], Dataset, GraphChart2DProperties, MultiColorsProperties) assigns a variable in a larger scope then is needed
i (57) 734 : 0 Use of non-localized String.toUpperCase() or String.toLowerCase
d (58) 809 : 37 [unchecked] unchecked call to <T>toArray(T[]) as a member of the raw type java.util.List
c (59) 878 : 0 Line is longer than 80 characters.
c (60) 880 : 0 Line is longer than 80 characters.
d (61) 889 : 31 [unchecked] unchecked call to addAll(java.util.Collection<? extends E>) as a member of the raw type java.util.List
d (62) 890 : 27 [unchecked] unchecked conversion found : java.util.List required: java.util.List<T>
d (63) 890 : 26 [unchecked] unchecked method invocation: <T>sort(java.util.List<T>) in java.util.Collections is applied to (java.util.List)
d (64) 900 : 35 [unchecked] unchecked call to addAll(java.util.Collection<? extends E>) as a member of the raw type java.util.List
d (65) 901 : 30 [unchecked] unchecked conversion found : java.util.List required: java.util.List<T>
d (66) 901 : 29 [unchecked] unchecked method invocation: <T>sort(java.util.List<T>) in java.util.Collections is applied to (java.util.List)
d (67) 929 : 36 [unchecked] unchecked call to addAll(java.util.Collection<? extends E>) as a member of the raw type java.util.List
d (68) 930 : 33 [unchecked] unchecked conversion found : java.util.List required: java.util.List<T>
d (69) 930 : 32 [unchecked] unchecked method invocation: <T>sort(java.util.List<T>) in java.util.Collections is applied to (java.util.List)
c (70) 955 : 0 Line is longer than 80 characters.
c (71) 957 : 0 Line is longer than 80 characters.
c (72) 958 : 0 Line is longer than 80 characters.
c (73) 959 : 0 Line is longer than 80 characters.
c (74) 960 : 0 Line is longer than 80 characters.
c (75) 962 : 0 Line is longer than 80 characters.
i (76) 981 : 0 method org.jcoderz.phoenix.report.JcSummaryReportAntTask.renderHtmlView(Map, Map) throws exception with static message string
w (77) 1022 : 0 method org.jcoderz.phoenix.report.JcSummaryReportAntTask.wrapValue(JcSummaryReportAntTask$Summary, int, String, String) passes simple concatenating string in StringBuffer or StringBuilder append
w (78) 1231 : 0 org.jcoderz.phoenix.report.JcSummaryReportAntTask$Summary.equals(Object) is unusual