KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > metamata > AbstractMetamataTask


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 package org.apache.tools.ant.taskdefs.optional.metamata;
18
19 import java.io.File JavaDoc;
20 import java.io.FileWriter JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.PrintWriter JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Hashtable JavaDoc;
25 import java.util.Vector JavaDoc;
26 import org.apache.tools.ant.BuildException;
27 import org.apache.tools.ant.DirectoryScanner;
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.ExecuteStreamHandler;
32 import org.apache.tools.ant.types.Commandline;
33 import org.apache.tools.ant.types.CommandlineJava;
34 import org.apache.tools.ant.types.FileSet;
35 import org.apache.tools.ant.types.Path;
36 import org.apache.tools.ant.util.FileUtils;
37 import org.apache.tools.ant.util.JavaEnvUtils;
38
39 /**
40  * Somewhat abstract framework to be used for other metama 2.0 tasks.
41  * This should include, audit, metrics, cover and mparse.
42  *
43  * For more information, visit the website at
44  * <a HREF="http://www.metamata.com">www.metamata.com</a>
45  *
46  */

47 public abstract class AbstractMetamataTask extends Task {
48
49     /**
50      * The user classpath to be provided. It matches the -classpath of the
51      * command line. The classpath must includes both the <tt>.class</tt> and the
52      * <tt>.java</tt> files for accurate audit.
53      */

54     protected Path classPath = null;
55
56     /** the path to the source file */
57     protected Path sourcePath = null;
58
59     /**
60      * Metamata home directory. It will be passed as a <tt>metamata.home</tt> property
61      * and should normally matches the environment property <tt>META_HOME</tt>
62      * set by the Metamata installer.
63      */

64     protected File JavaDoc metamataHome = null;
65
66     /** the command line used to run MAudit */
67     protected CommandlineJava cmdl = new CommandlineJava();
68
69     /** the set of files to be audited */
70     protected Vector JavaDoc fileSets = new Vector JavaDoc();
71
72     /** the options file where are stored the command line options */
73     protected File JavaDoc optionsFile = null;
74
75     // this is used to keep track of which files were included. It will
76
// be set when calling scanFileSets();
77
protected Hashtable JavaDoc includedFiles = null;
78
79     public AbstractMetamataTask() {
80     }
81
82     /** initialize the task with the classname of the task to run */
83     protected AbstractMetamataTask(String JavaDoc className) {
84         cmdl.setVm(JavaEnvUtils.getJreExecutable("java"));
85         cmdl.setClassname(className);
86     }
87
88     /**
89      * the metamata.home property to run all tasks.
90      * @ant.attribute ignore="true"
91      */

92     public void setHome(final File JavaDoc value) {
93         this.metamataHome = value;
94     }
95
96     /**
97      * The home directory containing the Metamata distribution; required
98      */

99     public void setMetamatahome(final File JavaDoc value) {
100         setHome(value);
101     }
102
103     /**
104      * Sets the class path (also source path unless one explicitly set).
105      * Overrides METAPATH/CLASSPATH environment variables.
106      */

107     public Path createClasspath() {
108         if (classPath == null) {
109             classPath = new Path(getProject());
110         }
111         return classPath;
112     }
113
114     /**
115      * Sets the source path.
116      * Overrides the SOURCEPATH environment variable.
117      */

118     public Path createSourcepath() {
119         if (sourcePath == null) {
120             sourcePath = new Path(getProject());
121         }
122         return sourcePath;
123     }
124
125     /**
126      * Additional optional parameters to pass to the JVM.
127      * You can avoid using the <code>&lt;jvmarg&gt;</code> by adding these empty
128      * entries to <code>metamata.properties</code> located at <code>${metamata.home}/bin</code>
129      *
130      * <pre>metamata.classpath=
131      * metamata.sourcepath=
132      * metamata.baseclasspath=
133      * </pre>
134      */

135     public Commandline.Argument createJvmarg() {
136         return cmdl.createVmArgument();
137     }
138
139     /**
140      * Set the maximum memory for the JVM; optional.
141      * -mx or -Xmx depending on VM version
142      */

143     public void setMaxmemory(String JavaDoc max) {
144         cmdl.setMaxmemory(max);
145     }
146
147
148     /**
149      * The java files or directory to audit.
150      * Whatever the filter is, only the files that end
151      * with .java will be included for processing.
152      * Note that the base directory used for the fileset
153      * MUST be the root of the source files otherwise package names
154      * deduced from the file path will be incorrect.
155      */

156     public void addFileSet(FileSet fs) {
157         fileSets.addElement(fs);
158     }
159
160     /** execute the command line */
161     public void execute() throws BuildException {
162         try {
163             setUp();
164             ExecuteStreamHandler handler = createStreamHandler();
165             execute0(handler);
166         } finally {
167             cleanUp();
168         }
169     }
170
171     /** check the options and build the command line */
172     protected void setUp() throws BuildException {
173         checkOptions();
174
175         // set the classpath as the jar file
176
File JavaDoc jar = getMetamataJar(metamataHome);
177         final Path classPath = cmdl.createClasspath(getProject());
178         classPath.createPathElement().setLocation(jar);
179
180         // set the metamata.home property
181
final Commandline.Argument vmArgs = cmdl.createVmArgument();
182         vmArgs.setValue("-Dmetamata.home=" + metamataHome.getAbsolutePath());
183
184         // retrieve all the files we want to scan
185
includedFiles = scanSources(new Hashtable JavaDoc());
186         //String[] entries = sourcePath.list();
187
//includedFiles = scanSources(new Hashtable(), entries);
188
log(includedFiles.size() + " files added for audit", Project.MSG_VERBOSE);
189
190         // write all the options to a temp file and use it ro run the process
191
Vector JavaDoc options = getOptions();
192         optionsFile = createTmpFile();
193         generateOptionsFile(optionsFile, options);
194         Commandline.Argument args = cmdl.createArgument();
195         args.setLine("-arguments " + optionsFile.getAbsolutePath());
196     }
197
198     /**
199      * create a stream handler that will be used to get the output since
200      * metamata tools do not report with convenient files such as XML.
201      */

202     protected abstract ExecuteStreamHandler createStreamHandler();
203
204
205     /** execute the process with a specific handler */
206     protected void execute0(ExecuteStreamHandler handler) throws BuildException {
207         final Execute process = new Execute(handler);
208         log(cmdl.describeCommand(), Project.MSG_VERBOSE);
209         process.setCommandline(cmdl.getCommandline());
210         try {
211             if (process.execute() != 0) {
212                 throw new BuildException("Metamata task failed.");
213             }
214         } catch (IOException JavaDoc e) {
215             throw new BuildException("Failed to launch Metamata task", e);
216         }
217     }
218
219     /** clean up all the mess that we did with temporary objects */
220     protected void cleanUp() {
221         if (optionsFile != null) {
222             optionsFile.delete();
223             optionsFile = null;
224         }
225     }
226
227     /** return the location of the jar file used to run */
228     protected final File JavaDoc getMetamataJar(File JavaDoc home) {
229         return new File JavaDoc(home, "lib/metamata.jar");
230     }
231
232     /** validate options set */
233     protected void checkOptions() throws BuildException {
234         // do some validation first
235
if (metamataHome == null || !metamataHome.exists()) {
236             throw new BuildException("'home' must point to Metamata home directory.");
237         }
238         File JavaDoc jar = getMetamataJar(metamataHome);
239         if (!jar.exists()) {
240             throw new BuildException(jar + " does not exist. Check your metamata installation.");
241         }
242     }
243
244     /** return all options of the command line as string elements */
245     protected abstract Vector JavaDoc getOptions();
246
247
248     protected void generateOptionsFile(File JavaDoc tofile, Vector JavaDoc options) throws BuildException {
249         FileWriter JavaDoc fw = null;
250         try {
251             fw = new FileWriter JavaDoc(tofile);
252             PrintWriter JavaDoc pw = new PrintWriter JavaDoc(fw);
253             final int size = options.size();
254             for (int i = 0; i < size; i++) {
255                 pw.println(options.elementAt(i));
256             }
257             pw.flush();
258         } catch (IOException JavaDoc e) {
259             throw new BuildException("Error while writing options file " + tofile, e);
260         } finally {
261             if (fw != null) {
262                 try {
263                     fw.close();
264                 } catch (IOException JavaDoc ignored) {
265                 }
266             }
267         }
268     }
269
270
271     protected Hashtable JavaDoc getFileMapping() {
272         return includedFiles;
273     }
274
275     /**
276      * convenient method for JDK 1.1. Will copy all elements from src to dest
277      */

278     protected static final void addAllVector(Vector JavaDoc dest, Enumeration JavaDoc files) {
279         while (files.hasMoreElements()) {
280             dest.addElement(files.nextElement());
281         }
282     }
283
284     protected final File JavaDoc createTmpFile() {
285         File JavaDoc tmpFile = FileUtils.newFileUtils()
286             .createTempFile("metamata", ".tmp", getProject().getBaseDir());
287         tmpFile.deleteOnExit();
288         return tmpFile;
289     }
290
291     /**
292      * @return the list of .java files (as their absolute path) that should
293      * be audited.
294      */

295
296     protected Hashtable JavaDoc scanSources(Hashtable JavaDoc map) {
297         Hashtable JavaDoc files = new Hashtable JavaDoc();
298         for (int i = 0; i < fileSets.size(); i++) {
299             FileSet fs = (FileSet) fileSets.elementAt(i);
300             DirectoryScanner ds = fs.getDirectoryScanner(getProject());
301             ds.scan();
302             String JavaDoc[] f = ds.getIncludedFiles();
303             log(i + ") Adding " + f.length + " files from directory "
304                 + ds.getBasedir(), Project.MSG_VERBOSE);
305             for (int j = 0; j < f.length; j++) {
306                 String JavaDoc pathname = f[j];
307                 if (pathname.endsWith(".java")) {
308                     File JavaDoc file = new File JavaDoc(ds.getBasedir(), pathname);
309 // file = project.resolveFile(file.getAbsolutePath());
310
String JavaDoc classname = pathname.substring(0, pathname.length() - ".java".length());
311                     classname = classname.replace(File.separatorChar, '.');
312                     files.put(file.getAbsolutePath(), classname); // it's a java file, add it.
313
}
314             }
315         }
316         return files;
317     }
318
319     protected Hashtable JavaDoc scanSources(final Hashtable JavaDoc mapping, final String JavaDoc[] entries) {
320         final Vector JavaDoc javaFiles = new Vector JavaDoc(512);
321         for (int i = 0; i < entries.length; i++) {
322             final File JavaDoc f = new File JavaDoc(entries[i]);
323             if (f.isDirectory()) {
324                 DirectoryScanner ds = new DirectoryScanner();
325                 ds.setBasedir(f);
326                 ds.setIncludes(new String JavaDoc[]{"**/*.java"});
327                 ds.scan();
328                 String JavaDoc[] included = ds.getIncludedFiles();
329                 for (int j = 0; j < included.length; j++) {
330                     javaFiles.addElement(new File JavaDoc(f, included[j]));
331                 }
332             } else if (entries[i].endsWith(".java")) {
333                 javaFiles.addElement(f);
334             }
335         }
336         // do the mapping paths/classname
337
final int count = javaFiles.size();
338         for (int i = 0; i < count; i++) {
339             File JavaDoc file = (File JavaDoc) javaFiles.elementAt(i);
340             String JavaDoc pathname = Path.translateFile(file.getAbsolutePath());
341             String JavaDoc classname = pathname.substring(0, pathname.length() - ".java".length());
342             classname = classname.replace(File.separatorChar, '.');
343             mapping.put(pathname, classname);
344         }
345         return mapping;
346     }
347
348 }
349
Popular Tags