Project Report: fawkez

Packagesummary org.jcoderz.phoenix.report

org.jcoderz.phoenix.report.JcReportAntTask

LineHitsNoteSource
1  /*
2   * $Id: JcReportAntTask.java 1466 2009-05-10 18:37:30Z 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.FileOutputStream;
37  import java.io.IOException;
38  import java.nio.charset.Charset;
39  import java.util.ArrayList;
40  import java.util.Collections;
41  import java.util.HashSet;
42  import java.util.Iterator;
43  import java.util.List;
44  import java.util.Set;
45  import java.util.concurrent.ArrayBlockingQueue;
46  import java.util.concurrent.Callable;
47  import java.util.concurrent.CompletionService;
48  import java.util.concurrent.ExecutionException;
49  import java.util.concurrent.ExecutorCompletionService;
50  import java.util.concurrent.Future;
51  import java.util.concurrent.ThreadPoolExecutor;
52  import java.util.concurrent.TimeUnit;
53  import java.util.logging.Level;
54  
55  import javax.xml.bind.JAXBException;
56  import javax.xml.transform.TransformerException;
57  
58  import org.apache.tools.ant.BuildException;
59  import org.apache.tools.ant.Project;
60  import org.apache.tools.ant.Task;
61  import org.apache.tools.ant.taskdefs.Execute;
62  import org.apache.tools.ant.taskdefs.LogStreamHandler;
63  import org.apache.tools.ant.taskdefs.PumpStreamHandler;
64  import org.apache.tools.ant.types.CommandlineJava;
65  import org.apache.tools.ant.types.Path;
66  import org.apache.tools.ant.types.Environment.Variable;
67  import org.jcoderz.commons.taskdefs.AntTaskUtil;
68  import org.jcoderz.commons.types.Date;
69  import org.jcoderz.commons.util.ArraysUtil;
70  import org.jcoderz.commons.util.FileUtils;
71  import org.jcoderz.commons.util.StringUtil;
72  
73  /**
74   * This is the Ant task for the Jcoderz Report.
75   * This task forks all processing steps as separate processes
76   * so that memory for each process can be controlled separately.
77   *
78 (1) * TODO: Why are the inner classes static + take a JcReportAntTask?
79   *
80   * @author Michael Rumpf
81   */
820 public class JcReportAntTask
83     extends Task
84  {
85     private static final int DEFAULT_MAX_HEAP = 256;
860    private static final Date CREATION_TIMESTAMP = Date.now();
87     private static final int DEFAULT_CPUS = 2;
88  
890    private NestedReportsElement mReports = null;
900(2)   private NestedMappingsElement mMappings = null;
910    private NestedToolsElement mTools = null;
920    private final NestedFiltersElement mFilterElements
93         = new NestedFiltersElement();
940    private NestedLogfilesElement mLogfilesElements
95         = new NestedLogfilesElement();
96  
970    private String mName = null;
980    private File mDest = null;
990    private File mOldReportFile = null;
1000    private String mWikiBase = null;
1010    private String mWebRcsBase = null;
1020    private String mWebRcsSuffix = null;
1030    private String mPackageBase = null;
1040    private String mProjectBase = null;
1050    private String mStylesheet = null;
1060    private File mTempfolder = null;
1070    private int mMaxHeap = DEFAULT_MAX_HEAP;
1080    private int mCpus = DEFAULT_CPUS;
1090    private Charset mSourceEncoding = null;
1100    private boolean mDebug = false;
111  
1120    private File mWorkingDir = null;
113  
114     /** The global Java Commandline instance */
1150    private final CommandlineJava mCommandline = new CommandlineJava();
116     private int mMaxInner;
117  
118     /**
119      * @return the number of cpus to put load on.
120      */
121      public int getCpus ()
122      {
1230         return mCpus;
124      }
125  
126      /**
127       * @param cpus the cpus to set
128       */
129      public void setCpus (int cpus)
130      {
1310         mCpus = cpus;
1320     }
133  
134      /**
135       * @return the sourceEncoding
136       */
137      public String getEncoding ()
138      {
1390         return mSourceEncoding.name();
140      }
141  
142      /**
143       * @param encoding the sourceEncoding to set
144       */
145      public void setEncoding (String encoding)
146      {
1470         mSourceEncoding = Charset.forName(encoding);
1480     }
149  
150      /**
151      * Returns the working directory.
152      *
153      * @return the working directory.
154      */
155     public File getWorkingDir ()
156     {
1570       return mWorkingDir;
158     }
159  
160     /**
161      * Sets the maximum heap value.
162      * If not defined in the Ant task the default value of 512MB will be used.
163      *
164      * @param maxheap the max heap value.
165      */
166     public void setMaxHeap (String maxheap)
167     {
1680(3)      mMaxHeap = Integer.parseInt(maxheap);
1690    }
170  
171  
172     /**
173      * Sets the name of the report.
174 (4)    *
175      * @param name the report name.
176      */
177     public void setName (String name)
178 (5)   {
1790       mName = name;
1800    }
181  
182  
183     /**
184      * Sets the destination of the report.
185      *
186      * @param dest the report destination.
187      */
188     public void setDest (String dest)
189     {
1900       mDest = new File(dest);
1910       AntTaskUtil.ensureDirectory(mDest);
1920    }
193  
194  
195 (6)   public void setPackageBase (String packageBase)
196     {
1970       mPackageBase = packageBase;
1980    }
199  
200  
201 (7)   public void setProjectBase (String projectBase)
202     {
2030       mProjectBase = projectBase;
2040    }
205  
206  
207 (8)   public void setWebRcsBase (String webRcsBase)
208     {
2090       mWebRcsBase = webRcsBase;
2100    }
211  
212  
213 (9)   public void setWebRcsSuffix (String webRcsSuffix)
214     {
2150       mWebRcsSuffix = webRcsSuffix;
2160    }
217  
218  
219 (10)   public void setWikiBase (String wikiBase)
220     {
2210       mWikiBase = wikiBase;
2220    }
223  
224 (11)   public void setOldReportFile (String oldReportFile)
225     {
2260       mOldReportFile = new File(oldReportFile);
2270    }
228  
229     /**
230      * Sets the stylesheet to be used for the report.
231      *
232      * @param stylesheet the report stylesheet.
233      */
234     public void setStylesheet (String stylesheet)
235     {
2360       mStylesheet = stylesheet;
2370    }
238  
239  
240     /**
241      * Sets the temporary folder.
242      *
243      * @param tempfolder the temporary folder.
244      */
245     public void setTempfolder (String tempfolder)
246     {
2470       mTempfolder = new File(tempfolder);
2480    }
249  
250  
251     /**
252      * Sets the debug parameter.
253      *
254      * @param debug the debug parameter.
255      */
256     public void setDebug (Boolean debug)
257     {
2580       mDebug = debug.booleanValue();
2590    }
260  
261  
262 (12)   public Path createClasspath ()
263     {
2640       return mCommandline.createClasspath(getProject()).createPath();
265     }
266  
267  
268     /**
269      * This method is called by Ant for executing this task.
270      *
271      * @throws BuildException whenever a problem occurs.
272      */
273     public void execute ()
274        throws BuildException
275     {
276        try
277        {
278           // Always show this line
2790          super.log("Executing JcReportAntTask...");
280  
2810          checkParameters();
282  
283           // Delete the dest folder in case it exists so that we don't mix
284           // already deleted files. And create a fresh folder afterwards again.
2850          if (mDest.exists())
286           {
2870             FileUtils.rmdir(mDest);
2880             AntTaskUtil.ensureDirectory(mDest);
289           }
290  
291           // Now start processing the different reports
2920          log("Processing reports...");
293  
2940          final int max
295               = Math.min(mCpus + 1 , mReports.getReports().size());
2960          mMaxInner = 1 + (mCpus / max);
2970          super.log("Decided to have " + max + " report types with "
298               + mMaxInner + " reports each in parallel.");
2990          final CompletionService<File> service
300               = new ExecutorCompletionService<File>(
301                   new ThreadPoolExecutor(max, max, 0, TimeUnit.SECONDS,
302                       new ArrayBlockingQueue<Runnable>(
303                           mReports.getReports().size())));
304  
3050          final List<Future<File>> jcReports = new ArrayList<Future<File>>();
3060          final Iterator<NestedReportElement> iterReport
307               = mReports.getReports().iterator();
3080          while (iterReport.hasNext())
309           {
3100             final NestedReportElement nre = iterReport.next();
3110             log("Processing report '" + nre.getName() + "' ...");
3120             final Future<File> jcReport = service.submit(
313                  new Callable<File> ()
3140                 {
315                      public File call ()
316                          throws InterruptedException, ExecutionException,
317                              IOException, JAXBException, TransformerException
318                      {
319                          final File result;
3200                         log("Starting: " + nre.getName()
321                              + " for " + nre.getSourcePath() + ".");
3220                         result = performNestedReport(nre);
3230                         log("Done: " + nre.getName()
324                              + " got " + nre.getSourcePath() + ".");
3250                         return result;
326                      }
327                  }
328              );
3290             jcReports.add(jcReport);
3300          }
331  
3320          final File jcReport = executeReportMerger(jcReports);
3330          executeJava2Html(jcReport);
334        }
3350       catch (Exception ex)
336        {
3370(13)         log(ex.toString(), ex, Project.MSG_ERR); // CHECKME!
3380          throw new BuildException("An unexpected exception occured!", ex);
3390       }
3400    }
341  
342  
343      private File performNestedReport (final NestedReportElement nre)
344          throws InterruptedException, ExecutionException, IOException,
345              JAXBException, TransformerException
346      {
347          // Create a temp folder for this report
3480         final File reportTmpDir = new File(mWorkingDir, nre.getName());
3490         AntTaskUtil.ensureDirectory(reportTmpDir);
3500         final File srcDir = new File(nre.getSourcePath());
3510         final File clsDir = new File(nre.getClassPath());
352  
3530         final CompletionService<File> service
354              = new ExecutorCompletionService<File>(
355                  new ThreadPoolExecutor(mMaxInner, mMaxInner, 0,
356                      TimeUnit.SECONDS,
357                      new ArrayBlockingQueue<Runnable>(5))); // 2 max threads?
358  
359  
3600         File pmdXml = null;
3610         final Future<File> pmdResult
362              = submit(mTools.getPmd(), reportTmpDir,
363                  srcDir, clsDir, service);
364  
3650         File checkstyleXml = null;
3660         final Future<File> checkstyleResult
367              = submit(mTools.getCheckstyle(), reportTmpDir,
368                  srcDir, clsDir, service);
369  
3700         File findbugsXml = null;
3710         final Future<File> findbugsResult
372              = submit(mTools.getFindbugs(), reportTmpDir,
373                  srcDir, clsDir, service);
374  
3750         File cpdXml = null;
3760         final Future<File> cpdResult
377              = submit(mTools.getCpd(), reportTmpDir,
378                  srcDir, clsDir, service);
379  
3800         File coberturaXml = null;
3810         final Future<File> coberturaResult
382              = submit(mTools.getCobertura(), reportTmpDir,
383                  srcDir, clsDir, service);
384  
385          // now get the results....
3860         if (checkstyleResult != null)
387          { // EXCEPTION?
3880             checkstyleXml = checkstyleResult.get();
389          }
3900         if (findbugsResult != null)
391          { // EXCEPTION?
3920             findbugsXml = findbugsResult.get();
393          }
3940         if (pmdResult != null)
395          { // EXCEPTION?
3960             pmdXml = pmdResult.get();
397          }
3980         if (cpdResult != null)
399          { // EXCEPTION?
4000             cpdXml = cpdResult.get();
401          }
4020         if (coberturaResult != null)
403          { // EXCEPTION?
4040             coberturaXml = coberturaResult.get();
405          }
406  
407          final File emmaFile;
4080         if (mTools.getEmma() != null)
409          { // EXCEPTION?
4100             emmaFile = new File(mTools.getEmma().mDatafile);
411          }
412          else
413          {
4140             emmaFile = null;
415          }
416  
417          // Merge the different reports into one jcoderz-report.xml
418          // This must be done on a level by level basis
4190         return executeReportNormalizer(srcDir, reportTmpDir,
420                nre.getLevel(), checkstyleXml, findbugsXml, pmdXml,
421                cpdXml, coberturaXml, emmaFile);
422      }
423  
424  
425      private Future<File> submit (final NestedToolElement nce,
426          final File reportTmpDir, final File srcDir, final File clsDir,
427          CompletionService<File> service)
428      {
4290         Future<File> result = null;
4300         if (nce != null)
431          {
4320            result = service.submit(
433                 new Callable<File> ()
4340                {
435                     public File call ()
436                     {
437                         final File result;
4380                        log("Starting: " + nce.toString() + " for " + srcDir
439                             + ".");
4400                        result = nce.execute(reportTmpDir, srcDir, clsDir);
4410                        log("Done: " + nce.toString() + " got " + result + ".");
4420                        return result;
443                     }
444                 }
445             );
446          }
4470         return result;
448      }
449  
450  
451     private void checkParameters ()
452     {
4530        if (mTempfolder == null)
454         {
4550            throw new BuildException("You must specify a temporary folder!",
456                 getLocation());
457         }
4580        AntTaskUtil.ensureDirectory(mTempfolder);
4590        mWorkingDir = new File(mTempfolder, mName);
4600        AntTaskUtil.ensureDirectory(mWorkingDir);
461  
462         // Check that the names of the reports differ!
4630        final Set<String> reportNames = new HashSet<String>();
4640        final Iterator<NestedReportElement> iterReport
465             = mReports.getReports().iterator();
4660        while (iterReport.hasNext())
467         {
4680            final NestedReportElement nre = iterReport.next();
4690            reportNames.add(nre.getName());
4700        }
4710        if (reportNames.size() != mReports.getReports().size())
472         {
4730            throw new BuildException("Reports must not have the same names!",
474                 getLocation());
475         }
4760    }
477  
478  
479     /**
480      * Executes the report normalizer in a separate process.
481      *
482      * The following command line parameters are supported:
483      * <ul>
484      *   <li><code>-cobertura coberturareport.xml</code>
485      *   (http://cobertura.sf.net)</li>
486      *   <li><code>-checkstyle checkstylereport.xml</code>
487      *   (http://checkstyle.sf.net)</li>
488      *   <li><code>-findbugs findbugsreport.xml</code>
489      *   (http://findbugs.sf.net)</li>
490      *   <li><code>-pmd pmdreport.xml</code>
491      *   (http://pmd.sf.net)</li>
492      *   <li><code>-cpd cpdreport.xml</code>
493      *   (http://pmd.sf.net)</li>
494      *   <li><code>-projectHome</code></li>
495      *   <li><code>-srcDir</code></li>
496      *   <li><code>-projectName</code></li>
497      *   <li><code>-level PROD|TEST|MISC</code> The weight level</li>
498      *   <li><code>-out</code></li>
499      * </ul>
500      */
501     private File executeReportNormalizer (File srcDir, File reportDir,
502              ReportLevel level, File checkstyleXml,
503              File findbugsXml, File pmdXml, File cpdXml, File coberturaXml,
504              File emmaSummary)
505         throws IOException, JAXBException, TransformerException
506     {
507        // INLINE failed, got java.lang.OutOfMemoryError: PermGen space
5080       log("Creating report normalizer command line...");
5090       final CommandlineJava cmd = createCommandlineJava(mCommandline, mMaxHeap);
510  
5110       cmd.setClassname("org.jcoderz.phoenix.report.ReportNormalizer");
512  
5130       cmd.createArgument().setValue("-srcDir");
5140       cmd.createArgument().setFile(srcDir);
515  
5160       cmd.createArgument().setValue("-level");
5170       cmd.createArgument().setValue(level.toString());
518  
5190       if (mDebug)
520        {
5210          cmd.createArgument().setValue("-loglevel");
5220          cmd.createArgument().setValue("FINEST");
523        }
524  
5250       cmd.createArgument().setValue("-projectName");
5260       cmd.createArgument().setValue(mName);
527  
5280       cmd.createArgument().setValue("-out");
5290       cmd.createArgument().setFile(reportDir);
530  
5310       if (checkstyleXml != null)
532        {
5330          cmd.createArgument().setValue("-checkstyle");
5340          cmd.createArgument().setFile(checkstyleXml);
535        }
536  
5370       if (findbugsXml != null)
538        {
5390          cmd.createArgument().setValue("-findbugs");
5400          cmd.createArgument().setFile(findbugsXml);
541        }
542  
5430       if (pmdXml != null)
544        {
5450          cmd.createArgument().setValue("-pmd");
5460          cmd.createArgument().setFile(pmdXml);
547        }
548  
5490       if (cpdXml != null)
550        {
5510          cmd.createArgument().setValue("-cpd");
5520          cmd.createArgument().setFile(cpdXml);
553        }
554  
5550       if (coberturaXml != null)
556        {
5570          cmd.createArgument().setValue("-cobertura");
5580          cmd.createArgument().setFile(coberturaXml);
559        }
560  
5610       if (emmaSummary != null)
562        {
5630          cmd.createArgument().setValue("-emma");
5640          cmd.createArgument().setFile(emmaSummary);
565        }
566  
5670       for (NestedLogfileElement nge : mLogfilesElements.mGenericReaders)
568        {
5690           cmd.createArgument().setValue("-generic");
5700           cmd.createArgument().setFile(nge.getFile());
5710           cmd.createArgument().setValue(nge.getType());
572        }
573  
5740       forkToolProcess(this, cmd, new LogStreamHandler(this, Project.MSG_INFO,
575           Project.MSG_WARN));
576  
5770       return new File(reportDir, ReportNormalizer.JCODERZ_REPORT_XML);
578     }
579  
580  
581     private File executeReportMerger (List<Future<File>> jcReports)
582         throws InterruptedException, ExecutionException, IOException,
583             JAXBException, TransformerException
584     {
5850       log("Preparing report merger...");
5860       final ReportMerger merger = new ReportMerger();
5870       if (mDebug)
588        {
5890           merger.setLogLevel(Level.ALL);
590        }
5910       merger.setOutFile(mWorkingDir);
5920       final Iterator<Future<File>> jcReportIter = jcReports.iterator();
5930       while (jcReportIter.hasNext())
594        {
5950          final File jcReport = jcReportIter.next().get();
5960          merger.addReport(jcReport);
5970       }
5980       final Iterator<NestedFilterElement> filterIter
599            = mFilterElements.getFilters().iterator();
6000       while (filterIter.hasNext())
601        {
6020          final NestedFilterElement filterElement = filterIter.next();
6030          merger.addFilter(filterElement.getFile());
6040       }
6050       merger.merge();
6060       merger.filter();
6070       if (mOldReportFile != null)
608        {
6090           merger.setOldFile(mOldReportFile);
6100           merger.flagNewFindings();
611        }
612  
6130       final File outFile = new File(mWorkingDir,
614           ReportNormalizer.JCODERZ_REPORT_XML);
615        try
616        {
6170          FileUtils.copy(outFile, mDest);
618        }
6190       catch (IOException e)
620        {
6210          throw new BuildException("Could not copy '" + outFile
622                 + "' to destination folder '" + mDest + "'!", e, getLocation());
6230       }
624  
6250       return outFile;
626     }
627  
628  
629     /**
630      * Executes the Java2Html tool in a separate process.
631      *
632      * The following command line parameters are supported:
633      * <pre>
634      * -outDir
635      * -report
636      * -projectHome
637      * -projectName
638      * -cvsBase
639      * -timestamp
640      * -wikiBase
641      * -reportStyle
642      * -packageBase
643      * </pre>
644      */
645     private void executeJava2Html (File jcReport)
646     {
6470       log("Creating java2html command line...");
648  
6490       final CommandlineJava cmd = createCommandlineJava(mCommandline, mMaxHeap);
650  
6510       cmd.setClassname("org.jcoderz.phoenix.report.Java2Html");
652  
653        // let it run in headless mode to avoid exceptions because of a missing X
6540       cmd.createVmArgument().setValue("-Djava.awt.headless=true");
655  
6560       cmd.createArgument().setValue("-outDir");
6570       cmd.createArgument().setFile(mDest);
658  
6590       cmd.createArgument().setValue("-report");
6600       cmd.createArgument().setFile(jcReport);
661  
6620       cmd.createArgument().setValue("-timestamp");
6630       cmd.createArgument().setValue(CREATION_TIMESTAMP.toString(
664              "yyyyMMddHHmmss"));
665  
6660       if (mProjectBase != null)
667        {
6680          cmd.createArgument().setValue("-projectHome");
6690          cmd.createArgument().setValue(mProjectBase);
670        }
671  
6720       if (mStylesheet != null)
673        {
6740          cmd.createArgument().setValue("-reportStyle");
6750          cmd.createArgument().setValue(mStylesheet);
676        }
677  
6780       cmd.createArgument().setValue("-projectName");
6790       cmd.createArgument().setValue(mName);
680  
6810       cmd.createArgument().setValue("-cvsBase");
6820       cmd.createArgument().setValue(mWebRcsBase);
683  
6840       if (!StringUtil.isNullOrBlank(mWebRcsSuffix))
685        {
6860           cmd.createArgument().setValue("-cvsSuffix");
6870           cmd.createArgument().setValue(mWebRcsSuffix);
688        }
689  
6900       cmd.createArgument().setValue("-wikiBase");
6910       cmd.createArgument().setValue(mWikiBase);
692  
6930       if (mPackageBase != null)
694        {
6950          cmd.createArgument().setValue("-packageBase");
6960          cmd.createArgument().setValue(mPackageBase);
697        }
698  
6990       if (mSourceEncoding != null)
700        {
7010           cmd.createArgument().setValue("-sourceEncoding");
7020           cmd.createArgument().setValue(getEncoding());
703        }
7040       if (mDebug)
705        {
7060          cmd.createArgument().setValue("-loglevel");
7070          cmd.createArgument().setValue("FINEST");
708        }
709  
7100       forkToolProcess(this, cmd, new LogStreamHandler(this, Project.MSG_INFO,
711           Project.MSG_WARN));
7120    }
713  
714  
715     //
716     // Reports section
717     //
718  
719  
720     /**
721      * This method is called by Ant to create an instance of the
722      * NestedReportsElement class when the 'reports' tag is read.
723      *
724      * @return the new instance of type NestedReportsElement.
725      */
726     public NestedReportsElement createReports ()
727     {
7280       mReports = new NestedReportsElement(this);
7290       return mReports;
730     }
731  
732  
733     public static class NestedReportsElement
734     {
7350       private List<NestedReportElement> mReports
736            = new ArrayList<NestedReportElement>();
737        private JcReportAntTask mTask;
738  
739        public NestedReportsElement (JcReportAntTask task)
7400       {
7410          mTask = task;
7420       }
743  
744  
745        public NestedReportElement createReport ()
746        {
7470          mTask.log("Creating report element...");
7480          final NestedReportElement nre = new NestedReportElement();
7490          mReports.add(nre);
7500          return nre;
751        }
752  
753  
754        public List<NestedReportElement> getReports ()
755        {
7560          return Collections.unmodifiableList(mReports);
757        }
758     }
759  
760  
761     /**
762      * This class represents a &lt;report&gt; tag in an Ant
763      * <code>build.xml</code> file.
764      *
765      * @author Michael Rumpf
766      */
7670    public static class NestedReportElement
768     {
769        private String mName;
770        private ReportLevel mLevel;
771        private String mSourcePath;
772        private String mClassPath;
773  
774        public String getName ()
775        {
7760          return mName;
777        }
778  
779  
780        public void setName (String name)
781        {
7820          mName = name;
7830       }
784  
785        public ReportLevel getLevel ()
786        {
7870          return mLevel;
788        }
789  
790  
791        public void setLevel (String level)
792        {
7930          mLevel = ReportLevel.fromString(level);
7940       }
795  
796  
797        public String getClassPath ()
798        {
7990          return mClassPath;
800        }
801  
802  
803        public void setClassPath (String classPath)
804        {
8050          mClassPath = classPath;
8060       }
807  
808  
809        public String getSourcePath ()
810        {
8110          return mSourcePath;
812        }
813  
814  
815        public void setSourcePath (String sourcePath)
816        {
8170          mSourcePath = sourcePath;
8180       }
819     }
820  
821  
822     //
823     // Mappings section
824     //
825  
826  
827     /**
828      * This method is called by Ant to create an instance of the
829      * NestedMappingsElement class when the 'mappings' tag is read.
830      *
831      * @return the new instance of type NestedMappingsElement.
832      */
833     public NestedMappingsElement createMappings ()
834     {
8350       mMappings = new NestedMappingsElement(this);
8360       return mMappings;
837     }
838  
839  
840     public static class NestedMappingsElement
841     {
8420       private List<NestedMappingElement> mMappings
843            = new ArrayList<NestedMappingElement>();
844        private JcReportAntTask mTask;
845  
846        public NestedMappingsElement (JcReportAntTask task)
8470       {
8480          mTask = task;
8490       }
850  
851        public NestedMappingElement createWebRcs ()
852        {
8530          mTask.log("Creating mapping element...");
8540          final NestedMappingElement nme = new NestedMappingElement();
8550          mMappings.add(nme);
8560          return nme;
857        }
858  
859        public List<NestedMappingElement> getMappings ()
860        {
8610          return mMappings;
862        }
863     }
864  
865  
8660    public static class NestedMappingElement
867     {
868        private String mPattern;
869        private String mUrl;
870        private String mSuffix;
871  
872  
873        public String getPattern ()
874        {
8750          return mPattern;
876        }
877  
878  
879        public void setPattern (String pattern)
880        {
8810          mPattern = pattern;
8820       }
883  
884  
885        public String getSuffix ()
886        {
8870          return mSuffix;
888        }
889  
890  
891        public void setSuffix (String suffix)
892        {
8930          mSuffix = suffix;
8940       }
895  
896  
897        public String getUrl ()
898        {
8990          return mUrl;
900        }
901  
902  
903        public void setUrl (String url)
904        {
9050          mUrl = url;
9060       }
907     }
908  
909  
910     //
911     // Tools section
912     //
913  
914  
915     /**
916      * This method is called by Ant to create an instance of the
917      * NestedToolsElement class when the 'tools' tag is read.
918      *
919      * @return the new instance of type NestedToolsElement.
920      */
921     public NestedToolsElement createTools ()
922     {
9230       mTools = new NestedToolsElement(this);
9240       return mTools;
925     }
926  
927  
928     public static class NestedToolsElement
929     {
930        private JcReportAntTask mTask;
9310       private NestedPmdElement mPmd = null;
9320       private NestedCpdElement mCpd = null;
9330       private NestedFindbugsElement mFindbugs = null;
9340       private NestedCheckstyleElement mCheckstyle = null;
9350       private NestedCoberturaElement mCobertura = null;
9360       private NestedEmmaElement mEmma = null;
937  
938        public NestedToolsElement (JcReportAntTask task)
9390       {
9400          mTask = task;
9410       }
942  
943  
944        public NestedPmdElement createPmd ()
945        {
9460          mTask.log("Creating Pmd element...");
9470          mPmd = new NestedPmdElement(mTask);
9480          return mPmd;
949        }
950  
951  
952        public NestedPmdElement getPmd ()
953        {
9540          return mPmd;
955        }
956  
957  
958        public NestedCpdElement createCpd ()
959        {
9600          mTask.log("Creating Cpd element...");
9610          mCpd = new NestedCpdElement(mTask);
9620          return mCpd;
963        }
964  
965  
966        public NestedCpdElement getCpd ()
967        {
9680          return mCpd;
969        }
970  
971  
972        public NestedFindbugsElement createFindbugs ()
973        {
9740          mTask.log("Creating Findbugs element...");
9750          mFindbugs = new NestedFindbugsElement(mTask);
9760          return mFindbugs;
977        }
978  
979  
980        public NestedFindbugsElement getFindbugs ()
981        {
9820          return mFindbugs;
983        }
984  
985  
986        public NestedCheckstyleElement createCheckstyle ()
987        {
9880          mTask.log("Creating Checkstyle element...");
9890          mCheckstyle = new NestedCheckstyleElement(mTask);
9900          return mCheckstyle;
991        }
992  
993  
994        public NestedCheckstyleElement getCheckstyle ()
995        {
9960          return mCheckstyle;
997        }
998  
999  
1000        public NestedCoberturaElement createCobertura ()
1001        {
10020          mTask.log("Creating Cobertura element...");
10030          mCobertura = new NestedCoberturaElement(mTask);
10040          return mCobertura;
1005        }
1006  
1007  
1008        public NestedCoberturaElement getCobertura ()
1009        {
10100          return mCobertura;
1011        }
1012  
1013        public NestedEmmaElement createEmma ()
1014        {
10150          mTask.log("Creating Emma element...");
10160          mEmma = new NestedEmmaElement(mTask);
10170          return mEmma;
1018        }
1019  
1020        public NestedEmmaElement getEmma ()
1021        {
10220          return mEmma;
1023        }
1024     }
1025  
1026  
1027     /**
1028      * This is the base class for all tool elements.
1029      * It provides support for the maxheap attribute
1030      * and the nested classpath element.
1031      *
1032      * @author Michael Rumpf
1033      */
1034     public abstract static class NestedToolElement
1035     {
1036        protected JcReportAntTask mTask;
1037        protected Path mPath;
1038        protected int mMaxHeap;
1039  
1040        /** The global Java Commandline instance */
10410       protected final CommandlineJava mCommandline = new CommandlineJava();
1042  
1043        public NestedToolElement (JcReportAntTask task)
10440       {
10450           mTask = task;
10460           mMaxHeap = mTask.mMaxHeap;
10470       }
1048  
1049        /**
1050         * Sets the maximum heap value.
1051         * If not defined in the Ant task the default value of 512MB will be used.
1052         *
1053         * @param maxheap the max heap value.
1054         */
1055        public void setMaxheap (String maxheap)
1056        {
10570          mMaxHeap = Integer.parseInt(maxheap);
10580       }
1059  
1060  
1061        /**
1062         * Creates a classpath for the tool element.
1063         *
1064         * @return the created classpath.
1065         */
1066        public Path createClasspath ()
1067        {
10680          mPath = mCommandline.createClasspath(mTask.getProject()).createPath();
10690          return mPath;
1070        }
1071  
1072        public abstract File execute (File reportDir, File srcDir, File clsDir);
1073     }
1074  
1075  
1076     public static class NestedPmdElement
1077           extends NestedToolElement
1078     {
1079        private String mConfig;
1080        private String mTargetjdk;
1081        private String mEncoding;
1082  
1083        public NestedPmdElement (JcReportAntTask task)
1084        {
10850          super(task);
10860          mCommandline.setClassname("net.sourceforge.pmd.PMD");
10870       }
1088  
1089  
1090        public void setConfig (String config)
1091        {
10920          mConfig = config;
10930       }
1094  
1095  
1096        public void setTargetjdk (String targetjdk)
1097        {
10980          mTargetjdk = targetjdk;
10990       }
1100  
1101  
1102        public void setEncoding (String encoding)
1103        {
11040          mEncoding = encoding;
11050       }
1106  
1107  
1108        public File execute (File reportDir, File srcDir, File clsDir)
1109        {
11100          mTask.log("Creating pmd command line...");
11110          final CommandlineJava cmd
1112               = createCommandlineJava(mCommandline, mMaxHeap);
1113  
11140          cmd.createArgument().setFile(srcDir);
1115  
1116           // We always write pmd reports in XML format
11170          cmd.createArgument().setValue("xml");
1118  
11190          if (mConfig != null)
1120           {
11210             cmd.createArgument().setFile(new File(mConfig));
1122           }
1123  
11240          if (mEncoding != null)
1125           {
11260             cmd.createArgument().setValue("-encoding");
11270             cmd.createArgument().setValue(mEncoding);
1128           }
11290          else if (mTask.getEncoding() != null)
1130           {
11310              cmd.createArgument().setValue("-encoding");
11320              cmd.createArgument().setValue(mTask.getEncoding());
1133           }
1134  
11350          if (mTargetjdk != null)
1136           {
11370             cmd.createArgument().setValue("-targetjdk");
11380             cmd.createArgument().setValue(mTargetjdk);
1139           }
1140  
11410          final File outFile = new File(reportDir, "pmd.xml");
11420          FileOutputStream fos = null;
1143           try
1144           {
11450             fos = new FileOutputStream(outFile);
1146           }
11470          catch (IOException e)
1148           {
11490             throw new BuildException("Could not find output file: "
1150                    + outFile.getAbsolutePath(), e, mTask.getLocation());
11510          }
1152  
11530          forkToolProcess(mTask, cmd, new PumpStreamHandler(fos, System.err));
1154  
11550          return outFile;
1156        }
1157     }
1158  
1159  
1160     public static class NestedCpdElement
1161           extends NestedToolElement
1162     {
1163        private static final int DEFAULT_MINIMUM_TOKENS = 100;
11640       private int mMinimumtokens = DEFAULT_MINIMUM_TOKENS;
11650       private String mEncoding = null;
11660       private String mOutputEncoding = "UTF-8";
1167  
1168        public NestedCpdElement (JcReportAntTask task)
1169        {
11700           super(task);
11710          mCommandline.setClassname("net.sourceforge.pmd.cpd.CPD");
11720       }
1173  
1174        public void setMinimumtokens (String minimumtokens)
1175        {
11760          mMinimumtokens = Integer.parseInt(minimumtokens);
11770       }
1178  
1179        public void setEncoding (String encoding)
1180        {
11810          mEncoding = encoding;
11820       }
1183  
1184        public void setOutputEncoding (String encoding)
1185        {
11860          mOutputEncoding = encoding;
11870       }
1188  
1189        /**
1190         * Executes the cpd tool in a separate process.
1191         *
1192         * The following command line switches are supported by this method:
1193         * <pre>
1194         * CPD --minimum-tokens xxx --files xxx
1195         * </pre>
1196         */
1197        public File execute (File reportDir, File srcDir, File clsDir)
1198        {
11990          mTask.log("Creating cpd command line...");
12000          final CommandlineJava cmd
1201               = createCommandlineJava(mCommandline, mMaxHeap);
1202  
12030          final Variable var = new Variable();
12040          var.setKey("file.encoding");
12050          var.setValue(mOutputEncoding);
12060          cmd.getSystemProperties().addVariable(var);
1207  
12080          cmd.createArgument().setFile(srcDir);
1209  
1210           // We always write pmd reports in XML format
12110          cmd.createArgument().setValue("--format");
12120          cmd.createArgument().setValue("net.sourceforge.pmd.cpd.XMLRenderer");
1213  
12140          if (mEncoding != null)
1215           {
12160              cmd.createArgument().setValue("--encoding");
12170              cmd.createArgument().setValue(mEncoding);
1218           }
12190          else if (mTask.getEncoding() != null)
1220           {
12210              cmd.createArgument().setValue("--encoding");
12220              cmd.createArgument().setValue(mTask.getEncoding());
1223           }
1224  
1225  
12260          cmd.createArgument().setValue("--language");
12270          cmd.createArgument().setValue("java");
1228  
12290          cmd.createArgument().setValue("--files");
12300          cmd.createArgument().setFile(srcDir);
1231  
12320          cmd.createArgument().setValue("--minimum-tokens");
12330          cmd.createArgument().setValue(String.valueOf(mMinimumtokens));
1234  
12350          final File outFile = new File(reportDir, "cpd.xml");
12360          FileOutputStream fos = null;
1237           try
1238           {
12390             fos = new FileOutputStream(outFile);
1240           }
12410          catch (IOException e)
1242           {
12430             throw new BuildException("Could not find output file: "
1244                    + outFile.getAbsolutePath(), e, mTask.getLocation());
12450          }
1246  
12470          forkToolProcess(mTask, cmd, new PumpStreamHandler(fos, System.err));
1248  
12490          return outFile;
1250        }
1251     }
1252  
1253  
1254     public static class NestedFindbugsElement
1255           extends NestedToolElement
1256     {
1257        private String mConfig;
12580       private String mWarninglevel = "medium";
12590       private String mEffort = "default";
12600       private String mOmitVisitors = "";
1261        private Path mAuxPath;
12620       private boolean mFindBugsDebug = false;
1263        /**
1264         * Path of the findbugs plugin jar files. Must at least contain
1265         * the coreplugin.jar
1266         */
1267        private Path mPluginList;
1268  
1269        public NestedFindbugsElement (JcReportAntTask task)
1270        {
12710          super(task);
12720          mCommandline.setClassname("edu.umd.cs.findbugs.FindBugs2");
12730       }
1274  
1275  
1276        /**
1277         * Sets the debug parameter.
1278         * @param debug the debug parameter.
1279         */
1280        public void setDebug (Boolean debug)
1281        {
12820           mFindBugsDebug = debug.booleanValue();
12830       }
1284  
1285        public void setOmitVisitors (String omitVisitors)
1286        {
12870          mOmitVisitors = omitVisitors;
12880       }
1289  
1290        public void setConfig (String config)
1291        {
12920          mConfig = config;
12930       }
1294  
1295        public void setEffort (String effort)
1296        {
12970          if ("min".equals(effort) || "default".equals(effort)
1298                 || "max".equals(effort))
1299           {
13000             mEffort = effort;
1301           }
1302           else
1303           {
13040             mTask.log("Invalid effort value '" + effort + "!'");
1305           }
13060       }
1307  
1308  
1309        public void setWarninglevel (String warninglevel)
1310        {
13110          if ("experimental".equals(warninglevel) || "low".equals(warninglevel)
1312                 || "medium".equals(warninglevel) || "high".equals(warninglevel))
1313           {
13140             mWarninglevel = warninglevel;
1315           }
1316           else
1317           {
13180             mTask.log("Invalid warninglevel value '" + warninglevel + "!'");
1319           }
13200       }
1321  
1322  
1323        /**
1324         * The findbugs tool needs an list of jar files where all the plugins are
1325         * defined in. Minimum plugin list contains the coreplugin.
1326         *
1327         * @return the created plugin list path.
1328         */
1329        public Path createPluginlist ()
1330        {
13310          mPluginList = new Path(mTask.getProject());
13320          return mPluginList;
1333        }
1334  
1335        /**
1336         * The findbugs tool needs an auxiliary classpath with all the classes,
1337         * referenced from the project class files.
1338         *
1339         * @return the created auxiliary classpath.
1340         */
1341        public Path createAuxclasspath ()
1342        {
13430          mAuxPath = new Path(mTask.getProject());
13440          return mAuxPath;
1345        }
1346  
1347  
1348        /**
1349         * Executes the findbugs tool in a separate process.
1350         * <pre>
1351         * maxheap:
1352         *   -maxHeap size    Maximum Java heap size in megabytes (default=256)
1353         *
1354         * effort:
1355         *   -effort[:min|default|max] set analysis effort level
1356         *
1357         *  warninglevel:
1358         *     -experimental   report all warnings including experimental bug
1359         *                     patterns
1360         *     -low            report all warnings
1361         *     -medium         report only medium and high priority warnings
1362         *                     [default]
1363         *     -high           report only high priority warnings
1364         *
1365         * config:
1366         *   -exclude &lt;filter file>     include only bugs matching given filter
1367         *
1368         * internally:
1369         *   -outputFile &lt;filename>       Save output in named file
1370         *   -xml[:withMessages]          XML output (optionally with messages)
1371         *
1372         * auxclasspath:
1373         *   -auxclasspath &lt;classpath>    set aux classpath for analysis
1374         *
1375         * report: sourcepath
1376         *   -sourcepath &lt;source path>    set source path for analyzed classes
1377         * </pre>
1378         * The target assumes that all libs needed by findbugs are on the
1379         * classpath and the plugins are set via pluginlist element.
1380         *
1381         */
1382        public File execute (File reportDir, File srcDir, File clsDir)
1383        {
13840          mTask.log("Creating findbugs command line...");
13850          final CommandlineJava cmd
1386               = createCommandlineJava(mCommandline, mMaxHeap);
1387  
13880           if (mFindBugsDebug)
1389            {
13900               cmd.createVmArgument().setValue("-Dfindbugs.debug=true");
1391            }
1392  
13930          if (mPluginList != null)
1394           {
13950              cmd.createArgument().setValue("-pluginList");
13960              cmd.createArgument().setPath(mPluginList);
1397           }
1398  
13990          if (!StringUtil.isEmptyOrNull(mOmitVisitors))
1400           {
14010              cmd.createArgument().setValue("-omitVisitors");
14020              cmd.createArgument().setValue(mOmitVisitors);
1403           }
1404  
1405  
14060          final File outFile = new File(reportDir, "findbugs.xml");
14070          cmd.createArgument().setValue("-output");
14080          cmd.createArgument().setFile(outFile);
1409  
14100          cmd.createArgument().setValue("-sourcepath");
14110          cmd.createArgument().setFile(srcDir);
1412  
1413           // We always write findbugs reports in XML format
14140          cmd.createArgument().setValue("-xml:withMessages");
1415  
14160          if (mConfig != null)
1417           {
14180             cmd.createArgument().setValue("-exclude");
14190             cmd.createArgument().setFile(new File(mConfig));
1420           }
1421  
14220          if (mAuxPath != null)
1423           {
14240             cmd.createArgument().setValue("-auxclasspath");
14250             cmd.createArgument().setPath(mAuxPath);
1426           }
1427  
14280          cmd.createArgument().setValue("-" + mWarninglevel);
1429  
14300          cmd.createArgument().setValue("-effort:" + mEffort);
1431  
14320          cmd.createArgument().setFile(clsDir);
1433  
1434 (14)         // TODO: use PumpStreamHandler to suppress info messages from FindBugs
14350          forkToolProcess(mTask, cmd, new LogStreamHandler(mTask,
1436              Project.MSG_INFO, Project.MSG_WARN));
1437  
14380          return outFile;
1439        }
1440  
1441     }
1442  
1443  
1444     public static class NestedCheckstyleElement
1445           extends NestedToolElement
1446     {
1447        private String mConfig;
1448        private String mProperties;
1449  
1450        public NestedCheckstyleElement (JcReportAntTask task)
1451        {
14520          super(task);
14530          mCommandline.setClassname("com.puppycrawl.tools.checkstyle.Main");
14540       }
1455  
1456  
1457        public void setConfig (String config)
1458        {
14590          mConfig = config;
14600       }
1461  
1462  
1463        public void setProperties (String properties)
1464        {
14650          mProperties = properties;
14660       }
1467  
1468        public String toString ()
1469        {
14700           return "Checkstyle";
1471        }
1472  
1473        public File execute (File reportDir, File srcDir, File clsPath)
1474        {
14750          mTask.log("Creating checkstyle command line...");
14760          final CommandlineJava cmd
1477               = createCommandlineJava(mCommandline, mMaxHeap);
1478  
14790          cmd.createArgument().setValue("-o");
14800          final File outFile = new File(reportDir, "checkstyle.xml");
14810          cmd.createArgument().setFile(outFile);
1482  
14830          if (mConfig == null)
1484           {
14850(15)            throw new BuildException("The 'config' attribute is mandatory"
1486                    + " for the checkstyle task!", mTask.getLocation());
1487           }
14880          cmd.createArgument().setValue("-c");
14890          cmd.createArgument().setFile(new File(mConfig));
1490  
1491           // We always write checkstyle reports in XML format
14920          cmd.createArgument().setValue("-f");
14930          cmd.createArgument().setValue("xml");
1494  
14950          if (mProperties != null)
1496           {
14970             cmd.createArgument().setValue("-p");
14980             cmd.createArgument().setFile(new File(mProperties));
1499           }
1500  
15010          cmd.createArgument().setValue("-r");
15020          cmd.createArgument().setFile(srcDir);
1503  
15040          if (mTask.getEncoding() != null)
1505           {
15060              final Variable var = new Variable();
15070              var.setKey("file.encoding");
15080              var.setValue(mTask.getEncoding());
15090              cmd.getSystemProperties().addVariable(var);
1510           }
1511  
15120          forkToolProcess(mTask, cmd, new LogStreamHandler(mTask,
1513              Project.MSG_INFO, Project.MSG_WARN));
1514  
15150          return outFile;
1516        }
1517     }
1518  
1519  
1520     public static class NestedCoberturaElement
1521           extends NestedToolElement
1522     {
1523        private String mDatafile;
1524  
1525        public NestedCoberturaElement (JcReportAntTask task)
1526        {
15270          super(task);
15280          mCommandline.setClassname("net.sourceforge.cobertura.reporting.Main");
15290       }
1530  
1531  
1532        public void setDatafile (String datafile)
1533        {
15340          mDatafile = datafile;
15350       }
1536  
1537  
1538        /**
1539         * Executes the cobertura tool in a separate process.
1540         *
1541         * <pre>
1542         * [--datafile file]
1543         * [--destination dir]
1544         * source code directory [...]
1545         * </pre>
1546         */
1547        public File execute (File reportDir, File srcDir, File clsPath)
1548        {
15490          mTask.log("Creating cobertura command line...");
15500          final CommandlineJava cmd
1551               = createCommandlineJava(mCommandline, mMaxHeap);
1552  
15530          File dataFile = null;
15540          if (mDatafile == null)
1555           {
15560(16)            throw new BuildException("The datafile attribute is mandatory!",
1557                 mTask.getLocation());
1558           }
15590          dataFile = new File(mDatafile);
15600          if (!dataFile.exists())
1561           {
15620              throw new BuildException(
1563                   "The datafile '" + mDatafile + "' was not found!",
1564                   mTask.getLocation());
1565           }
1566  
15670          cmd.createArgument().setValue("--destination");
15680          final File outFile = new File(reportDir, "coverage.xml");
15690          cmd.createArgument().setFile(reportDir);
1570  
1571           // We always write checkstyle reports in XML format
15720          cmd.createArgument().setValue("--format");
15730          cmd.createArgument().setValue("xml");
1574  
15750          cmd.createArgument().setValue("--datafile");
15760          cmd.createArgument().setFile(dataFile);
1577  
15780          cmd.createArgument().setFile(srcDir);
1579  
15800          forkToolProcess(mTask, cmd, new LogStreamHandler(mTask,
1581              Project.MSG_INFO, Project.MSG_WARN));
1582  
15830          return outFile;
1584        }
1585     }
1586  
15870    public static class NestedEmmaElement
1588          extends NestedToolElement
1589      {
1590          private String mDatafile;
1591  
1592          public NestedEmmaElement (JcReportAntTask task)
1593          {
15940             super(task);
15950         }
1596  
1597          public void setDatafile (String datafile)
1598          {
15990             mDatafile = datafile;
16000         }
1601  
1602          /**
1603           * Nothing to be done for emma.
1604           */
1605          public File execute (File reportDir, File srcDir, File clsPath)
1606          {
16070             return new File(mDatafile);
1608          }
1609      }
1610  
1611     //
1612     // Generic input
1613     //
1614     /**
1615      * This method is called by Ant to create an instance of the
1616      * NestedLogfilesElement class when the 'logfiles' tag is read.
1617      *
1618      * @return the new instance of type NestedFiltersElement.
1619      */
1620     public NestedLogfilesElement createLogfiles ()
1621     {
16220       return mLogfilesElements;
1623     }
1624  
1625  
16260    public static class NestedLogfilesElement
1627     {
16280       private List<NestedLogfileElement> mGenericReaders
1629            = new ArrayList<NestedLogfileElement>();
1630  
1631  
1632        public void addLogfile (NestedLogfileElement nge)
1633        {
16340           mGenericReaders.add(nge);
16350       }
1636  
1637  
1638        public List<NestedLogfileElement> getLogfile ()
1639        {
16400          return mGenericReaders;
1641        }
1642     }
1643  
16440    public static class NestedLogfileElement
1645     {
1646         private String mType;
1647         private File mFile;
1648         
1649         public File getFile ()
1650         {
16510             return mFile;
1652         }
1653      
1654          public String getType ()
1655          {
16560             return mType;
1657          }
1658  
1659         public void setFile (File file)
1660         {
16610            mFile = file;
16620        }
1663      
1664         public void setType (String type)
1665         {
16660            mType = type;
16670        }
1668      }
1669     //
1670     // Filters section
1671     //
1672  
1673  
1674     /**
1675      * This method is called by Ant to create an instance of the
1676      * NestedFiltersElement class when the 'filters' tag is read.
1677      *
1678      * @return the new instance of type NestedFiltersElement.
1679      */
1680     public NestedFiltersElement createFilters ()
1681     {
16820       return mFilterElements;
1683     }
1684  
1685  
16860    public static class NestedFiltersElement
1687     {
16880       private List<NestedFilterElement> mFilters
1689            = new ArrayList<NestedFilterElement>();
1690  
1691  
1692        public void addFilter (NestedFilterElement nfe)
1693        {
16940          mFilters.add(nfe);
16950       }
1696  
1697  
1698        public List<NestedFilterElement> getFilters ()
1699        {
17000          return mFilters;
1701        }
1702     }
1703  
1704  
17050    public static class NestedFilterElement
1706     {
1707        private File mFile;
1708  
1709        public File getFile ()
1710        {
17110          return mFile;
1712        }
1713  
1714  
1715        public void setFile (String file)
1716        {
17170          mFile = new File(file);
17180       }
1719     }
1720  
1721  
1722     //
1723     // Helper methods
1724     //
1725  
1726  
1727     /**
1728      * Creates a copy of the global command line instance
1729      * and sets the maximum heap vm parameter.
1730      *
1731      * @param cmdline the global command line instance.
1732      * @param maxHeap the maximum heap size for the process.
1733      * @return a copy of the global command line instance.
1734      */
1735     private static CommandlineJava createCommandlineJava (
1736              CommandlineJava cmdline, int maxHeap)
1737     {
1738        final CommandlineJava cmd;
1739        try
1740        {
17410           cmd = (CommandlineJava) cmdline.clone();
1742        }
17430       catch (CloneNotSupportedException unexpected)
1744        {
17450(17)          throw new RuntimeException(
1746                    "Ups, CommandLineJava doesn't support the method clone()",
1747                    unexpected);
17480       }
1749  
17500       cmd.createVmArgument().setValue("-Xmx" + maxHeap + "m");
17510       return cmd;
1752     }
1753  
1754  
1755     /**
1756      * Forks the tool as external process.
1757      *
1758      * @param cmdline the command line.
1759      * @param psh the pump stream handler for redirecting the process streams.
1760      */
1761     private static void forkToolProcess (JcReportAntTask task,
1762              CommandlineJava cmdline, PumpStreamHandler psh)
1763     {
17640(18)      final Execute execute = new Execute(psh);
17650       execute.setCommandline(cmdline.getCommandline());
1766  
1767        try
1768        {
17690          task.logCommandLine(cmdline.getCommandline());
17700          final int exitCode = execute.execute();
17710          if (exitCode != 0)
1772           {
17730             task.log("Process returned with exit code: " + exitCode);
1774           }
1775        }
17760       catch (IOException e)
1777        {
17780          throw new BuildException(
1779               "Process fork failed. "
1780                   + ArraysUtil.toString(cmdline.getCommandline()), e,
1781              task.getLocation());
17820       }
17830    }
1784  
1785  
1786     /**
1787      * This is a special logging method to print the array of command
1788      * line parameters to the ant logging sub-system.
1789      *
1790      * @param cmdLine the command line parameter array.
1791      */
1792     private void logCommandLine (String[] cmdLine)
1793     {
17940       log("Command line: ");
17950       for (int i = 0; i < cmdLine.length; i++)
1796        {
17970          log(" " + cmdLine[i]);
1798        }
17990    }
1800  
1801  
1802     /**
1803      * Overwrites the method from the super class in order to
1804      * check for debug mode.
1805      *
1806      * @param msg the message to log.
1807      */
1808     public void log (String msg)
1809     {
18100       if (mDebug)
1811        {
18120          super.log(msg);
1813        }
18140    }
1815  }

