1 11 package org.eclipse.jdt.core; 12 13 import java.io.File ; 14 import java.io.IOException ; 15 import java.io.PrintWriter ; 16 import java.lang.reflect.Constructor ; 17 import java.lang.reflect.InvocationTargetException ; 18 import java.lang.reflect.Method ; 19 import java.util.ArrayList ; 20 import java.util.Arrays ; 21 import java.util.Comparator ; 22 import java.util.HashMap ; 23 import java.util.List ; 24 import java.util.Map ; 25 26 import org.apache.tools.ant.BuildException; 27 import org.apache.tools.ant.Project; 28 import org.apache.tools.ant.taskdefs.Javac; 29 import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter; 30 import org.apache.tools.ant.types.Commandline; 31 import org.apache.tools.ant.types.Path; 32 import org.apache.tools.ant.types.Commandline.Argument; 33 import org.apache.tools.ant.util.JavaEnvUtils; 34 import org.eclipse.jdt.core.compiler.CharOperation; 35 import org.eclipse.jdt.internal.antadapter.AntAdapterMessages; 36 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 37 import org.eclipse.jdt.internal.compiler.util.SuffixConstants; 38 import org.eclipse.jdt.internal.compiler.util.Util; 39 40 53 public class JDTCompilerAdapter extends DefaultCompilerAdapter { 54 private static final char[] SEPARATOR_CHARS = new char[] { '/', '\\' }; 55 private static final char[] ADAPTER_PREFIX = "#ADAPTER#".toCharArray(); private static final char[] ADAPTER_ENCODING = "ENCODING#".toCharArray(); private static final char[] ADAPTER_ACCESS = "ACCESS#".toCharArray(); private static String compilerClass = "org.eclipse.jdt.internal.compiler.batch.Main"; String logFileName; 60 Map customDefaultOptions; 61 private Map fileEncodings = null; 62 private Map dirEncodings = null; 63 private List accessRules = null; 64 65 70 public boolean execute() throws BuildException { 71 this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.usingJDTCompiler"), Project.MSG_VERBOSE); Commandline cmd = setupJavacCommand(); 73 74 try { 75 Class c = Class.forName(compilerClass); 76 Constructor batchCompilerConstructor = c.getConstructor(new Class [] { PrintWriter .class, PrintWriter .class, Boolean.TYPE, Map .class}); 77 Object batchCompilerInstance = batchCompilerConstructor.newInstance(new Object [] {new PrintWriter (System.out), new PrintWriter (System.err), Boolean.TRUE, this.customDefaultOptions}); 78 Method compile = c.getMethod("compile", new Class [] {String [].class}); Object result = compile.invoke(batchCompilerInstance, new Object [] { cmd.getArguments()}); 80 final boolean resultValue = ((Boolean ) result).booleanValue(); 81 if (!resultValue && this.logFileName != null) { 82 this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.error.compilationFailed", this.logFileName)); } 84 return resultValue; 85 } catch (ClassNotFoundException cnfe) { 86 throw new BuildException(AntAdapterMessages.getString("ant.jdtadapter.error.cannotFindJDTCompiler")); } catch (Exception ex) { 88 throw new BuildException(ex); 89 } 90 } 91 92 93 protected Commandline setupJavacCommand() throws BuildException { 94 Commandline cmd = new Commandline(); 95 this.customDefaultOptions = new CompilerOptions().getMap(); 96 97 Class javacClass = Javac.class; 98 99 103 String [] compilerArgs = processCompilerArguments(javacClass); 104 105 108 cmd.createArgument().setValue("-noExit"); 110 if (this.bootclasspath != null) { 111 cmd.createArgument().setValue("-bootclasspath"); if (this.bootclasspath.size() != 0) { 113 116 cmd.createArgument().setPath(this.bootclasspath); 117 } else { 118 cmd.createArgument().setValue(Util.EMPTY_STRING); 119 } 120 } 121 122 Path classpath = new Path(this.project); 123 124 129 if (this.extdirs != null) { 130 cmd.createArgument().setValue("-extdirs"); cmd.createArgument().setPath(this.extdirs); 132 } 133 134 138 classpath.append(getCompileClasspath()); 139 140 Path sourcepath = null; 143 144 Method getSourcepathMethod = null; 147 try { 148 getSourcepathMethod = javacClass.getMethod("getSourcepath", null); } catch(NoSuchMethodException e) { 150 } 152 Path compileSourcePath = null; 153 if (getSourcepathMethod != null) { 154 try { 155 compileSourcePath = (Path) getSourcepathMethod.invoke(this.attributes, null); 156 } catch (IllegalAccessException e) { 157 } catch (InvocationTargetException e) { 159 } 161 } 162 if (compileSourcePath != null) { 163 sourcepath = compileSourcePath; 164 } else { 165 sourcepath = this.src; 166 } 167 classpath.append(sourcepath); 168 171 cmd.createArgument().setValue("-classpath"); createClasspathArgument(cmd, classpath); 173 174 final String javaVersion = JavaEnvUtils.getJavaVersion(); 175 String memoryParameterPrefix = javaVersion.equals(JavaEnvUtils.JAVA_1_1) ? "-J-" : "-J-X"; if (this.memoryInitialSize != null) { 177 if (!this.attributes.isForkedJavac()) { 178 this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.ignoringMemoryInitialSize"), Project.MSG_WARN); } else { 180 cmd.createArgument().setValue(memoryParameterPrefix 181 + "ms" + this.memoryInitialSize); } 183 } 184 185 if (this.memoryMaximumSize != null) { 186 if (!this.attributes.isForkedJavac()) { 187 this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.ignoringMemoryMaximumSize"), Project.MSG_WARN); } else { 189 cmd.createArgument().setValue(memoryParameterPrefix 190 + "mx" + this.memoryMaximumSize); } 192 } 193 194 if (this.debug) { 195 Method getDebugLevelMethod = null; 198 try { 199 getDebugLevelMethod = javacClass.getMethod("getDebugLevel", null); } catch(NoSuchMethodException e) { 201 } 204 String debugLevel = null; 205 if (getDebugLevelMethod != null) { 206 try { 207 debugLevel = (String ) getDebugLevelMethod.invoke(this.attributes, null); 208 } catch (IllegalAccessException e) { 209 } catch (InvocationTargetException e) { 211 } 213 } 214 if (debugLevel != null) { 215 this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE); 216 this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE); 217 this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.DO_NOT_GENERATE); 218 if (debugLevel.length() != 0) { 219 if (debugLevel.indexOf("vars") != -1) { this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); 221 } 222 if (debugLevel.indexOf("lines") != -1) { this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE); 224 } 225 if (debugLevel.indexOf("source") != -1) { this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.GENERATE); 227 } 228 } 229 } else { 230 this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); 231 this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE); 232 this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.GENERATE); 233 } 234 } else { 235 this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE); 236 this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE); 237 this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.DO_NOT_GENERATE); 238 } 239 240 243 if (this.attributes.getNowarn()) { 244 Object [] entries = this.customDefaultOptions.entrySet().toArray(); 246 for (int i = 0, max = entries.length; i < max; i++) { 247 Map.Entry entry = (Map.Entry ) entries[i]; 248 if (!(entry.getKey() instanceof String )) 249 continue; 250 if (!(entry.getValue() instanceof String )) 251 continue; 252 if (((String ) entry.getValue()).equals(CompilerOptions.WARNING)) { 253 this.customDefaultOptions.put(entry.getKey(), CompilerOptions.IGNORE); 254 } 255 } 256 this.customDefaultOptions.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING); 257 if (this.deprecation) { 258 this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING); 259 this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED); 260 this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED); 261 } 262 } else if (this.deprecation) { 263 this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING); 264 this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED); 265 this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED); 266 } else { 267 this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE); 268 this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED); 269 this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED); 270 } 271 272 275 if (this.destDir != null) { 276 cmd.createArgument().setValue("-d"); cmd.createArgument().setFile(this.destDir.getAbsoluteFile()); 278 } 279 280 283 if (this.verbose) { 284 cmd.createArgument().setValue("-verbose"); } 286 287 290 if (!this.attributes.getFailonerror()) { 291 cmd.createArgument().setValue("-proceedOnError"); } 293 294 297 if (this.target != null) { 298 this.customDefaultOptions.put(CompilerOptions.OPTION_TargetPlatform, this.target); 299 } 300 301 304 String source = this.attributes.getSource(); 305 if (source != null) { 306 this.customDefaultOptions.put(CompilerOptions.OPTION_Source, source); 307 } 308 309 312 if (this.encoding != null) { 313 cmd.createArgument().setValue("-encoding"); cmd.createArgument().setValue(this.encoding); 315 } 316 317 if (compilerArgs != null) { 318 321 final int length = compilerArgs.length; 322 if (length != 0) { 323 for (int i = 0, max = length; i < max; i++) { 324 String arg = compilerArgs[i]; 325 if (this.logFileName == null && "-log".equals(arg) && ((i + 1) < max)) { this.logFileName = compilerArgs[i + 1]; 327 } 328 cmd.createArgument().setValue(arg); 329 } 330 } 331 } 332 337 logAndAddFilesToCompile(cmd); 338 return cmd; 339 } 340 341 346 private String [] processCompilerArguments(Class javacClass) { 347 Method getCurrentCompilerArgsMethod = null; 350 try { 351 getCurrentCompilerArgsMethod = javacClass.getMethod("getCurrentCompilerArgs", null); } catch (NoSuchMethodException e) { 353 } 356 String [] compilerArgs = null; 357 if (getCurrentCompilerArgsMethod != null) { 358 try { 359 compilerArgs = (String []) getCurrentCompilerArgsMethod.invoke(this.attributes, null); 360 } catch (IllegalAccessException e) { 361 } catch (InvocationTargetException e) { 363 } 365 } 366 if (compilerArgs != null) checkCompilerArgs(compilerArgs); 368 return compilerArgs; 369 } 370 376 private void checkCompilerArgs(String [] args) { 377 for (int i = 0; i < args.length; i++) { 378 if (args[i].charAt(0) == '@') { 379 try { 380 char[] content = Util.getFileCharContent(new File (args[i].substring(1)), null); 381 int offset = 0; 382 int prefixLength = ADAPTER_PREFIX.length; 383 while ((offset = CharOperation.indexOf(ADAPTER_PREFIX, content, true, offset)) > -1) { 384 int start = offset + prefixLength; 385 int end = CharOperation.indexOf('\n', content, start); 386 if (end == -1) 387 end = content.length; 388 while (CharOperation.isWhitespace(content[end])) { 389 end--; 390 } 391 392 if (CharOperation.equals(ADAPTER_ENCODING, content, start, start + ADAPTER_ENCODING.length)) { 394 CharOperation.replace(content, SEPARATOR_CHARS, File.separatorChar, start, end + 1); 395 start += ADAPTER_ENCODING.length; 397 int encodeStart = CharOperation.lastIndexOf('[', content, start, end); 398 if (start < encodeStart && encodeStart < end) { 399 boolean isFile = CharOperation.equals(SuffixConstants.SUFFIX_java, content, encodeStart - 5, encodeStart, false); 400 401 String str = String.valueOf(content, start, encodeStart - start); 402 String enc = String.valueOf(content, encodeStart, end - encodeStart + 1); 403 if (isFile) { 404 if (fileEncodings == null) 405 fileEncodings = new HashMap (); 406 fileEncodings.put(str, enc); 408 } else { 409 if (dirEncodings == null) 410 dirEncodings = new HashMap (); 411 dirEncodings.put(str, enc); 412 } 413 } 414 } else if (CharOperation.equals(ADAPTER_ACCESS, content, start, start + ADAPTER_ACCESS.length)) { 415 start += ADAPTER_ACCESS.length; 417 int accessStart = CharOperation.indexOf('[', content, start, end); 418 CharOperation.replace(content, SEPARATOR_CHARS, File.separatorChar, start, accessStart); 419 if (start < accessStart && accessStart < end) { 420 String path = String.valueOf(content, start, accessStart - start); 421 String access = String.valueOf(content, accessStart, end - accessStart + 1); 422 if (accessRules == null) 423 accessRules = new ArrayList (); 424 accessRules.add(path); 425 accessRules.add(access); 426 } 427 } 428 offset = end; 429 } 430 } catch (IOException e) { 431 } 433 } 434 } 435 436 } 437 438 443 private void createClasspathArgument(Commandline cmd, Path classpath) { 444 Argument arg = cmd.createArgument(); 445 final String [] pathElements = classpath.list(); 446 447 if (pathElements.length == 0) { 449 arg.setValue(Util.EMPTY_STRING); 450 return; 451 } 452 453 if (accessRules == null) { 455 arg.setPath(classpath); 456 return; 457 } 458 459 int rulesLength = accessRules.size(); 460 String [] rules = (String []) accessRules.toArray(new String [rulesLength]); 461 int nextRule = 0; 462 final StringBuffer result = new StringBuffer (); 463 464 for (int i = 0, max = pathElements.length; i < max; i++) { 467 if (i > 0) 468 result.append(File.pathSeparatorChar); 469 String pathElement = pathElements[i]; 470 result.append(pathElement); 471 for (int j = nextRule; j < rulesLength; j += 2) { 473 String rule = rules[j]; 474 if (pathElement.endsWith(rule)) { 475 result.append(rules[j + 1]); 476 nextRule = j + 2; 477 break; 478 } 479 if (rule.endsWith(File.separator)) { 481 int ruleLength = rule.length(); 484 if (pathElement.regionMatches(false, pathElement.length() - ruleLength + 1, rule, 0, ruleLength - 1)) { 485 result.append(rules[j + 1]); 486 nextRule = j + 2; 487 break; 488 } 489 } else if (pathElement.endsWith(File.separator)) { 490 int ruleLength = rule.length(); 492 if (pathElement.regionMatches(false, pathElement.length() - ruleLength - 1, rule, 0, ruleLength)) { 493 result.append(rules[j + 1]); 494 nextRule = j + 2; 495 break; 496 } 497 } 498 } 499 } 500 501 arg.setValue(result.toString()); 502 } 503 510 protected void logAndAddFilesToCompile(Commandline cmd) { 511 attributes.log("Compilation " + cmd.describeArguments(), Project.MSG_VERBOSE); 513 514 StringBuffer niceSourceList = new StringBuffer ("File"); if (compileList.length != 1) { 516 niceSourceList.append("s"); } 518 niceSourceList.append(" to be compiled:"); niceSourceList.append(lSep); 520 521 String [] encodedFiles = null, encodedDirs = null; 522 int encodedFilesLength = 0, encodedDirsLength = 0; 523 if (fileEncodings != null) { 524 encodedFilesLength = fileEncodings.size(); 525 encodedFiles = new String [encodedFilesLength]; 526 fileEncodings.keySet().toArray(encodedFiles); 527 } 528 if (dirEncodings != null) { 529 encodedDirsLength = dirEncodings.size(); 530 encodedDirs = new String [encodedDirsLength]; 531 dirEncodings.keySet().toArray(encodedDirs); 532 Comparator comparator = new Comparator () { 535 public int compare(Object o1, Object o2) { 536 return ((String ) o2).length() - ((String ) o1).length(); 537 } 538 }; 539 Arrays.sort(encodedDirs, comparator); 540 } 541 542 for (int i = 0; i < compileList.length; i++) { 543 String arg = compileList[i].getAbsolutePath(); 544 boolean encoded = false; 545 if (encodedFiles != null) { 546 for (int j = 0; j < encodedFilesLength; j++) { 548 if (arg.endsWith(encodedFiles[j])) { 549 arg = arg + (String ) fileEncodings.get(encodedFiles[j]); 551 if (j < encodedFilesLength - 1) { 552 System.arraycopy(encodedFiles, j + 1, encodedFiles, j, encodedFilesLength - j - 1); 553 } 554 encodedFiles[--encodedFilesLength] = null; 555 encoded = true; 556 break; 557 } 558 } 559 } 560 if (!encoded && encodedDirs != null) { 561 for (int j = 0; j < encodedDirsLength; j++) { 563 if (arg.lastIndexOf(encodedDirs[j]) != -1) { 564 arg = arg + (String ) dirEncodings.get(encodedDirs[j]); 565 break; 566 } 567 } 568 } 569 cmd.createArgument().setValue(arg); 570 niceSourceList.append(" " + arg + lSep); } 572 573 attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE); 574 } 575 } 576 | Popular Tags |