1 18 19 package org.apache.tools.ant.taskdefs.optional.javacc; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.util.Enumeration ; 24 import java.util.Hashtable ; 25 26 import org.apache.tools.ant.BuildException; 27 import org.apache.tools.ant.Project; 28 import org.apache.tools.ant.Task; 29 import org.apache.tools.ant.taskdefs.Execute; 30 import org.apache.tools.ant.taskdefs.LogStreamHandler; 31 import org.apache.tools.ant.types.Commandline; 32 import org.apache.tools.ant.types.CommandlineJava; 33 import org.apache.tools.ant.types.Path; 34 import org.apache.tools.ant.util.JavaEnvUtils; 35 36 40 public class JJTree extends Task { 41 42 private static final String OUTPUT_FILE = "OUTPUT_FILE"; 44 private static final String BUILD_NODE_FILES = "BUILD_NODE_FILES"; 45 private static final String MULTI = "MULTI"; 46 private static final String NODE_DEFAULT_VOID = "NODE_DEFAULT_VOID"; 47 private static final String NODE_FACTORY = "NODE_FACTORY"; 48 private static final String NODE_SCOPE_HOOK = "NODE_SCOPE_HOOK"; 49 private static final String NODE_USES_PARSER = "NODE_USES_PARSER"; 50 private static final String STATIC = "STATIC"; 51 private static final String VISITOR = "VISITOR"; 52 53 private static final String NODE_PACKAGE = "NODE_PACKAGE"; 54 private static final String VISITOR_EXCEPTION = "VISITOR_EXCEPTION"; 55 private static final String NODE_PREFIX = "NODE_PREFIX"; 56 57 private final Hashtable optionalAttrs = new Hashtable (); 58 59 private String outputFile = null; 60 61 private static final String DEFAULT_SUFFIX = ".jj"; 62 63 private File outputDirectory = null; 65 private File targetFile = null; 66 private File javaccHome = null; 67 68 private CommandlineJava cmdl = new CommandlineJava(); 69 70 71 75 public void setBuildnodefiles(boolean buildNodeFiles) { 76 optionalAttrs.put(BUILD_NODE_FILES, buildNodeFiles ? Boolean.TRUE : Boolean.FALSE); 77 } 78 79 83 public void setMulti(boolean multi) { 84 optionalAttrs.put(MULTI, multi ? Boolean.TRUE : Boolean.FALSE); 85 } 86 87 91 public void setNodedefaultvoid(boolean nodeDefaultVoid) { 92 optionalAttrs.put(NODE_DEFAULT_VOID, nodeDefaultVoid ? Boolean.TRUE : Boolean.FALSE); 93 } 94 95 99 public void setNodefactory(boolean nodeFactory) { 100 optionalAttrs.put(NODE_FACTORY, nodeFactory ? Boolean.TRUE : Boolean.FALSE); 101 } 102 103 107 public void setNodescopehook(boolean nodeScopeHook) { 108 optionalAttrs.put(NODE_SCOPE_HOOK, nodeScopeHook ? Boolean.TRUE : Boolean.FALSE); 109 } 110 111 115 public void setNodeusesparser(boolean nodeUsesParser) { 116 optionalAttrs.put(NODE_USES_PARSER, nodeUsesParser ? Boolean.TRUE : Boolean.FALSE); 117 } 118 119 123 public void setStatic(boolean staticParser) { 124 optionalAttrs.put(STATIC, staticParser ? Boolean.TRUE : Boolean.FALSE); 125 } 126 127 131 public void setVisitor(boolean visitor) { 132 optionalAttrs.put(VISITOR, visitor ? Boolean.TRUE : Boolean.FALSE); 133 } 134 135 139 public void setNodepackage(String nodePackage) { 140 optionalAttrs.put(NODE_PACKAGE, nodePackage); 141 } 142 143 147 public void setVisitorException(String visitorException) { 148 optionalAttrs.put(VISITOR_EXCEPTION, visitorException); 149 } 150 151 155 public void setNodeprefix(String nodePrefix) { 156 optionalAttrs.put(NODE_PREFIX, nodePrefix); 157 } 158 159 165 public void setOutputdirectory(File outputDirectory) { 166 this.outputDirectory = outputDirectory; 167 } 168 169 175 public void setOutputfile(String outputFile) { 176 this.outputFile = outputFile; 177 } 178 179 183 public void setTarget(File targetFile) { 184 this.targetFile = targetFile; 185 } 186 187 191 public void setJavacchome(File javaccHome) { 192 this.javaccHome = javaccHome; 193 } 194 195 198 public JJTree() { 199 cmdl.setVm(JavaEnvUtils.getJreExecutable("java")); 200 } 201 202 206 public void execute() throws BuildException { 207 208 Enumeration iter = optionalAttrs.keys(); 210 while (iter.hasMoreElements()) { 211 String name = (String ) iter.nextElement(); 212 Object value = optionalAttrs.get(name); 213 cmdl.createArgument().setValue("-" + name + ":" + value.toString()); 214 } 215 216 if (targetFile == null || !targetFile.isFile()) { 217 throw new BuildException("Invalid target: " + targetFile); 218 } 219 220 File javaFile = null; 221 222 if (outputDirectory == null) { 224 cmdl.createArgument().setValue("-OUTPUT_DIRECTORY:" 227 + getDefaultOutputDirectory()); 228 229 javaFile = new File (createOutputFileName(targetFile, outputFile, 230 null)); 231 } else { 232 if (!outputDirectory.isDirectory()) { 233 throw new BuildException("'outputdirectory' " + outputDirectory 234 + " is not a directory."); 235 } 236 237 cmdl.createArgument().setValue("-OUTPUT_DIRECTORY:" 240 + outputDirectory.getAbsolutePath() 241 .replace('\\', '/')); 242 243 javaFile = new File (createOutputFileName(targetFile, outputFile, 244 outputDirectory 245 .getPath())); 246 } 247 248 if (javaFile.exists() 249 && targetFile.lastModified() < javaFile.lastModified()) { 250 log("Target is already built - skipping (" + targetFile + ")", 251 Project.MSG_VERBOSE); 252 return; 253 } 254 255 if (outputFile != null) { 256 cmdl.createArgument().setValue("-" + OUTPUT_FILE + ":" 257 + outputFile.replace('\\', '/')); 258 } 259 260 cmdl.createArgument().setValue(targetFile.getAbsolutePath()); 261 262 final Path classpath = cmdl.createClasspath(getProject()); 263 final File javaccJar = JavaCC.getArchiveFile(javaccHome); 264 classpath.createPathElement().setPath(javaccJar.getAbsolutePath()); 265 classpath.addJavaRuntime(); 266 267 cmdl.setClassname(JavaCC.getMainClass(classpath, 268 JavaCC.TASKDEF_TYPE_JJTREE)); 269 270 final Commandline.Argument arg = cmdl.createVmArgument(); 271 arg.setValue("-mx140M"); 272 arg.setValue("-Dinstall.root=" + javaccHome.getAbsolutePath()); 273 274 final Execute process = 275 new Execute(new LogStreamHandler(this, 276 Project.MSG_INFO, 277 Project.MSG_INFO), 278 null); 279 log(cmdl.describeCommand(), Project.MSG_VERBOSE); 280 process.setCommandline(cmdl.getCommandline()); 281 282 try { 283 if (process.execute() != 0) { 284 throw new BuildException("JJTree failed."); 285 } 286 } catch (IOException e) { 287 throw new BuildException("Failed to launch JJTree", e); 288 } 289 } 290 291 private String createOutputFileName(File destFile, String optionalOutputFile, 292 String outputDir) { 293 optionalOutputFile = validateOutputFile(optionalOutputFile, 294 outputDir); 295 String jjtreeFile = destFile.getAbsolutePath().replace('\\', '/'); 296 297 if ((optionalOutputFile == null) || optionalOutputFile.equals("")) { 298 int filePos = jjtreeFile.lastIndexOf("/"); 299 300 if (filePos >= 0) { 301 jjtreeFile = jjtreeFile.substring(filePos + 1); 302 } 303 304 int suffixPos = jjtreeFile.lastIndexOf('.'); 305 306 if (suffixPos == -1) { 307 optionalOutputFile = jjtreeFile + DEFAULT_SUFFIX; 308 } else { 309 String currentSuffix = jjtreeFile.substring(suffixPos); 310 311 if (currentSuffix.equals(DEFAULT_SUFFIX)) { 312 optionalOutputFile = jjtreeFile + DEFAULT_SUFFIX; 313 } else { 314 optionalOutputFile = jjtreeFile.substring(0, suffixPos) 315 + DEFAULT_SUFFIX; 316 } 317 } 318 } 319 320 if ((outputDir == null) || outputDir.equals("")) { 321 outputDir = getDefaultOutputDirectory(); 322 } 323 324 return (outputDir + "/" + optionalOutputFile).replace('\\', '/'); 325 } 326 327 338 private String validateOutputFile(String destFile, 339 String outputDir) 340 throws BuildException { 341 if (destFile == null) { 342 return null; 343 } 344 345 if ((outputDir == null) 346 && (destFile.startsWith("/") || destFile.startsWith("\\"))) { 347 String relativeOutputFile = makeOutputFileRelative(destFile); 348 setOutputfile(relativeOutputFile); 349 350 return relativeOutputFile; 351 } 352 353 String root = getRoot(new File (destFile)).getAbsolutePath(); 354 355 if ((root.length() > 1) 356 && destFile.startsWith(root.substring(0, root.length() - 1))) { 357 throw new BuildException("Drive letter in 'outputfile' not " 358 + "supported: " + destFile); 359 } 360 361 return destFile; 362 } 363 364 private String makeOutputFileRelative(String destFile) { 365 StringBuffer relativePath = new StringBuffer (); 366 String defaultOutputDirectory = getDefaultOutputDirectory(); 367 int nextPos = defaultOutputDirectory.indexOf('/'); 368 int startPos = nextPos + 1; 369 370 while (startPos > -1 && startPos < defaultOutputDirectory.length()) { 371 relativePath.append("/.."); 372 nextPos = defaultOutputDirectory.indexOf('/', startPos); 373 374 if (nextPos == -1) { 375 startPos = nextPos; 376 } else { 377 startPos = nextPos + 1; 378 } 379 } 380 381 relativePath.append(destFile); 382 383 return relativePath.toString(); 384 } 385 386 private String getDefaultOutputDirectory() { 387 return getProject().getBaseDir().getAbsolutePath().replace('\\', '/'); 388 } 389 390 396 private File getRoot(File file) { 397 File root = file.getAbsoluteFile(); 398 399 while (root.getParent() != null) { 400 root = root.getParentFile(); 401 } 402 403 return root; 404 } 405 } 406 | Popular Tags |