Project Report: fawkez

Packagesummary org.jcoderz.phoenix.report

org.jcoderz.phoenix.report.ReportNormalizer

LineHitsNoteSource
1  /*
2   * $Id: ReportNormalizer.java 1468 2009-05-11 16:49:58Z 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.io.File;
36  import java.io.FileNotFoundException;
37  import java.io.FileOutputStream;
38  import java.io.IOException;
39  import java.io.OutputStream;
40  import java.util.ArrayList;
41  import java.util.HashMap;
42  import java.util.List;
43  import java.util.Map;
44  import java.util.logging.Level;
45  import java.util.logging.Logger;
46  
47  import javax.xml.bind.JAXBException;
48  import javax.xml.transform.Transformer;
49  import javax.xml.transform.TransformerConfigurationException;
50  import javax.xml.transform.TransformerException;
51  import javax.xml.transform.TransformerFactory;
52  import javax.xml.transform.TransformerFactoryConfigurationError;
53  import javax.xml.transform.stream.StreamResult;
54  import javax.xml.transform.stream.StreamSource;
55  
56  import org.jcoderz.commons.util.FileUtils;
57  import org.jcoderz.commons.util.IoUtil;
58  import org.jcoderz.commons.util.LoggingUtils;
59  import org.jcoderz.phoenix.report.jaxb.Item;
60  import org.jcoderz.phoenix.report.jaxb.ObjectFactory;
61  
62  /**
63   * Provides merging of findbugs, pmd, checkstyle, cpd, and cobertura
64   * XML files into a single XML representation.
65   *
66   * @author Michael Griffel
67   * @author Michael Rumpf
68   */
69  public final class ReportNormalizer
70  {
71  
72      /** The Constant JCODERZ_REPORT_XML. */
73      public static final String JCODERZ_REPORT_XML
74          = "jcoderz-report.xml";
75  
76      /** The Constant CLASSNAME. */
770     private static final String CLASSNAME
78          = ReportNormalizer.class.getName();
79  
80      /** The Constant logger. */
810     private static final Logger logger
82          = Logger.getLogger(CLASSNAME);
83  
84      /** The project home. */
85      private File mProjectHome;
86  
87      /** The project name. */
880     private String mProjectName = "Unknown Project";
89  
90      /** The out file. */
91      private File mOutFile;
92  
93      /** The log level. */
940     private Level mLogLevel = Level.INFO;
95  
96      /** The report level. */
970     private ReportLevel mLevel = ReportLevel.PROD;
98  
99      /** The report list. */
1000     private List<SourceReport> mReportList
101          = new ArrayList<SourceReport>();
102  
103      /** The src list. */
1040     private List<SourceReport> mSrcList
105          = new ArrayList<SourceReport>();
106  
107      /**
108       * The XSL stylesheet that can be used to filter the
109       * jcoderz-report XML file.
110       */
1110     private File mFilterFile = null;
112  
113      /**
114       * Constructor.
115       *
116       * @throws IOException in case of any error.
117       */
118      public ReportNormalizer ()
119          throws IOException
1200     {
1210         mProjectHome = new File(".").getCanonicalFile();
1220         mOutFile = new File(JCODERZ_REPORT_XML);
1230     }
124  
125      /**
126       * Main method.
127       *
128       * @param args arguments.
129       *
130       * @throws Exception the exception
131       */
132      public static void main (String[] args)
133          throws Exception
134      {
135          try
136          {
1370             final ReportNormalizer rn = new ReportNormalizer();
1380             rn.parseArguments(args);
1390             rn.run();
140          }
1410         catch (Exception e)
142          {
1430             logger.log(Level.WARNING, "Failed in Normalizer.", e);
1440             throw e;
1450         }
1460     }
147  
148      /**
149       * Run ReportNormalizer.
150       */
151 (1)(2)(3)    public void run () throws JAXBException, IOException, TransformerException
152      {
1530         logger.fine("Running report normalizer on #" + mReportList.size()
154              + " reports ...");
1550         final Map<ResourceInfo, List<Item>> items
156              = new HashMap<ResourceInfo, List<Item>>();
1570         for (SourceReport report : mSrcList)
158          {
1590             handleReport(report, items);
160          }
1610         for (SourceReport report : mReportList)
162          {
1630             handleReport(report, items);
164          }
165  
1660         final JcoderzReport myReport = new JcoderzReport();
1670         myReport.setProjectHome(mProjectHome.getAbsolutePath());
1680         myReport.setProjectName(mProjectName);
1690         myReport.setLevel(mLevel);
170  
171          // XML report
1720         final OutputStream out = new FileOutputStream(mOutFile);
173          try
174          {
1750             myReport.write(out, items);
176          }
177          finally
178          {
1790             IoUtil.close(out);
1800         }
181  
182          // apply filters to the report
1830         if (mFilterFile != null)
184          {
1850             filter();
186          }
1870     }
188  
189      /**
190       * Handle report.
191       *
192       * @param report the report
193       * @param items the items
194       *
195       * @throws JAXBException the JAXB exception
196       */
197      private void handleReport (SourceReport report,
198          final Map<ResourceInfo, List<Item>> items)
199              throws JAXBException
200      {
201          try
202          {
2030             logger.fine("Processing report " + report.getReportFormat()
204                  + " '" + report.getFilename() + "'");
205              
206              
207              
2080             if (report.getFilename().length() != 0
209                  || report.getFilename().isDirectory())
210              {
2110                 final ReportReader reportReader
212                      = ReportReaderFactory.createReader(report);
2130                 reportReader.parse(report.getFilename());
2140                 reportReader.merge(items);
2150             }
216              else
217              {
2180                 logger.fine("Good job, no findings reported by "
219                      + report.getReportFormat());
220              }
221          }
2220         catch (Exception e)
223          {
2240             logger.log(Level.SEVERE, "Error while processing", e);
2250             final Item item = new ObjectFactory().createItem();
2260             item.setMessage("Error while Processing '"
227                  + report.getReportFormat() + "' '"
228                  + report.getFilename() + "' got Exception: '" + e + "'.");
2290             item.setSeverity(Severity.ERROR);
2300             item.setFindingType(SystemFindingType.SYS_PARSE_ERROR.getSymbol());
2310             item.setOrigin(Origin.SYSTEM);
2320             final ResourceInfo res
233                  = ResourceInfo.register(report.getFilename().getAbsolutePath(),
234                      "", report.getFilename().getAbsolutePath());
2350             if (items.containsKey(res))
236              {
2370                 items.get(res).add(item);
238              }
239              else
240              {
2410                 final List<Item> list = new ArrayList<Item>();
2420                 list.add(item);
2430                 items.put(res, list);
244              }
2450         }
2460     }
247  
248      /**
249       * Filters the report XML file using the JDK XSL processor.
250       *
251       * @throws TransformerFactoryConfigurationError
252    * the transformer factory configuration error
253       * @throws TransformerConfigurationException
254    * the transformer configuration exception
255       * @throws IOException Signals that an I/O exception has occurred.
256       * @throws TransformerException the transformer exception
257       * @throws FileNotFoundException the file not found exception
258       */
259      private void filter ()
260          throws TransformerFactoryConfigurationError,
261              TransformerConfigurationException, IOException,
262              TransformerException, FileNotFoundException
263      {
2640         logger.log(Level.FINE, "Filter: " + mFilterFile);
2650         final TransformerFactory tFactory = TransformerFactory.newInstance();
266  
2670         final Transformer transformer = tFactory.newTransformer(
268              new StreamSource(mFilterFile));
269  
2700         final File tempOutputFile = new File(
271              mOutFile.getCanonicalPath() + ".tmp");
2720         FileUtils.createNewFile(tempOutputFile);
273  
2740         final FileOutputStream out = new FileOutputStream(tempOutputFile);
275          try
276          {
2770             transformer.transform(new StreamSource(mOutFile),
278                  new StreamResult(out));
279          }
280          finally
281          {
2820             IoUtil.close(out);
2830         }
2840         FileUtils.copyFile(tempOutputFile, mOutFile);
2850         FileUtils.delete(tempOutputFile);
2860     }
287  
288      /**
289       * The following parameters select the different reports
290       * to combine into a single report.
291       *
292       * <ul>
293       * <li><code>-jcoverage jvoveragereport.xml</code> (http://???)</li>
294       * <li><code>-cobertura coberturareport.xml</code> (http://???)</li>
295       * <li><code>-checkstyle checkstylereport.xml</code>
296       * (http://checkstyle.sf.net)</li>
297       * <li><code>-findbugs findbugsreport.xml</code>
298       * (http://findbugs.sf.net)</li>
299       * <li><code>-pmd pmdreport.xml</code> (http://pmd.sf.net)</li>
300       * <li><code>-cpd cpdreport.xml</code> (http://))))</li>
301       * <li><code>-generic javadoc javadoc.log</code> (http://))))</li>
302       * </ul>
303       *
304       * <ul>
305       * <li><code>-projectHome</code></li>
306       * <li><code>-filter filter.xsl</code></li>
307       * <li><code>-srcDir</code></li>
308       * <li><code>-projectName</code></li>
309       * <li><code>-level PROD|TEST|MISC</code> The weight level</li>
310       * <li><code>-loglevel</code></li>
311       * <li><code>-out</code></li>
312       * </ul>
313       *
314       * @param args The command line arguments
315       *
316       * @return The list of reports to normalize
317       *
318       * @throws IOException When the filter file cannot be found
319       */
320 (4)    private void parseArguments (String[] args)
321          throws IOException
322      {
323          try
324          {
3250             for (int i = 0; i < args.length; )
326              {
3270                 logger.fine("Parsing argument '" + args[i] + "' = '"
328                      + args[i + 1] + "'");
329  
3300(5)                if (args[i].equals("-jcoverage"))
331                  {
3320                     addReport(ReportFormat.JCOVERAGE, args[i + 1]);
333                  }
3340(6)                else if (args[i].equals("-cobertura"))
335                  {
3360                     addReport(ReportFormat.COBERTURA, args[i + 1]);
337                  }
3380(7)                else if (args[i].equals("-checkstyle"))
339                  {
3400                     addReport(ReportFormat.CHECKSTYLE, args[i + 1]);
341                  }
3420(8)                else if (args[i].equals("-findbugs"))
343                  {
3440                     addReport(ReportFormat.FINDBUGS, args[i + 1]);
345                  }
3460(9)                else if (args[i].equals("-pmd"))
347                  {
3480                     addReport(ReportFormat.PMD, args[i + 1]);
349                  }
3500(10)                else if (args[i].equals("-emma"))
351                  {
3520                     addReport(ReportFormat.EMMA, args[i + 1]);
353                  }
3540(11)                else if (args[i].equals("-cpd"))
355                  {
3560                     addReport(ReportFormat.CPD, args[i + 1]);
357                  }
3580(12)                else if (args[i].equals("-generic"))
359                  {
3600                     addReport(ReportFormat.GENERIC, args[++i], args[i + 1]);
361                  }
3620(13)                else if (args[i].equals("-projectHome"))
363                  {
3640                     setProjectHome(new File(args[i + 1]));
365                  }
3660(14)                else if (args[i].equals("-filter"))
367                  {
3680                     setFilterFile(new File(args[i + 1]));
369                  }
3700(15)                else if (args[i].equals("-srcDir"))
371                  {
3720                     addReport(ReportFormat.SOURCE_DIRECTORY, args[i + 1]);
373                  }
3740(16)                else if (args[i].equals("-projectName"))
375                  {
3760                     setProjectName(args[i + 1]);
377                  }
3780(17)                else if (args[i].equals("-level"))
379                  {
3800                     setLevel(ReportLevel.fromString(args[i + 1]));
381                  }
3820(18)                else if (args[i].equals("-loglevel"))
383                  {
3840                     setLogLevel(Level.parse(args[i + 1]));
385                  }
3860(19)                else if (args[i].equals("-out"))
387                  {
3880                     setOutFile(new File(args[i + 1]));
389                  }
390                  else
391                  {
3920                     throw new IllegalArgumentException(
393                          "Invalid argument '" + args[i] + "'");
394                  }
395  
3960                 ++i;
3970                 ++i;
398              }
399          }
4000         catch (IndexOutOfBoundsException e)
401          {
4020             final IllegalArgumentException ex = new IllegalArgumentException(
403                  "Missing value for " + args[args.length - 1]);
4040             ex.initCause(e);
4050             throw ex;
4060         }
4070     }
408  
409      /**
410       * Adds the report.
411       *
412       * @param format the format
413       * @param file the file
414       */
415      public void addReport (ReportFormat format, String file)
416      {
4170         addReport(format, new File(file));
4180     }
419      
420      /**
421       * Adds the report with a given flavor.
422       * The flavor is used for generic reports to detect the type of file.
423       *
424       * @param format the format
425       * @param file the file
426       * @param flavor the flavor of the report.
427       */
428      public void addReport (ReportFormat format, String file, String flavor)
429      {
4300         mReportList.add(new SourceReport(format, new File(file), flavor));
4310     }
432  
433      /**
434       * Adds the report.
435       *
436       * @param format the format
437       * @param file the file
438       */
439      public void addReport (ReportFormat format, File file)
440      {
4410         if (format == ReportFormat.SOURCE_DIRECTORY)
442          {
4430             addSource(file);
444          }
445          else
446          {
4470             mReportList.add(new SourceReport(format, file));
448          }
4490     }
450  
451  
452 (20)    public void addSource (File srcDir)
453      {
4540         mSrcList.add(new SourceReport(
455              ReportFormat.SOURCE_DIRECTORY, srcDir));
4560     }
457  
458      /**
459       * Gets the project home.
460       *
461       * @return the project home
462       */
463      public File getProjectHome ()
464      {
4650         return mProjectHome;
466      }
467  
468      /**
469       * Sets the project home.
470       *
471       * @param projectHome the new project home
472       */
473      public void setProjectHome (File projectHome)
474      {
4750         mProjectHome = projectHome;
4760     }
477  
478      /**
479       * Gets the project name.
480       *
481       * @return the project name
482       */
483      public String getProjectName ()
484      {
4850         return mProjectName;
486      }
487  
488      /**
489       * Sets the project name.
490       *
491       * @param projectName the new project name
492       */
493      public void setProjectName (String projectName)
494      {
4950         mProjectName = projectName;
4960     }
497  
498      /**
499       * Gets the out file.
500       *
501       * @return the out file
502       */
503      public File getOutFile ()
504      {
5050         return mOutFile;
506      }
507  
508      /**
509       * Sets the out file.
510       *
511       * @param outFile the new out file
512       *
513       * @throws IOException Signals that an I/O exception has occurred.
514       */
515      public void setOutFile (File outFile) throws IOException
516      {
5170         if (outFile.isDirectory())
518          {
5190             mOutFile
520              = new File(outFile, JCODERZ_REPORT_XML).getCanonicalFile();
521          }
522          else
523          {
5240             mOutFile = outFile.getCanonicalFile();
525          }
5260     }
527  
528      /**
529       * Gets the log level.
530       *
531       * @return the log level
532       */
533      public Level getLogLevel ()
534      {
5350         return mLogLevel;
536      }
537  
538      /**
539       * Sets the log level.
540       *
541       * @param logLevel the new log level
542       */
543      public void setLogLevel (Level logLevel)
544      {
5450         mLogLevel = logLevel;
5460         LoggingUtils.setGlobalHandlerLogLevel(mLogLevel);
5470         logger.config("Setting log level: " + mLogLevel);
5480         Logger.getLogger("org.jcoderz.phoenix.report")
549              .setLevel(mLogLevel);
5500     }
551  
552      /**
553       * Gets the level.
554       *
555       * @return the level
556       */
557      public ReportLevel getLevel ()
558      {
5590         return mLevel;
560      }
561  
562      /**
563       * Sets the level.
564       *
565       * @param level the new level
566       */
567      public void setLevel (ReportLevel level)
568      {
5690         mLevel = level;
5700     }
571  
572      /**
573       * Gets the filter file.
574       *
575       * @return the filter file
576       */
577      public File getFilterFile ()
578      {
5790         return mFilterFile;
580      }
581  
582      /**
583       * Sets the filter file.
584       *
585       * @param filterFile the new filter file
586       *
587       * @throws IOException Signals that an I/O exception has occurred.
588       */
589      public void setFilterFile (File filterFile)
590          throws IOException
591      {
5920         mFilterFile = filterFile;
593          // Do not fail here if the argument is invalid.
5940         if (!mFilterFile.exists())
595          {
5960             throw new IOException("Filter file '" + mFilterFile
597                  + "' does not exists.");
598          }
5990     }
600  
601      /**
602       * The Class SourceReport.
603       */
604      public static final class SourceReport
605      {
606  
607          /** The report format. */
608          private final ReportFormat mReportFormat;
609  
610          /** The filename. */
611          private final File mFilename;
612  
613          /** The flavor. */
614          private final String mFlavor;
615          
616          /**
617           * Instantiates a new source report.
618           * No check here. Let the report parsing fail.
619           * @param r the ReportFormat
620           * @param f the File
621           */
622          SourceReport (ReportFormat r, File f)
623100         {
624100             mReportFormat = r;
625100             mFilename = f;
626100             mFlavor = null;
627100         }
628  
629          /**
630           * Instantiates a new source report.
631           * No check here. Let the report parsing fail.
632           * @param r the ReportFormat
633           * @param f the File
634           * @param flavor the report flavor
635           */
636          SourceReport (ReportFormat r, File f, String flavor)
6370         {
6380             mReportFormat = r;
6390             mFilename = f;
6400             mFlavor = flavor;
6410         }
642  
643          /**
644           * Returns the filename.
645           *
646           * @return the filename.
647           */
648          File getFilename ()
649          {
6500             return mFilename;
651          }
652  
653          /**
654           * Returns the reportFormat.
655           *
656           * @return the reportFormat.
657           */
658          ReportFormat getReportFormat ()
659          {
660100             return mReportFormat;
661          }
662  
663          /**
664           * Returns the report flavor.
665           *
666           * @return the report flavor.
667           */
668          public String getFlavor ()
669          {
6700             return mFlavor;
671          }
672      }
673  }

Findings in this File

c (1) 151 : 31 Expected @throws tag for 'JAXBException'.
c (2) 151 : 46 Expected @throws tag for 'IOException'.
c (3) 151 : 59 Expected @throws tag for 'TransformerException'.
c (4) 320 : 5 Cyclomatic Complexity is 18 (max allowed is 12).
i (5) 330 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (6) 334 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (7) 338 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (8) 342 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (9) 346 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (10) 350 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (11) 354 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (12) 358 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (13) 362 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (14) 366 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (15) 370 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (16) 374 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (17) 378 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (18) 382 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
i (19) 386 : 0 method org.jcoderz.phoenix.report.ReportNormalizer.parseArguments(String[]) makes literal string comparisons passing the literal as an argument
c (20) 452 : 5 Missing a Javadoc comment.