Findings in this File

c (19) Got an exception - java.lang.RuntimeException: Unable to get class information for @throws tag 'BuildException'.
i (1) 78 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
w (2) 90 : 0 class org.jcoderz.phoenix.report.JcReportAntTask defines fields that are used only as locals
i (3) 168 : 0 Confusing to have methods org.jcoderz.phoenix.report.JcReportAntTask.setMaxHeap(String) and org.jcoderz.phoenix.report.JcReportAntTask$NestedToolElement.setMaxheap(String)
i (4) 174 : 0 Confusing to have methods org.jcoderz.phoenix.findbugs.jaxb.impl.SourceLineTypeImpl.getSourcepath() and org.jcoderz.phoenix.report.JcReportAntTask$NestedReportElement.getSourcePath()
i (5) 178 : 0 Confusing to have methods org.jcoderz.phoenix.findbugs.jaxb.impl.SourceLineTypeImpl.setSourcepath(String) and org.jcoderz.phoenix.report.JcReportAntTask$NestedReportElement.setSourcePath(String)
c (6) 195 : 4 Missing a Javadoc comment.
c (7) 201 : 4 Missing a Javadoc comment.
c (8) 207 : 4 Missing a Javadoc comment.
c (9) 213 : 4 Missing a Javadoc comment.
c (10) 219 : 4 Missing a Javadoc comment.
c (11) 224 : 4 Missing a Javadoc comment.
c (12) 262 : 4 Missing a Javadoc comment.
i (13) 337 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (14) 1434 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (15) 1485 : 0 method org.jcoderz.phoenix.report.JcReportAntTask$NestedCheckstyleElement.execute(File, File, File) throws exception with static message string
i (16) 1556 : 0 method org.jcoderz.phoenix.report.JcReportAntTask$NestedCoberturaElement.execute(File, File, File) throws exception with static message string
i (17) 1745 : 0 method org.jcoderz.phoenix.report.JcReportAntTask.createCommandlineJava(CommandlineJava, int) throws exception with static message string
w (18) 1764 : 0 method org.jcoderz.phoenix.report.JcReportAntTask.forkToolProcess(JcReportAntTask, CommandlineJava, PumpStreamHandler) needlessly defines parameter with concrete classes