• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: emmajavaTask.java,v 1.1.1.1.2.2 2004/07/16 23:32:04 vlad_r Exp $
8  */
9 package com.vladium.emma;
10 
11 import java.io.File;
12 
13 import com.vladium.util.IProperties;
14 import com.vladium.util.Strings;
15 import com.vladium.emma.ant.*;
16 import com.vladium.emma.instr.FilterCfg;
17 import com.vladium.emma.instr.FilterCfg.filterElement;
18 import com.vladium.emma.report.ReportCfg;
19 import com.vladium.emma.report.IReportEnums.DepthAttribute;
20 import com.vladium.emma.report.IReportEnums.UnitsTypeAttribute;
21 import com.vladium.emma.report.ReportCfg.Element_HTML;
22 import com.vladium.emma.report.ReportCfg.Element_LCOV;
23 import com.vladium.emma.report.ReportCfg.Element_TXT;
24 import com.vladium.emma.report.ReportCfg.Element_XML;
25 
26 import org.apache.tools.ant.BuildException;
27 import org.apache.tools.ant.Project;
28 import org.apache.tools.ant.taskdefs.Java;
29 import org.apache.tools.ant.types.Commandline;
30 import org.apache.tools.ant.types.Path;
31 import org.apache.tools.ant.types.Reference;
32 
33 // ----------------------------------------------------------------------------
34 /**
35  * @author Vlad Roubtsov, (C) 2003
36  */
37 public
38 class emmajavaTask extends Java
39 {
40     // public: ................................................................
41 
42 
init()43     public void init () throws BuildException
44     {
45         super.init ();
46 
47         m_verbosityCfg = new VerbosityCfg ();
48         m_genericCfg = new GenericCfg (this);
49         m_filterCfg = new FilterCfg (this);
50         m_reportCfg = new ReportCfg (project, this);
51         setEnabled (true);
52     }
53 
54 
execute()55     public void execute () throws BuildException
56     {
57         log (IAppConstants.APP_VERBOSE_BUILD_ID, Project.MSG_VERBOSE);
58 
59         if (getClasspath () == null)
60             throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
61                 + ": this task requires 'classpath' attribute to be set", location).fillInStackTrace ();
62 
63 
64         if (isEnabled ())
65         {
66             // fork:
67             if (m_forkUserOverride && ! m_fork)
68                 log (getTaskName () + ": 'fork=\"false\"' attribute setting ignored (this task always forks)", Project.MSG_WARN);
69 
70             super.setFork (true); // always fork
71 
72             // add emma libs to the parent task's classpath [to support non-extdir deployment]:
73             final Path libClasspath = m_libClasspath;
74             if ((libClasspath != null) && (libClasspath.size () > 0))
75             {
76                 super.createClasspath ().append (libClasspath);
77             }
78 
79             // classname|jar (1/2):
80             super.setClassname ("emmarun");
81 
82             // <emmajava> extensions:
83             {
84                 // report types:
85                 {
86                     String reportTypes = Strings.toListForm (m_reportCfg.getReportTypes (), ',');
87                     if ((reportTypes == null) || (reportTypes.length () == 0)) reportTypes = "txt";
88 
89                     super.createArg ().setValue ("-r");
90                     super.createArg ().setValue (reportTypes);
91                 }
92 
93                 // full classpath scan flag:
94                 {
95                     if (m_scanCoveragePath)
96                     {
97                         super.createArg ().setValue ("-f");
98                     }
99                 }
100 
101                 // dump raw data flag and options:
102                 {
103                     if (m_dumpSessionData)
104                     {
105                         super.createArg ().setValue ("-raw");
106 
107                         if (m_outFile != null)
108                         {
109                             super.createArg ().setValue ("-out");
110                             super.createArg ().setValue (m_outFile.getAbsolutePath ());
111                         }
112 
113                         if (m_outFileMerge != null)
114                         {
115                             super.createArg ().setValue ("-merge");
116                             super.createArg ().setValue (m_outFileMerge.booleanValue () ? "y" : "n");
117                         }
118                     }
119                     else
120                     {
121                         if (m_outFile != null)
122                             log (getTaskName () + ": output file attribute ignored ('fullmetadata=\"true\"' not specified)", Project.MSG_WARN);
123 
124                         if (m_outFileMerge != null)
125                             log (getTaskName () + ": merge attribute setting ignored ('fullmetadata=\"true\"' not specified)", Project.MSG_WARN);
126                     }
127                 }
128 
129                 // instr filter:
130                 {
131                     final String [] specs = m_filterCfg.getFilterSpecs ();
132                     if ((specs != null) && (specs.length > 0))
133                     {
134                         super.createArg ().setValue ("-ix");
135                         super.createArg ().setValue (Strings.toListForm (specs, ','));
136                     }
137                 }
138 
139                 // sourcepath:
140                 {
141                     final Path srcpath = m_reportCfg.getSourcepath ();
142                     if (srcpath != null)
143                     {
144                         super.createArg ().setValue ("-sp");
145                         super.createArg ().setValue (Strings.toListForm (srcpath.list (), ','));
146                     }
147                 }
148 
149                 // all other generic settings:
150                 {
151                     final IProperties reportSettings = m_reportCfg.getReportSettings ();
152                     final IProperties genericSettings = m_genericCfg.getGenericSettings ();
153 
154                     // TODO: another options is to read this file in the forked JVM [use '-props' pass-through]
155                     // the best option depends on how ANT resolves relative file names
156                     final IProperties fileSettings = m_genericCfg.getFileSettings ();
157 
158                     // verbosity settings use dedicated attributes and hence are more specific
159                     // than anything generic:
160                     final IProperties verbositySettings = m_verbosityCfg.getSettings ();
161 
162                     // (1) file settings have lower priority than any explicitly named overrides
163                     // (2) named report settings override generic named settings
164                     // (3) verbosity settings use dedicated attributes (not overlapping with report
165                     // cfg) and hence are more specific than anything generic
166                     final IProperties settings = IProperties.Factory.combine (reportSettings,
167                                                  IProperties.Factory.combine (verbositySettings,
168                                                  IProperties.Factory.combine (genericSettings,
169                                                                               fileSettings)));
170 
171                     final String [] argForm = settings.toAppArgsForm ("-D");
172                     if (argForm.length > 0)
173                     {
174                         for (int a = 0; a < argForm.length; ++ a)
175                             super.createArg ().setValue (argForm [a]);
176                     }
177                 }
178             }
179 
180             // [assertion: getClasspath() is not null]
181 
182             // classpath:
183             super.createArg ().setValue ("-cp");
184             super.createArg ().setPath (getClasspath ());
185 
186             // classname|jar (2/2):
187             if (getClassname () != null)
188                 super.createArg ().setValue (getClassname ());
189             else if (getJar () != null)
190             {
191                 super.createArg ().setValue ("-jar");
192                 super.createArg ().setValue (getJar ().getAbsolutePath ());
193             }
194             else
195                 throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
196                     + "either 'jar' or 'classname' attribute must be set", location).fillInStackTrace ();
197 
198             // main class args:
199             if (m_appArgs != null)
200             {
201                 final String [] args = m_appArgs.getArguments ();
202                 for (int a = 0; a < args.length; ++ a)
203                 {
204                     super.createArg ().setValue (args [a]); // note: spaces etc are escaped correctly by ANT libs
205                 }
206             }
207         }
208         else
209         {
210             // fork:
211             super.setFork (m_fork);
212 
213             // [assertion: getClasspath() is not null]
214 
215             // classpath:
216             super.createClasspath ().append (getClasspath ()); // can't use setClasspath() for obvious reasons
217 
218             // classname|jar:
219             if (getClassname () != null)
220                 super.setClassname (getClassname ());
221             else if (getJar () != null)
222                 super.setJar (getJar ());
223             else
224                 throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
225                     + "either 'jar' or 'classname' attribute must be set", location).fillInStackTrace ();
226 
227             // main class args:
228             if (m_appArgs != null)
229             {
230                 final String [] args = m_appArgs.getArguments ();
231                 for (int a = 0; a < args.length; ++ a)
232                 {
233                     super.createArg ().setValue (args [a]); // note: spaces etc are escaped correctly by ANT libs
234                 }
235             }
236         }
237 
238         super.execute ();
239     }
240 
241 
242 
243     // <java> overrides [ANT 1.4]:
244 
setClassname(final String classname)245     public void setClassname (final String classname)
246     {
247         if (getJar () != null)
248             throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
249                 + "'jar' and 'classname' attributes cannot be set at the same time", location).fillInStackTrace ();
250 
251         m_classname = classname;
252     }
253 
setJar(final File file)254     public void setJar (final File file)
255     {
256         if (getClassname () != null)
257             throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
258                 + "'jar' and 'classname' attributes cannot be set at the same time", location).fillInStackTrace ();
259 
260         m_jar = file;
261     }
262 
263 
setClasspath(final Path path)264     public void setClasspath (final Path path)
265     {
266         if (m_classpath == null)
267             m_classpath = path;
268         else
269             m_classpath.append (path);
270     }
271 
setClasspathRef(final Reference ref)272     public void setClasspathRef (final Reference ref)
273     {
274         createClasspath ().setRefid (ref);
275     }
276 
createClasspath()277     public Path createClasspath ()
278     {
279         if (m_classpath == null)
280             m_classpath = new Path (project);
281 
282         return m_classpath.createPath ();
283     }
284 
285     /**
286      * This is already deprecated in ANT v1.4. However, it is still supported by
287      * the parent task so I do likewise.
288      */
setArgs(final String args)289     public void setArgs (final String args)
290     {
291         throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
292             + ": disallows using <java>'s deprecated 'args' attribute", location).fillInStackTrace ();
293     }
294 
295     /**
296      * Not overridable.
297      */
setFork(final boolean fork)298     public final void setFork (final boolean fork)
299     {
300         m_fork = fork;
301         m_forkUserOverride = true;
302     }
303 
304     /**
305      * Not overridable [due to limitations in ANT's Commandline].
306      */
createArg()307     public final Commandline.Argument createArg ()
308     {
309         if (m_appArgs == null)
310             m_appArgs = new Commandline ();
311 
312         return m_appArgs.createArgument ();
313     }
314 
315     // <java> overrides [ANT 1.5]:
316 
317     // [nothing at this point]
318 
319 
320     // <emmajava> extensions:
321 
setEnabled(final boolean enabled)322     public void setEnabled (final boolean enabled)
323     {
324         m_enabled = enabled;
325     }
326 
327     // .properties file attribute:
328 
setProperties(final File file)329     public final void setProperties (final File file)
330     {
331         m_genericCfg.setProperties (file);
332     }
333 
334     // generic property element:
335 
createProperty()336     public final PropertyElement createProperty ()
337     {
338         return m_genericCfg.createProperty ();
339     }
340 
341     // verbosity attribute:
342 
setVerbosity(final VerbosityCfg.VerbosityAttribute verbosity)343     public void setVerbosity (final VerbosityCfg.VerbosityAttribute verbosity)
344     {
345         m_verbosityCfg.setVerbosity (verbosity);
346     }
347 
348     // verbosity class filter attribute:
349 
setVerbosityfilter(final String filter)350     public void setVerbosityfilter (final String filter)
351     {
352         m_verbosityCfg.setVerbosityfilter (filter);
353     }
354 
355     // lib classpath attribute [to support non-extdir deployment]:
356 
setLibclasspath(final Path classpath)357     public final void setLibclasspath (final Path classpath)
358     {
359         if (m_libClasspath == null)
360             m_libClasspath = classpath;
361         else
362             m_libClasspath.append (classpath);
363     }
364 
setLibclasspathRef(final Reference ref)365     public final void setLibclasspathRef (final Reference ref)
366     {
367         if (m_libClasspath == null)
368             m_libClasspath = new Path (project);
369 
370         m_libClasspath.createPath ().setRefid (ref);
371     }
372 
373     // -f flag:
374 
setFullmetadata(final boolean full)375     public void setFullmetadata (final boolean full)
376     {
377         m_scanCoveragePath = full; // defaults to false TODO: maintain the default in a central location
378     }
379 
380     // -raw flag:
381 
setDumpsessiondata(final boolean dump)382     public void setDumpsessiondata (final boolean dump)
383     {
384         m_dumpSessionData = dump;
385     }
386 
387     // -out option:
388 
389     // sessiondatafile|outfile attribute:
390 
setSessiondatafile(final File file)391     public void setSessiondatafile (final File file)
392     {
393         if (m_outFile != null)
394             throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
395                 + ": session data file attribute already set", location).fillInStackTrace ();
396 
397         m_outFile = file;
398     }
399 
setOutfile(final File file)400     public void setOutfile (final File file)
401     {
402         if (m_outFile != null)
403             throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
404                 + ": session data file attribute already set", location).fillInStackTrace ();
405 
406         m_outFile = file;
407     }
408 
409 //    public void setTofile (final File file)
410 //    {
411 //        if (m_outFile != null)
412 //            throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
413 //                + ": session data file attribute already set", location).fillInStackTrace ();
414 //
415 //        m_outFile = file;
416 //    }
417 //
418 //    public void setFile (final File file)
419 //    {
420 //        if (m_outFile != null)
421 //            throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
422 //                + ": session data file attribute already set", location).fillInStackTrace ();
423 //
424 //        m_outFile = file;
425 //    }
426 
427 
428     // merge attribute:
429 
setMerge(final boolean merge)430     public void setMerge (final boolean merge)
431     {
432         m_outFileMerge = merge ? Boolean.TRUE : Boolean.FALSE;
433     }
434 
435     // instr filter attribute/element:
436 
setFilter(final String filter)437     public final void setFilter (final String filter)
438     {
439         m_filterCfg.setFilter (filter);
440     }
441 
createFilter()442     public final filterElement createFilter ()
443     {
444         return m_filterCfg.createFilter ();
445     }
446 
447 
448     // TODO: should what's below go inside <report></report> ?
449 
450     // sourcepath attribute/element:
451 
setSourcepath(final Path path)452     public final void setSourcepath (final Path path)
453     {
454         m_reportCfg.setSourcepath (path);
455     }
456 
setSourcepathRef(final Reference ref)457     public final void setSourcepathRef (final Reference ref)
458     {
459         m_reportCfg.setSourcepathRef (ref);
460     }
461 
createSourcepath()462     public final Path createSourcepath ()
463     {
464         return m_reportCfg.createSourcepath ();
465     }
466 
467 
468     // generator elements:
469 
createTxt()470     public final Element_TXT createTxt ()
471     {
472         return m_reportCfg.createTxt ();
473     }
474 
createLcov()475     public final Element_LCOV createLcov ()
476     {
477         return m_reportCfg.createLcov ();
478     }
479 
createHtml()480     public final Element_HTML createHtml ()
481     {
482         return m_reportCfg.createHtml ();
483     }
484 
createXml()485     public final Element_XML createXml ()
486     {
487         return m_reportCfg.createXml ();
488     }
489 
490 
491     // report properties [defaults for all report types]:
492 
setUnits(final UnitsTypeAttribute units)493     public final void setUnits (final UnitsTypeAttribute units)
494     {
495         m_reportCfg.setUnits (units);
496     }
497 
setDepth(final DepthAttribute depth)498     public final void setDepth (final DepthAttribute depth)
499     {
500         m_reportCfg.setDepth (depth);
501     }
502 
setColumns(final String columns)503     public final void setColumns (final String columns)
504     {
505         m_reportCfg.setColumns (columns);
506     }
507 
setSort(final String sort)508     public final void setSort (final String sort)
509     {
510         m_reportCfg.setSort (sort);
511     }
512 
setMetrics(final String metrics)513     public final void setMetrics (final String metrics)
514     {
515         m_reportCfg.setMetrics (metrics);
516     }
517 
518     // these are not supported anymore
519 
520 //    public final void setOutdir (final File dir)
521 //    {
522 //        m_reportCfg.setOutdir (dir);
523 //    }
524 //
525 //    public final void setDestdir (final File dir)
526 //    {
527 //        m_reportCfg.setDestdir (dir);
528 //    }
529 
530       // should be set at this level [and conflicts with raw data opts]:
531 
532 //    public void setOutfile (final String fileName)
533 //    {
534 //        m_reportCfg.setOutfile (fileName);
535 //    }
536 
setEncoding(final String encoding)537     public void setEncoding (final String encoding)
538     {
539         m_reportCfg.setEncoding (encoding);
540     }
541 
542     // protected: .............................................................
543 
544 
getClassname()545     protected String getClassname ()
546     {
547         return m_classname;
548     }
549 
getJar()550     protected File getJar ()
551     {
552         return m_jar;
553     }
554 
getClasspath()555     protected Path getClasspath ()
556     {
557         return m_classpath;
558     }
559 
560     // extended functionality:
561 
isEnabled()562     protected boolean isEnabled ()
563     {
564         return m_enabled;
565     }
566 
567     // package: ...............................................................
568 
569     // private: ...............................................................
570 
571     // <java> overrides:
572 
573     private Path m_classpath;
574     private String m_classname;
575     private File m_jar;
576     private Commandline m_appArgs;
577     private boolean m_fork, m_forkUserOverride;
578 
579     // <emmajava> extensions:
580 
581     private boolean m_enabled;
582     private Path m_libClasspath;
583     private /*final*/ VerbosityCfg m_verbosityCfg;
584     private /*final*/ GenericCfg m_genericCfg;
585     private /*final*/ FilterCfg m_filterCfg;
586     private /*final*/ ReportCfg m_reportCfg;
587     private boolean m_scanCoveragePath; // defaults to false
588     private boolean m_dumpSessionData; //defaults to false
589     private File m_outFile;
590     private Boolean m_outFileMerge;
591 
592 } // end of class
593 // ----------------------------------------------------------------------------
594