source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 16.9 KB
Line 
1/*
2 * Copyright 2000-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
18package org.apache.tools.ant.taskdefs.optional.javacc;
19
20import java.io.File;
21import java.io.IOException;
22import java.util.Enumeration;
23import java.util.Hashtable;
24import java.util.zip.ZipFile;
25import org.apache.tools.ant.BuildException;
26import org.apache.tools.ant.Project;
27import org.apache.tools.ant.Task;
28import org.apache.tools.ant.taskdefs.Execute;
29import org.apache.tools.ant.types.Commandline;
30import org.apache.tools.ant.types.CommandlineJava;
31import org.apache.tools.ant.types.Path;
32import org.apache.tools.ant.util.JavaEnvUtils;
33
34/**
35 * JavaCC compiler compiler task.
36 *
37 */
38public class JavaCC extends Task {
39
40 // keys to optional attributes
41 private static final String LOOKAHEAD = "LOOKAHEAD";
42 private static final String CHOICE_AMBIGUITY_CHECK = "CHOICE_AMBIGUITY_CHECK";
43 private static final String OTHER_AMBIGUITY_CHECK = "OTHER_AMBIGUITY_CHECK";
44
45 private static final String STATIC = "STATIC";
46 private static final String DEBUG_PARSER = "DEBUG_PARSER";
47 private static final String DEBUG_LOOKAHEAD = "DEBUG_LOOKAHEAD";
48 private static final String DEBUG_TOKEN_MANAGER = "DEBUG_TOKEN_MANAGER";
49 private static final String OPTIMIZE_TOKEN_MANAGER = "OPTIMIZE_TOKEN_MANAGER";
50 private static final String ERROR_REPORTING = "ERROR_REPORTING";
51 private static final String JAVA_UNICODE_ESCAPE = "JAVA_UNICODE_ESCAPE";
52 private static final String UNICODE_INPUT = "UNICODE_INPUT";
53 private static final String IGNORE_CASE = "IGNORE_CASE";
54 private static final String COMMON_TOKEN_ACTION = "COMMON_TOKEN_ACTION";
55 private static final String USER_TOKEN_MANAGER = "USER_TOKEN_MANAGER";
56 private static final String USER_CHAR_STREAM = "USER_CHAR_STREAM";
57 private static final String BUILD_PARSER = "BUILD_PARSER";
58 private static final String BUILD_TOKEN_MANAGER = "BUILD_TOKEN_MANAGER";
59 private static final String SANITY_CHECK = "SANITY_CHECK";
60 private static final String FORCE_LA_CHECK = "FORCE_LA_CHECK";
61 private static final String CACHE_TOKENS = "CACHE_TOKENS";
62 private static final String KEEP_LINE_COLUMN = "KEEP_LINE_COLUMN";
63
64 private final Hashtable optionalAttrs = new Hashtable();
65
66 // required attributes
67 private File outputDirectory = null;
68 private File target = null;
69 private File javaccHome = null;
70
71 private CommandlineJava cmdl = new CommandlineJava();
72
73 protected static final int TASKDEF_TYPE_JAVACC = 1;
74 protected static final int TASKDEF_TYPE_JJTREE = 2;
75 protected static final int TASKDEF_TYPE_JJDOC = 3;
76
77 protected static final String[] ARCHIVE_LOCATIONS =
78 new String[] {
79 "JavaCC.zip",
80 "bin/lib/JavaCC.zip",
81 "bin/lib/javacc.jar",
82 "javacc.jar", // used by jpackage for JavaCC 3.x
83 };
84
85 protected static final int[] ARCHIVE_LOCATIONS_VS_MAJOR_VERSION =
86 new int[] {
87 1,
88 2,
89 3,
90 3,
91 };
92
93 protected static final String COM_PACKAGE = "COM.sun.labs.";
94 protected static final String COM_JAVACC_CLASS = "javacc.Main";
95 protected static final String COM_JJTREE_CLASS = "jjtree.Main";
96 protected static final String COM_JJDOC_CLASS = "jjdoc.JJDocMain";
97
98 protected static final String ORG_PACKAGE_3_0 = "org.netbeans.javacc.";
99 protected static final String ORG_PACKAGE_3_1 = "org.javacc.";
100 protected static final String ORG_JAVACC_CLASS = "parser.Main";
101 protected static final String ORG_JJTREE_CLASS = COM_JJTREE_CLASS;
102 protected static final String ORG_JJDOC_CLASS = COM_JJDOC_CLASS;
103
104 /**
105 * Sets the LOOKAHEAD grammar option.
106 */
107 public void setLookahead(int lookahead) {
108 optionalAttrs.put(LOOKAHEAD, new Integer(lookahead));
109 }
110
111 /**
112 * Sets the CHOICE_AMBIGUITY_CHECK grammar option.
113 */
114 public void setChoiceambiguitycheck(int choiceAmbiguityCheck) {
115 optionalAttrs.put(CHOICE_AMBIGUITY_CHECK, new Integer(choiceAmbiguityCheck));
116 }
117
118 /**
119 * Sets the OTHER_AMBIGUITY_CHECK grammar option.
120 */
121 public void setOtherambiguityCheck(int otherAmbiguityCheck) {
122 optionalAttrs.put(OTHER_AMBIGUITY_CHECK, new Integer(otherAmbiguityCheck));
123 }
124
125 /**
126 * Sets the STATIC grammar option.
127 */
128 public void setStatic(boolean staticParser) {
129 optionalAttrs.put(STATIC, new Boolean(staticParser));
130 }
131
132 /**
133 * Sets the DEBUG_PARSER grammar option.
134 */
135 public void setDebugparser(boolean debugParser) {
136 optionalAttrs.put(DEBUG_PARSER, new Boolean(debugParser));
137 }
138
139 /**
140 * Sets the DEBUG_LOOKAHEAD grammar option.
141 */
142 public void setDebuglookahead(boolean debugLookahead) {
143 optionalAttrs.put(DEBUG_LOOKAHEAD, new Boolean(debugLookahead));
144 }
145
146 /**
147 * Sets the DEBUG_TOKEN_MANAGER grammar option.
148 */
149 public void setDebugtokenmanager(boolean debugTokenManager) {
150 optionalAttrs.put(DEBUG_TOKEN_MANAGER, new Boolean(debugTokenManager));
151 }
152
153 /**
154 * Sets the OPTIMIZE_TOKEN_MANAGER grammar option.
155 */
156 public void setOptimizetokenmanager(boolean optimizeTokenManager) {
157 optionalAttrs.put(OPTIMIZE_TOKEN_MANAGER, new Boolean(optimizeTokenManager));
158 }
159
160 /**
161 * Sets the ERROR_REPORTING grammar option.
162 */
163 public void setErrorreporting(boolean errorReporting) {
164 optionalAttrs.put(ERROR_REPORTING, new Boolean(errorReporting));
165 }
166
167 /**
168 * Sets the JAVA_UNICODE_ESCAPE grammar option.
169 */
170 public void setJavaunicodeescape(boolean javaUnicodeEscape) {
171 optionalAttrs.put(JAVA_UNICODE_ESCAPE, new Boolean(javaUnicodeEscape));
172 }
173
174 /**
175 * Sets the UNICODE_INPUT grammar option.
176 */
177 public void setUnicodeinput(boolean unicodeInput) {
178 optionalAttrs.put(UNICODE_INPUT, new Boolean(unicodeInput));
179 }
180
181 /**
182 * Sets the IGNORE_CASE grammar option.
183 */
184 public void setIgnorecase(boolean ignoreCase) {
185 optionalAttrs.put(IGNORE_CASE, new Boolean(ignoreCase));
186 }
187
188 /**
189 * Sets the COMMON_TOKEN_ACTION grammar option.
190 */
191 public void setCommontokenaction(boolean commonTokenAction) {
192 optionalAttrs.put(COMMON_TOKEN_ACTION, new Boolean(commonTokenAction));
193 }
194
195 /**
196 * Sets the USER_TOKEN_MANAGER grammar option.
197 */
198 public void setUsertokenmanager(boolean userTokenManager) {
199 optionalAttrs.put(USER_TOKEN_MANAGER, new Boolean(userTokenManager));
200 }
201
202 /**
203 * Sets the USER_CHAR_STREAM grammar option.
204 */
205 public void setUsercharstream(boolean userCharStream) {
206 optionalAttrs.put(USER_CHAR_STREAM, new Boolean(userCharStream));
207 }
208
209 /**
210 * Sets the BUILD_PARSER grammar option.
211 */
212 public void setBuildparser(boolean buildParser) {
213 optionalAttrs.put(BUILD_PARSER, new Boolean(buildParser));
214 }
215
216 /**
217 * Sets the BUILD_TOKEN_MANAGER grammar option.
218 */
219 public void setBuildtokenmanager(boolean buildTokenManager) {
220 optionalAttrs.put(BUILD_TOKEN_MANAGER, new Boolean(buildTokenManager));
221 }
222
223 /**
224 * Sets the SANITY_CHECK grammar option.
225 */
226 public void setSanitycheck(boolean sanityCheck) {
227 optionalAttrs.put(SANITY_CHECK, new Boolean(sanityCheck));
228 }
229
230 /**
231 * Sets the FORCE_LA_CHECK grammar option.
232 */
233 public void setForcelacheck(boolean forceLACheck) {
234 optionalAttrs.put(FORCE_LA_CHECK, new Boolean(forceLACheck));
235 }
236
237 /**
238 * Sets the CACHE_TOKENS grammar option.
239 */
240 public void setCachetokens(boolean cacheTokens) {
241 optionalAttrs.put(CACHE_TOKENS, new Boolean(cacheTokens));
242 }
243
244 /**
245 * Sets the KEEP_LINE_COLUMN grammar option.
246 */
247 public void setKeeplinecolumn(boolean keepLineColumn) {
248 optionalAttrs.put(KEEP_LINE_COLUMN, new Boolean(keepLineColumn));
249 }
250
251 /**
252 * The directory to write the generated files to.
253 * If not set, the files are written to the directory
254 * containing the grammar file.
255 */
256 public void setOutputdirectory(File outputDirectory) {
257 this.outputDirectory = outputDirectory;
258 }
259
260 /**
261 * The grammar file to process.
262 */
263 public void setTarget(File target) {
264 this.target = target;
265 }
266
267 /**
268 * The directory containing the JavaCC distribution.
269 */
270 public void setJavacchome(File javaccHome) {
271 this.javaccHome = javaccHome;
272 }
273
274 public JavaCC() {
275 cmdl.setVm(JavaEnvUtils.getJreExecutable("java"));
276 }
277
278 public void execute() throws BuildException {
279
280 // load command line with optional attributes
281 Enumeration iter = optionalAttrs.keys();
282 while (iter.hasMoreElements()) {
283 String name = (String) iter.nextElement();
284 Object value = optionalAttrs.get(name);
285 cmdl.createArgument().setValue("-" + name + ":" + value.toString());
286 }
287
288 // check the target is a file
289 if (target == null || !target.isFile()) {
290 throw new BuildException("Invalid target: " + target);
291 }
292
293 // use the directory containing the target as the output directory
294 if (outputDirectory == null) {
295 outputDirectory = new File(target.getParent());
296 } else if (!outputDirectory.isDirectory()) {
297 throw new BuildException("Outputdir not a directory.");
298 }
299 cmdl.createArgument().setValue("-OUTPUT_DIRECTORY:"
300 + outputDirectory.getAbsolutePath());
301
302 // determine if the generated java file is up-to-date
303 final File javaFile = getOutputJavaFile(outputDirectory, target);
304 if (javaFile.exists() && target.lastModified() < javaFile.lastModified()) {
305 log("Target is already built - skipping (" + target + ")", Project.MSG_VERBOSE);
306 return;
307 }
308 cmdl.createArgument().setValue(target.getAbsolutePath());
309
310 cmdl.setClassname(JavaCC.getMainClass(javaccHome,
311 JavaCC.TASKDEF_TYPE_JAVACC));
312
313 final Path classpath = cmdl.createClasspath(getProject());
314 final File javaccJar = JavaCC.getArchiveFile(javaccHome);
315 classpath.createPathElement().setPath(javaccJar.getAbsolutePath());
316 classpath.addJavaRuntime();
317
318 final Commandline.Argument arg = cmdl.createVmArgument();
319 arg.setValue("-mx140M");
320 arg.setValue("-Dinstall.root=" + javaccHome.getAbsolutePath());
321
322 Execute.runCommand(this, cmdl.getCommandline());
323 }
324
325 /**
326 * Helper method to retrieve the path used to store the JavaCC.zip
327 * or javacc.jar which is different from versions.
328 *
329 * @param home the javacc home path directory.
330 * @throws BuildException thrown if the home directory is invalid
331 * or if the archive could not be found despite attempts to do so.
332 * @return the file object pointing to the JavaCC archive.
333 */
334 protected static File getArchiveFile(File home) throws BuildException {
335 return new File(home,
336 ARCHIVE_LOCATIONS[getArchiveLocationIndex(home)]);
337 }
338
339 /**
340 * Helper method to retrieve main class which is different from versions.
341 * @param home the javacc home path directory.
342 * @param type the taskdef.
343 * @throws BuildException thrown if the home directory is invalid
344 * or if the archive could not be found despite attempts to do so.
345 * @return the main class for the taskdef.
346 */
347 protected static String getMainClass(File home, int type)
348 throws BuildException {
349
350 int majorVersion = getMajorVersionNumber(home);
351 String packagePrefix = null;
352 String mainClass = null;
353
354 switch (majorVersion) {
355 case 1:
356 case 2:
357 packagePrefix = COM_PACKAGE;
358
359 switch (type) {
360 case TASKDEF_TYPE_JAVACC:
361 mainClass = COM_JAVACC_CLASS;
362
363 break;
364
365 case TASKDEF_TYPE_JJTREE:
366 mainClass = COM_JJTREE_CLASS;
367
368 break;
369
370 case TASKDEF_TYPE_JJDOC:
371 mainClass = COM_JJDOC_CLASS;
372
373 break;
374 }
375
376 break;
377
378 case 3:
379 /*
380 * This is where the fun starts, JavaCC 3.0 uses
381 * org.netbeans.javacc, 3.1 uses org.javacc - I wonder
382 * which version is going to use net.java.javacc.
383 *
384 * Look into to the archive to pick up the best
385 * package.
386 */
387 ZipFile zf = null;
388 try {
389 zf = new ZipFile(getArchiveFile(home));
390 if (zf.getEntry(ORG_PACKAGE_3_0.replace('.', '/')) != null) {
391 packagePrefix = ORG_PACKAGE_3_0;
392 } else {
393 packagePrefix = ORG_PACKAGE_3_1;
394 }
395 } catch (IOException e) {
396 throw new BuildException("Error reading javacc.jar", e);
397 } finally {
398 if (zf != null) {
399 try {
400 zf.close();
401 } catch (IOException e) {
402 throw new BuildException(e);
403 }
404 }
405 }
406
407 switch (type) {
408 case TASKDEF_TYPE_JAVACC:
409 mainClass = ORG_JAVACC_CLASS;
410
411 break;
412
413 case TASKDEF_TYPE_JJTREE:
414 mainClass = ORG_JJTREE_CLASS;
415
416 break;
417
418 case TASKDEF_TYPE_JJDOC:
419 mainClass = ORG_JJDOC_CLASS;
420
421 break;
422 }
423
424 break;
425 }
426
427 return packagePrefix + mainClass;
428 }
429
430 /**
431 * Helper method to determine the archive location index.
432 *
433 * @param home the javacc home path directory.
434 * @throws BuildException thrown if the home directory is invalid
435 * or if the archive could not be found despite attempts to do so.
436 * @return the archive location index
437 */
438 private static int getArchiveLocationIndex(File home)
439 throws BuildException {
440
441 if (home == null || !home.isDirectory()) {
442 throw new BuildException("JavaCC home must be a valid directory.");
443 }
444
445 for (int i = 0; i < ARCHIVE_LOCATIONS.length; i++) {
446 File f = new File(home, ARCHIVE_LOCATIONS[i]);
447
448 if (f.exists()) {
449 return i;
450 }
451 }
452
453 throw new BuildException("Could not find a path to JavaCC.zip "
454 + "or javacc.jar from '" + home + "'.");
455 }
456
457 /**
458 * Helper method to determine the major version number of JavaCC.
459 *
460 * @param home the javacc home path directory.
461 * @throws BuildException thrown if the home directory is invalid
462 * or if the archive could not be found despite attempts to do so.
463 * @return a the major version number
464 */
465 protected static int getMajorVersionNumber(File home)
466 throws BuildException {
467
468 return
469 ARCHIVE_LOCATIONS_VS_MAJOR_VERSION[getArchiveLocationIndex(home)];
470 }
471
472 /**
473 * Determines the output Java file to be generated by the given grammar
474 * file.
475 *
476 */
477 private File getOutputJavaFile(File outputdir, File srcfile) {
478 String path = srcfile.getPath();
479
480 // Extract file's base-name
481 int startBasename = path.lastIndexOf(File.separator);
482 if (startBasename != -1) {
483 path = path.substring(startBasename + 1);
484 }
485
486 // Replace the file's extension with '.java'
487 int startExtn = path.lastIndexOf('.');
488 if (startExtn != -1) {
489 path = path.substring(0, startExtn) + ".java";
490 } else {
491 path += ".java";
492 }
493
494 // Change the directory
495 if (outputdir != null) {
496 path = outputdir + File.separator + path;
497 }
498
499 return new File(path);
500 }
501}
Note: See TracBrowser for help on using the repository browser.