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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. *
  33. * <p><u>Warnings</u>:
  34. * <ol>
  35. * <li>cleaning will not work if no destination directory
  36. * is specified in the javac task.
  37. * (RFE: find and kill .class files in source dirs?)</li>
  38. * <li>cleaning will makes stepwise build processes fail
  39. * if they depend on the results of the prior compilation being
  40. * in the same directory, since this deletes <strong>all</strong>
  41. * .class files.</li>
  42. * <li>If no files are out of date, then the adapter is <b>never</b> called
  43. * and thus cannot gain control to clean out the destination dir.
  44. * </li>
  45. * <p>
  46. *
  47. * @author Wes Isberg
  48. * @since AspectJ 1.1, Ant 1.5.1
  49. */
  50. public class Ajc11CompilerAdapter implements CompilerAdapter {
  51. /**
  52. * Define this system/project property to signal that the
  53. * destination directory should be cleaned
  54. * and javac reinvoked
  55. * to get the complete list of files every time.
  56. */
  57. public static final String CLEAN = "build.compiler.clean";
  58. /** track whether we re-called <code>javac.execute()</code> */
  59. private static final ThreadLocal inSelfCall = new ThreadLocal() {
  60. public Object initialValue() {
  61. return Boolean.FALSE;
  62. }
  63. };
  64. Javac javac;
  65. public void setJavac(Javac javac) {
  66. this.javac = javac;
  67. javac.setTaskName(javac.getTaskName() + " - ajc");
  68. }
  69. public boolean execute() throws BuildException {
  70. if (null == javac) {
  71. throw new IllegalStateException("null javac");
  72. }
  73. if (!((Boolean) inSelfCall.get()).booleanValue()
  74. && afterCleaningDirs()) {
  75. // if we are not re-calling ourself and we cleaned dirs,
  76. // then re-call javac to get the list of all source files.
  77. inSelfCall.set(Boolean.TRUE);
  78. javac.execute();
  79. // javac re-invokes us after recalculating file list
  80. } else {
  81. try {
  82. AjcTask ajc = new AjcTask();
  83. String err = ajc.setupAjc(javac);
  84. if (null != err) {
  85. throw new BuildException(err, javac.getLocation());
  86. }
  87. ajc.execute();
  88. // handles BuildException for failonerror, etc.
  89. } finally {
  90. inSelfCall.set(Boolean.FALSE);
  91. }
  92. }
  93. return true;
  94. }
  95. /**
  96. * If destDir exists and property CLEAN is set,
  97. * this cleans out the dest dir of any .class files,
  98. * and returns true to signal a recursive call.
  99. * @return true if destDir was cleaned.
  100. */
  101. private boolean afterCleaningDirs() {
  102. String clean = javac.getProject().getProperty(CLEAN);
  103. if (null == clean) {
  104. return false;
  105. }
  106. File destDir = javac.getDestdir();
  107. if (null == destDir) {
  108. javac.log(
  109. CLEAN + " specified, but no dest dir to clean",
  110. Project.MSG_WARN);
  111. return false;
  112. }
  113. javac.log(
  114. CLEAN + " cleaning .class files from " + destDir,
  115. Project.MSG_VERBOSE);
  116. FileUtil.deleteContents(
  117. destDir,
  118. FileUtil.DIRS_AND_WRITABLE_CLASSES,
  119. true);
  120. return true;
  121. }
  122. }