KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > sitraka > Coverage


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17
18 package org.apache.tools.ant.taskdefs.optional.sitraka;
19
20 import java.io.File JavaDoc;
21 import java.io.FileWriter JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.io.PrintWriter JavaDoc;
25 import java.io.StringWriter JavaDoc;
26 import java.util.Vector JavaDoc;
27 import org.apache.tools.ant.BuildException;
28 import org.apache.tools.ant.Project;
29 import org.apache.tools.ant.Task;
30 import org.apache.tools.ant.taskdefs.Execute;
31 import org.apache.tools.ant.taskdefs.LogStreamHandler;
32 import org.apache.tools.ant.types.Commandline;
33 import org.apache.tools.ant.types.CommandlineJava;
34 import org.apache.tools.ant.types.EnumeratedAttribute;
35 import org.apache.tools.ant.types.FileSet;
36 import org.apache.tools.ant.types.Path;
37 import org.apache.tools.ant.util.JavaEnvUtils;
38
39 /**
40  * Runs Sitraka JProbe Coverage.
41  *
42  * Options are pretty numerous, you'd better check the manual for a full
43  * descriptions of options. (not that simple since they differ from the online
44  * help, from the usage command line and from the examples...)
45  * <p>
46  * For additional information, visit <a HREF="http://www.sitraka.com">www.sitraka.com</a>
47  *
48  *
49  * @ant.task name="jpcoverage" category="metrics"
50  */

