KickJava   Java API By Example, From Geeks To Geeks.

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


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.metamata;
19
20 import java.io.File JavaDoc;
21 import java.io.FileWriter JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.PrintWriter JavaDoc;
24 import java.util.Vector JavaDoc;
25 import org.apache.tools.ant.BuildException;
26 import org.apache.tools.ant.Project;
27 import org.apache.tools.ant.taskdefs.Execute;
28 import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
29 import org.apache.tools.ant.taskdefs.LogStreamHandler;
30 import org.apache.tools.ant.types.Commandline;
31 import org.apache.tools.ant.types.Path;
32 import org.apache.tools.ant.util.JavaEnvUtils;
33
34 /**
35  * Simple Metamata MParse task.
36  * Based on the original written by
37  * <a HREF="mailto:thomas.haas@softwired-inc.com">Thomas Haas</a>.
38  *
39  * This version was written for Metamata 2.0 available at
40  * <a HREF="http://www.metamata.com">http://www.metamata.com</a>
41  *
42  * @todo make a subclass of AbstractMetaMataTask
43  */

44 public class MParse extends AbstractMetamataTask {
45
46     private File JavaDoc target = null;
47     private boolean verbose = false;
48     private boolean debugparser = false;
49     private boolean debugscanner = false;
50     private boolean cleanup = false;
51
52     /** The .jj file to process; required. */
53     public void setTarget(File JavaDoc target) {
54         this.target = target;
55     }
56
57     /** set verbose mode */
58     public void setVerbose(boolean flag) {
59         verbose = flag;
60     }
61
62     /** set scanner debug mode; optional, default false */
63     public void setDebugscanner(boolean flag) {
64         debugscanner = flag;
65     }
66
67     /** set parser debug mode; optional, default false */
68     public void setDebugparser(boolean flag) {
69         debugparser = flag;
70     }
71
72     /** Remove the intermediate Sun JavaCC file
73      * ; optional, default false.
74      */

75     public void setCleanup(boolean value) {
76         cleanup = value;
77     }
78
79     public MParse() {
80         cmdl.setVm(JavaEnvUtils.getJreExecutable("java"));
81         cmdl.setClassname("com.metamata.jj.MParse");
82     }
83
84
85     /** execute the command line */
86     public void execute() throws BuildException {
87         try {
88             setUp();
89             ExecuteStreamHandler handler = createStreamHandler();
90             _execute(handler);
91         } finally {
92             cleanUp();
93         }
94     }
95
96     /** return the default stream handler for this task */
97     protected ExecuteStreamHandler createStreamHandler() {
98         return new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_INFO);
99     }
100
101     /**
102      * check the options and build the command line
103      */

104     protected void setUp() throws BuildException {
105         checkOptions();
106
107         // set the classpath as the jar files
108
File JavaDoc[] jars = getMetamataLibs();
109         final Path classPath = cmdl.createClasspath(getProject());
110         for (int i = 0; i < jars.length; i++) {
111             classPath.createPathElement().setLocation(jars[i]);
112         }
113
114         // set the metamata.home property
115
final Commandline.Argument vmArgs = cmdl.createVmArgument();
116         vmArgs.setValue("-Dmetamata.home=" + metamataHome.getAbsolutePath());
117
118
119         // write all the options to a temp file and use it ro run the process
120
Vector JavaDoc opts = getOptions();
121         String JavaDoc[] options = new String JavaDoc[ opts.size() ];
122         opts.copyInto(options);
123
124         optionsFile = createTmpFile();
125         generateOptionsFile(optionsFile, options);
126         Commandline.Argument args = cmdl.createArgument();
127         args.setLine("-arguments " + optionsFile.getAbsolutePath());
128     }
129
130
131     /** execute the process with a specific handler */
132     protected void _execute(ExecuteStreamHandler handler) throws BuildException {
133         // target has been checked as a .jj, see if there is a matching
134
// java file and if it is needed to run to process the grammar
135
String JavaDoc pathname = target.getAbsolutePath();
136         int pos = pathname.length() - ".jj".length();
137         pathname = pathname.substring(0, pos) + ".java";
138         File JavaDoc javaFile = new File JavaDoc(pathname);
139         if (javaFile.exists() && target.lastModified() < javaFile.lastModified()) {
140             getProject().log("Target is already build - skipping (" + target + ")");
141             return;
142         }
143
144         final Execute process = new Execute(handler);
145         log(cmdl.describeCommand(), Project.MSG_VERBOSE);
146         process.setCommandline(cmdl.getCommandline());
147         try {
148             if (process.execute() != 0) {
149                 throw new BuildException("Metamata task failed.");
150             }
151         } catch (IOException JavaDoc e) {
152             throw new BuildException("Failed to launch Metamata task: ", e);
153         }
154     }
155
156     /** clean up all the mess that we did with temporary objects */
157     protected void cleanUp() {
158         if (optionsFile != null) {
159             optionsFile.delete();
160             optionsFile = null;
161         }
162         if (cleanup) {
163             String JavaDoc name = target.getName();
164             int pos = name.length() - ".jj".length();
165             name = "__jj" + name.substring(0, pos) + ".sunjj";
166             final File JavaDoc sunjj = new File JavaDoc(target.getParent(), name);
167             if (sunjj.exists()) {
168                 getProject().log("Removing stale file: " + sunjj.getName());
169                 sunjj.delete();
170             }
171         }
172     }
173
174     /**
175      * return an array of files containing the path to the needed
176      * libraries to run metamata. The file are not checked for
177      * existence. You should do this yourself if needed or simply let the
178      * forked process do it for you.
179      * @return array of jars/zips needed to run metamata.
180      */

