You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Ajc11CompilerAdapter.java 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* *******************************************************************
  2. * Copyright (c) 2003 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Wes Isberg initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.tools.ant.taskdefs;
  13. import org.apache.tools.ant.BuildException;
  14. import org.apache.tools.ant.Project;
  15. import org.apache.tools.ant.taskdefs.Javac;
  16. import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter;
  17. import org.aspectj.util.FileUtil;
  18. import java.io.File;
  19. //import java.io.FileFilter;
  20. //import java.io.FileWriter;
  21. //import java.io.IOException;
  22. /**
  23. * Adapt ajc to javac commands.
  24. * Note that the srcdirs set for javac are NOT passed on to ajc;
  25. * instead, the list of source files generated is passed to ajc.
  26. * <p>
  27. * Javac usually prunes the source file list based on the timestamps
  28. * of corresponding .class files, which is wrong for ajc which
  29. * requires all the files every time. To work around this,
  30. * set the global property CLEAN ("build.compiler.clean") to delete
  31. * all .class files in the destination directory before compiling.
  32. * </p>
  33. *
  34. * <p><u>Warnings</u>:</p>
  35. * <ol>
  36. * <li>cleaning will not work if no destination directory
  37. * is specified in the javac task.
  38. * (RFE: find and kill .class files in source dirs?)</li>
  39. * <li>cleaning will makes stepwise build processes fail
  40. * if they depend on the results of the prior compilation being
  41. * in the same directory, since this deletes <strong>all</strong>
  42. * .class files.</li>
  43. * <li>If no files are out of date, then the adapter is <b>never</b> called
  44. * and thus cannot gain control to clean out the destination dir.
  45. * </li>
  46. * </ol>
  47. *
  48. * @author Wes Isberg
  49. * @since AspectJ 1.1, Ant 1.5.1
  50. */
  51. public class Ajc11CompilerAdapter implements CompilerAdapter {
  52. /**
  53. * Define this system/project property to signal that the
  54. * destination directory should be cleaned
  55. * and javac reinvoked
  56. * to get the complete list of files every time.
  57. */
  58. public static final String CLEAN = "build.compiler.clean";
  59. /** track whether we re-called <code>javac.execute()</code> */
  60. private static final ThreadLocal inSelfCall = new ThreadLocal() {
  61. public Object initialValue() {
  62. return Boolean.FALSE;
  63. }
  64. };
  65. Javac javac;
  66. public void setJavac(Javac javac) {
  67. this.javac = javac;
  68. javac.setTaskName(javac.getTaskName() + " - ajc");
  69. }
  70. public boolean execute() throws BuildException {
  71. if (null == javac) {
  72. throw new IllegalStateException("null javac");
  73. }
  74. if (!(Boolean) inSelfCall.get()
  75. && afterCleaningDirs()) {
  76. // if we are not re-calling ourself and we cleaned dirs,
  77. // then re-call javac to get the list of all source files.
  78. inSelfCall.set(Boolean.TRUE);
  79. javac.execute();
  80. // javac re-invokes us after recalculating file list
  81. } else {
  82. try {
  83. AjcTask ajc = new AjcTask();
  84. String err = ajc.setupAjc(javac);
  85. if (null != err) {
  86. throw new BuildException(err, javac.getLocation());
  87. }
  88. ajc.execute();
  89. // handles BuildException for failonerror, etc.
  90. } finally {
  91. inSelfCall.set(Boolean.FALSE);
  92. }
  93. }
  94. return true;
  95. }
  96. /**
  97. * If destDir exists and property CLEAN is set,
  98. * this cleans out the dest dir of any .class files,
  99. * and returns true to signal a recursive call.
  100. * @return true if destDir was cleaned.
  101. */
  102. private boolean afterCleaningDirs() {
  103. String clean = javac.getProject().getProperty(CLEAN);
  104. if (null == clean) {
  105. return false;
  106. }
  107. File destDir = javac.getDestdir();
  108. if (null == destDir) {
  109. javac.log(
  110. CLEAN + " specified, but no dest dir to clean",
  111. Project.MSG_WARN);
  112. return false;
  113. }
  114. javac.log(
  115. CLEAN + " cleaning .class files from " + destDir,
  116. Project.MSG_VERBOSE);
  117. FileUtil.deleteContents(
  118. destDir,
  119. FileUtil.DIRS_AND_WRITABLE_CLASSES,
  120. true);
  121. return true;
  122. }
  123. }