51 public class Coverage extends CovBase {
52
53     protected Commandline cmdl = new Commandline();
54
55     protected CommandlineJava cmdlJava = new CommandlineJava();
56
57     protected String JavaDoc function = "coverage";
58
59     protected String JavaDoc seedName;
60
61     protected File JavaDoc inputFile;
62
63     protected File JavaDoc javaExe;
64
65     protected String JavaDoc vm;
66
67     protected boolean applet = false;
68
69     /** this is a somewhat annoying thing, set it to never */
70     protected String JavaDoc exitPrompt = "never";
71
72     protected Filters filters = new Filters();
73
74     protected Triggers triggers;
75
76     protected String JavaDoc finalSnapshot = "coverage";
77
78     protected String JavaDoc recordFromStart = "coverage";
79
80     protected File JavaDoc snapshotDir;
81
82     protected File JavaDoc workingDir;
83
84     protected boolean trackNatives = false;
85
86     protected Socket socket;
87
88     protected int warnLevel = 0;
89
90     protected Vector JavaDoc filesets = new Vector JavaDoc();
91
92     //--------- setters used via reflection --
93

94     /** seed name for snapshot file. Can be null, default to snap */
95     public void setSeedname(String JavaDoc value) {
96         seedName = value;
97     }
98
99     /**
100      * @ant.attribute ignore="true"
101      */

102     public void setInputfile(File JavaDoc value) {
103         inputFile = value;
104     }
105
106     /**
107      * Path to the java executable.
108      */

109     public void setJavaexe(File JavaDoc value) {
110         javaExe = value;
111     }
112
113     public static class Javavm extends EnumeratedAttribute {
114         public String JavaDoc[] getValues() {
115             return new String JavaDoc[]{"java2", "jdk118", "jdk117"};
116         }
117     }
118
119     /**
120      * Indicates which virtual machine to run: "jdk117", "jdk118" or "java2".
121      * Can be null, default to "java2". */

122     public void setVm(Javavm value) {
123         vm = value.getValue();
124     }
125
126     /**
127      * If true, run an applet.
128      */

129     public void setApplet(boolean value) {
130         applet = value;
131     }
132
133     /**
134      * Toggles display of the console prompt: always, error, never
135      */

136     public void setExitprompt(String JavaDoc value) {
137         exitPrompt = value;
138     }
139
140     /**
141      * Defines class/method filters based on pattern matching.
142      * The syntax is filters is similar to a fileset.
143      */

144     public Filters createFilters() {
145         return filters;
146     }
147
148     /**
149      * Defines events to use for interacting with the
150      * collection of data performed during coverage.
151      *
152      * For example you may run a whole application but only decide
153      * to collect data once it reaches a certain method and once it
154      * exits another one.
155      */

156     public Triggers createTriggers() {
157         if (triggers == null) {
158             triggers = new Triggers();
159         }
160         return triggers;
161     }
162
163     /**
164      * Define a host and port to connect to if you want to do
165      * remote viewing.
166      */

167     public Socket createSocket() {
168         if (socket == null) {
169             socket = new Socket();
170         }
171         return socket;
172     }
173
174     public static class Finalsnapshot extends EnumeratedAttribute {
175         public String JavaDoc[] getValues() {
176             return new String JavaDoc[]{"coverage", "none", "all"};
177         }
178     }
179
180     /**
181      * Type of snapshot to send at program termination: none, coverage, all.
182      * Can be null, default to none
183      */

184     public void setFinalsnapshot(String JavaDoc value) {
185         finalSnapshot = value;
186     }
187
188     public static class Recordfromstart extends EnumeratedAttribute {
189         public String JavaDoc[] getValues() {
190             return new String JavaDoc[]{"coverage", "none", "all"};
191         }
192     }
193
194     /**
195      * "all", "coverage", or "none".
196      */

197     public void setRecordfromstart(Recordfromstart value) {
198         recordFromStart = value.getValue();
199     }
200
201     /**
202      * Set warning level (0-3, where 0 is the least amount of warnings).
203      */

204     public void setWarnlevel(Integer JavaDoc value) {
205         warnLevel = value.intValue();
206     }
207
208     /**
209      * The path to the directory where snapshot files are stored.
210      * Choose a directory that is reachable by both the remote
211      * and local computers, and enter the same path on the command-line
212      * and in the viewer.
213      */

214     public void setSnapshotdir(File JavaDoc value) {
215         snapshotDir = value;
216     }
217
218     /**
219      * The physical path to the working directory for the VM.
220      */

221     public void setWorkingdir(File JavaDoc value) {
222         workingDir = value;
223     }
224
225     /**
226      * If true, track native methods.
227      */

228     public void setTracknatives(boolean value) {
229         trackNatives = value;
230     }
231
232     //
233

234     /**
235      * Adds a JVM argument.
236      */

237     public Commandline.Argument createJvmarg() {
238         return cmdlJava.createVmArgument();
239     }
240
241     /**
242      * Adds a command argument.
243      */

244     public Commandline.Argument createArg() {
245         return cmdlJava.createArgument();
246     }
247
248     /**
249      * classpath to run the files.
250      */

251     public Path createClasspath() {
252         return cmdlJava.createClasspath(getProject()).createPath();
253     }
254
255     /**
256      * classname to run as standalone or runner for filesets.
257      */

258     public void setClassname(String JavaDoc value) {
259         cmdlJava.setClassname(value);
260     }
261
262     /**
263      * the classnames to execute.
264      */

265     public void addFileset(FileSet fs) {
266         filesets.addElement(fs);
267     }
268
269
270     //---------------- the tedious job begins here
271

272     public Coverage() {
273     }
274
275     /** execute the jplauncher by providing a parameter file */
276     public void execute() throws BuildException {
277         File JavaDoc paramfile = null;
278         // if an input file is used, all other options are ignored...
279
if (inputFile == null) {
280             checkOptions();
281             paramfile = createParamFile();
282         } else {
283             paramfile = inputFile;
284         }
285         try {
286             // we need to run Coverage from his directory due to dll/jar issues
287
cmdl.setExecutable(findExecutable("jplauncher"));
288             cmdl.createArgument().setValue("-jp_input=" + paramfile.getAbsolutePath());
289
290             // use the custom handler for stdin issues
291
LogStreamHandler handler = new CoverageStreamHandler(this);
292             Execute exec = new Execute(handler);
293             log(cmdl.describeCommand(), Project.MSG_VERBOSE);
294             exec.setCommandline(cmdl.getCommandline());
295             int exitValue = exec.execute();
296             if (Execute.isFailure(exitValue)) {
297                 throw new BuildException("JProbe Coverage failed (" + exitValue + ")");
298             }
299         } catch (IOException JavaDoc e) {
300             throw new BuildException("Failed to execute JProbe Coverage.", e);
301         } finally {
302             //@todo should be removed once switched to JDK1.2
303
if (inputFile == null && paramfile != null) {
304                 paramfile.delete();
305             }
306         }
307     }
308
309     /** wheck what is necessary to check, Coverage will do the job for us */
310     protected void checkOptions() throws BuildException {
311         // check coverage home
312
if (getHome() == null || !getHome().isDirectory()) {
313             throw new BuildException("Invalid home directory. Must point to JProbe home directory");
314         }
315         File JavaDoc jar = findCoverageJar();
316         if (!jar.exists()) {
317             throw new BuildException("Cannot find Coverage directory: " + getHome());
318         }
319
320         // make sure snapshot dir exists and is resolved
321
if (snapshotDir == null) {
322             snapshotDir = new File JavaDoc(".");
323         }
324         snapshotDir = getProject().resolveFile(snapshotDir.getPath());
325         if (!snapshotDir.isDirectory() || !snapshotDir.exists()) {
326             throw new BuildException("Snapshot directory does not exists :" + snapshotDir);
327         }
328         if (workingDir == null) {
329             workingDir = new File JavaDoc(".");
330         }
331         workingDir = getProject().resolveFile(workingDir.getPath());
332
333         // check for info, do your best to select the java executable.
334
// JProbe 3.0 fails if there is no javaexe option. So
335
if (javaExe == null && (vm == null || "java2".equals(vm))) {
336             if (!JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
337                 if (vm == null) {
338                     vm = "java2";
339                 }
340                 javaExe = new File JavaDoc(JavaEnvUtils.getJreExecutable("java"));
341             }
342         }
343     }
344
345     /**
346      * return the command line parameters. Parameters can either be passed
347      * to the command line and stored to a file (then use the -jp_input=&lt;filename&gt;)
348      * if they are too numerous.
349      */

350     protected String JavaDoc[] getParameters() {
351         Vector JavaDoc params = new Vector JavaDoc();
352         params.addElement("-jp_function=" + function);
353         if (vm != null) {
354             params.addElement("-jp_vm=" + vm);
355         }
356         if (javaExe != null) {
357             params.addElement("-jp_java_exe=" + getProject().resolveFile(javaExe.getPath()));
358         }
359         params.addElement("-jp_working_dir=" + workingDir.getPath());
360         params.addElement("-jp_snapshot_dir=" + snapshotDir.getPath());
361         params.addElement("-jp_record_from_start=" + recordFromStart);
362         params.addElement("-jp_warn=" + warnLevel);
363         if (seedName != null) {
364             params.addElement("-jp_output_file=" + seedName);
365         }
366         params.addElement("-jp_filter=" + filters.toString());
367         if (triggers != null) {
368             params.addElement("-jp_trigger=" + triggers.toString());
369         }
370         if (finalSnapshot != null) {
371             params.addElement("-jp_final_snapshot=" + finalSnapshot);
372         }
373         params.addElement("-jp_exit_prompt=" + exitPrompt);
374         //params.addElement("-jp_append=" + append);
375
params.addElement("-jp_track_natives=" + trackNatives);
376         //.... now the jvm
377
// arguments
378
String JavaDoc[] vmargs = cmdlJava.getVmCommand().getArguments();
379         for (int i = 0; i < vmargs.length; i++) {
380             params.addElement(vmargs[i]);
381         }
382         // classpath
383
Path classpath = cmdlJava.getClasspath();
384         if (classpath != null && classpath.size() > 0) {
385             params.addElement("-classpath " + classpath.toString());
386         }
387         // classname (runner or standalone)
388
if (cmdlJava.getClassname() != null) {
389             params.addElement(cmdlJava.getClassname());
390         }
391         // arguments for classname
392
String JavaDoc[] args = cmdlJava.getJavaCommand().getArguments();
393         for (int i = 0; i < args.length; i++) {
394             params.addElement(args[i]);
395         }
396
397         String JavaDoc[] array = new String JavaDoc[params.size()];
398         params.copyInto(array);
399         return array;
400     }
401
402
403     /**
404      * create the parameter file from the given options. The file is
405      * created with a random name in the current directory.
406      * @return the file object where are written the configuration to run
407      * JProbe Coverage
408      * @throws BuildException thrown if something bad happens while writing
409      * the arguments to the file.
410      */

411     protected File JavaDoc createParamFile() throws BuildException {
412         //@todo change this when switching to JDK 1.2 and use File.createTmpFile()
413
File JavaDoc file = createTempFile("jpcov");
414         file.deleteOnExit();
415         log("Creating parameter file: " + file, Project.MSG_VERBOSE);
416
417         // options need to be one per line in the parameter file
418
// so write them all in a single string
419
StringWriter JavaDoc sw = new StringWriter JavaDoc();
420         PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
421         String JavaDoc[] params = getParameters();
422         for (int i = 0; i < params.length; i++) {
423             pw.println(params[i]);
424         }
425         pw.flush();
426         log("JProbe Coverage parameters:\n" + sw.toString(), Project.MSG_VERBOSE);
427
428         // now write them to the file
429
FileWriter JavaDoc fw = null;
430         try {
431             fw = new FileWriter JavaDoc(file);
432             fw.write(sw.toString());
433             fw.flush();
434         } catch (IOException JavaDoc e) {
435             throw new BuildException("Could not write parameter file " + file, e);
436         } finally {
437             if (fw != null) {
438                 try {
439                     fw.close();
440                 } catch (IOException JavaDoc ignored) {
441                 }
442             }
443         }
444         return file;
445     }
446
447     /** specific pumper to avoid those nasty stdin issues */
448     static class CoverageStreamHandler extends LogStreamHandler {
449         CoverageStreamHandler(Task task) {
450             super(task, Project.MSG_INFO, Project.MSG_WARN);
451         }
452
453         /**
454          * there are some issues concerning all JProbe executable
455          * In our case a 'Press ENTER to close this window..." will
456          * be displayed in the current window waiting for enter.
457          * So I'm closing the stream right away to avoid problems.
458          */

459         public void setProcessInputStream(OutputStream JavaDoc os) {
460             try {
461                 os.close();
462             } catch (IOException JavaDoc ignored) {
463             }
464         }
465     }
466
467 }
468
Popular Tags