181     protected File JavaDoc[] getMetamataLibs() {
182         Vector JavaDoc files = new Vector JavaDoc();
183         files.addElement(new File JavaDoc(metamataHome, "lib/metamata.jar"));
184         files.addElement(new File JavaDoc(metamataHome, "bin/lib/JavaCC.zip"));
185
186         File JavaDoc[] array = new File JavaDoc[ files.size() ];
187         files.copyInto(array);
188         return array;
189     }
190
191
192     /**
193      * validate options set and resolve files and paths
194      * @throws BuildException thrown if an option has an incorrect state.
195      */

196     protected void checkOptions() throws BuildException {
197         // check that the home is ok.
198
if (metamataHome == null || !metamataHome.exists()) {
199             throw new BuildException("'metamatahome' must point to Metamata home directory.");
200         }
201         metamataHome = getProject().resolveFile(metamataHome.getPath());
202
203         // check that the needed jar exists.
204
File JavaDoc[] jars = getMetamataLibs();
205         for (int i = 0; i < jars.length; i++) {
206             if (!jars[i].exists()) {
207                 throw new BuildException(jars[i]
208                     + " does not exist. Check your metamata installation.");
209             }
210         }
211
212         // check that the target is ok and resolve it.
213
if (target == null || !target.isFile()
214             || !target.getName().endsWith(".jj")) {
215             throw new BuildException("Invalid target: " + target);
216         }
217         target = getProject().resolveFile(target.getPath());
218     }
219
220     /**
221      * return all options of the command line as string elements
222      * @return an array of options corresponding to the setted options.
223      */

224     protected Vector JavaDoc getOptions() {
225         Vector JavaDoc options = new Vector JavaDoc();
226         if (verbose) {
227             options.addElement("-verbose");
228         }
229         if (debugscanner) {
230             options.addElement("-ds");
231         }
232         if (debugparser) {
233             options.addElement("-dp");
234         }
235         if (classPath != null) {
236             options.addElement("-classpath");
237             options.addElement(classPath.toString());
238         }
239         if (sourcePath != null) {
240             options.addElement("-sourcepath");
241             options.addElement(sourcePath.toString());
242         }
243         options.addElement(target.getAbsolutePath());
244         return options;
245     }
246
247     /**
248      * write all options to a file with one option / line
249      * @param tofile the file to write the options to.
250      * @param options the array of options element to write to the file.
251      * @throws BuildException thrown if there is a problem while writing
252      * to the file.
253      */

254     protected void generateOptionsFile(File JavaDoc tofile, String JavaDoc[] options) throws BuildException {
255         FileWriter JavaDoc fw = null;
256         try {
257             fw = new FileWriter JavaDoc(tofile);
258             PrintWriter JavaDoc pw = new PrintWriter JavaDoc(fw);
259             for (int i = 0; i < options.length; i++) {
260                 pw.println(options[i]);
261             }
262             pw.flush();
263         } catch (IOException JavaDoc e) {
264             throw new BuildException("Error while writing options file " + tofile, e);
265         } finally {
266             if (fw != null) {
267                 try {
268                     fw.close();
269                 } catch (IOException JavaDoc ignored) {
270                     // ignore
271
}
272             }
273         }
274     }
275 }
276
Popular Tags