1 18 19 package org.apache.tools.ant.taskdefs.optional; 20 21 import java.io.BufferedReader ; 22 import java.io.ByteArrayOutputStream ; 23 import java.io.File ; 24 import java.io.FileReader ; 25 import java.io.IOException ; 26 import org.apache.tools.ant.AntClassLoader; 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.LogOutputStream; 32 import org.apache.tools.ant.taskdefs.PumpStreamHandler; 33 import org.apache.tools.ant.taskdefs.condition.Os; 34 import org.apache.tools.ant.types.Commandline; 35 import org.apache.tools.ant.types.CommandlineJava; 36 import org.apache.tools.ant.types.Path; 37 import org.apache.tools.ant.util.JavaEnvUtils; 38 import org.apache.tools.ant.util.LoaderUtils; 39 import org.apache.tools.ant.util.TeeOutputStream; 40 import org.apache.tools.ant.util.FileUtils; 41 42 46 public class ANTLR extends Task { 47 48 private CommandlineJava commandline = new CommandlineJava(); 49 50 51 private File targetFile; 52 53 54 private File outputDirectory; 55 56 57 private File superGrammar; 58 59 60 private boolean html; 61 62 63 private boolean diagnostic; 64 65 66 private boolean trace; 67 68 69 private boolean traceParser; 70 71 72 private boolean traceLexer; 73 74 75 private boolean traceTreeWalker; 76 77 78 private File workingdir = null; 79 80 81 private ByteArrayOutputStream bos = new ByteArrayOutputStream (); 82 83 84 private boolean debug; 85 86 87 88 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 89 90 91 public ANTLR() { 92 commandline.setVm(JavaEnvUtils.getJreExecutable("java")); 93 commandline.setClassname("antlr.Tool"); 94 } 95 96 100 public void setTarget(File target) { 101 log("Setting target to: " + target.toString(), Project.MSG_VERBOSE); 102 this.targetFile = target; 103 } 104 105 109 public void setOutputdirectory(File outputDirectory) { 110 log("Setting output directory to: " + outputDirectory.toString(), Project.MSG_VERBOSE); 111 this.outputDirectory = outputDirectory; 112 } 113 114 120 public void setGlib(String superGrammar) { 121 String sg = null; 122 if (Os.isFamily("dos")) { 123 sg = superGrammar.replace('\\', '/'); 124 } else { 125 sg = superGrammar; 126 } 127 setGlib(FILE_UTILS.resolveFile(getProject().getBaseDir(), sg)); 128 } 129 134 public void setGlib(File superGrammar) { 135 this.superGrammar = superGrammar; 136 } 137 141 public void setDebug(boolean enable) { 142 this.debug = enable; 143 } 144 145 149 public void setHtml(boolean enable) { 150 html = enable; 151 } 152 153 157 public void setDiagnostic(boolean enable) { 158 diagnostic = enable; 159 } 160 161 165 public void setTrace(boolean enable) { 166 trace = enable; 167 } 168 169 173 public void setTraceParser(boolean enable) { 174 traceParser = enable; 175 } 176 177 181 public void setTraceLexer(boolean enable) { 182 traceLexer = enable; 183 } 184 185 189 public void setTraceTreeWalker(boolean enable) { 190 traceTreeWalker = enable; 191 } 192 193 201 public void setFork(boolean s) { 202 } 204 205 209 public void setDir(File d) { 210 this.workingdir = d; 211 } 212 213 218 public Path createClasspath() { 219 return commandline.createClasspath(getProject()).createPath(); 220 } 221 222 227 public Commandline.Argument createJvmarg() { 228 return commandline.createVmArgument(); 229 } 230 231 237 public void init() throws BuildException { 238 addClasspathEntry("/antlr/ANTLRGrammarParseBehavior.class"); 239 } 240 241 249 protected void addClasspathEntry(String resource) { 250 259 if (resource.startsWith("/")) { 260 resource = resource.substring(1); 261 } else { 262 resource = "org/apache/tools/ant/taskdefs/optional/" 263 + resource; 264 } 265 266 File f = LoaderUtils.getResourceSource(getClass().getClassLoader(), 267 resource); 268 if (f != null) { 269 log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG); 270 createClasspath().setLocation(f); 271 } else { 272 log("Couldn\'t find " + resource, Project.MSG_VERBOSE); 273 } 274 } 275 276 280 public void execute() throws BuildException { 281 validateAttributes(); 282 283 File generatedFile = getGeneratedFile(); 285 boolean targetIsOutOfDate = 286 targetFile.lastModified() > generatedFile.lastModified(); 287 boolean superGrammarIsOutOfDate = superGrammar != null 288 && (superGrammar.lastModified() > generatedFile.lastModified()); 289 if (targetIsOutOfDate || superGrammarIsOutOfDate) { 290 if (targetIsOutOfDate) { 291 log("Compiling " + targetFile + " as it is newer than " 292 + generatedFile, Project.MSG_VERBOSE); 293 } else if (superGrammarIsOutOfDate) { 294 log("Compiling " + targetFile + " as " + superGrammar 295 + " is newer than " + generatedFile, Project.MSG_VERBOSE); 296 } 297 populateAttributes(); 298 commandline.createArgument().setValue(targetFile.toString()); 299 300 log(commandline.describeCommand(), Project.MSG_VERBOSE); 301 int err = run(commandline.getCommandline()); 302 if (err != 0) { 303 throw new BuildException("ANTLR returned: " + err, getLocation()); 304 } else { 305 String output = bos.toString(); 306 if (output.indexOf("error:") > -1) { 307 throw new BuildException("ANTLR signaled an error: " 308 + output, getLocation()); 309 } 310 } 311 } else { 312 log("Skipped grammar file. Generated file " + generatedFile 313 + " is newer.", Project.MSG_VERBOSE); 314 } 315 } 316 317 321 private void populateAttributes() { 322 commandline.createArgument().setValue("-o"); 323 commandline.createArgument().setValue(outputDirectory.toString()); 324 if (superGrammar != null) { 325 commandline.createArgument().setValue("-glib"); 326 commandline.createArgument().setValue(superGrammar.toString()); 327 } 328 if (html) { 329 commandline.createArgument().setValue("-html"); 330 } 331 if (diagnostic) { 332 commandline.createArgument().setValue("-diagnostic"); 333 } 334 if (trace) { 335 commandline.createArgument().setValue("-trace"); 336 } 337 if (traceParser) { 338 commandline.createArgument().setValue("-traceParser"); 339 } 340 if (traceLexer) { 341 commandline.createArgument().setValue("-traceLexer"); 342 } 343 if (traceTreeWalker) { 344 if (is272()) { 345 commandline.createArgument().setValue("-traceTreeParser"); 346 } else { 347 commandline.createArgument().setValue("-traceTreeWalker"); 348 } 349 } 350 if (debug) { 351 commandline.createArgument().setValue("-debug"); 352 } 353 } 354 355 private void validateAttributes() throws BuildException { 356 if (targetFile == null || !targetFile.isFile()) { 357 throw new BuildException("Invalid target: " + targetFile); 358 } 359 360 if (outputDirectory == null) { 362 setOutputdirectory(new File (targetFile.getParent())); 363 } 364 if (!outputDirectory.isDirectory()) { 365 throw new BuildException("Invalid output directory: " + outputDirectory); 366 } 367 } 368 369 private File getGeneratedFile() throws BuildException { 370 String generatedFileName = null; 371 try { 372 BufferedReader in = new BufferedReader (new FileReader (targetFile)); 373 String line; 374 while ((line = in.readLine()) != null) { 375 int extendsIndex = line.indexOf(" extends "); 376 if (line.startsWith("class ") && extendsIndex > -1) { 377 generatedFileName = line.substring(6, extendsIndex).trim(); 378 break; 379 } 380 } 381 in.close(); 382 } catch (Exception e) { 383 throw new BuildException("Unable to determine generated class", e); 384 } 385 if (generatedFileName == null) { 386 throw new BuildException("Unable to determine generated class"); 387 } 388 return new File (outputDirectory, generatedFileName 389 + (html ? ".html" : ".java")); 390 } 391 392 393 private int run(String [] command) throws BuildException { 394 PumpStreamHandler psh = 395 new PumpStreamHandler(new LogOutputStream(this, Project.MSG_INFO), 396 new TeeOutputStream( 397 new LogOutputStream(this, 398 Project.MSG_WARN), 399 bos) 400 ); 401 Execute exe = new Execute(psh, null); 402 exe.setAntRun(getProject()); 403 if (workingdir != null) { 404 exe.setWorkingDirectory(workingdir); 405 } 406 exe.setCommandline(command); 407 try { 408 return exe.execute(); 409 } catch (IOException e) { 410 throw new BuildException(e, getLocation()); 411 } finally { 412 FileUtils.close(bos); 413 } 414 } 415 416 422 protected boolean is272() { 423 AntClassLoader l = null; 424 try { 425 l = getProject().createClassLoader(commandline.getClasspath()); 426 l.loadClass("antlr.Version"); 427 return true; 428 } catch (ClassNotFoundException e) { 429 return false; 430 } finally { 431 if (l != null) { 432 l.cleanup(); 433 } 434 } 435 } 436 } 437 | Popular Tags |